eventconsumer.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 274 行

JAVA
274
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.observation;import org.apache.jackrabbit.core.ItemId;import org.apache.jackrabbit.core.SessionImpl;import org.apache.jackrabbit.core.security.AccessManager;import org.apache.jackrabbit.core.state.ItemState;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.RepositoryException;import javax.jcr.Session;import javax.jcr.observation.Event;import javax.jcr.observation.EventIterator;import javax.jcr.observation.EventListener;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.WeakHashMap;/** * The <code>EventConsumer</code> class combines the {@link * javax.jcr.observation.EventListener} with the implementation of specified * filter for the listener: {@link EventFilter}. * <p/> * Collections of {@link EventState} objects will be dispatched to {@link * #consumeEvents}. */class EventConsumer {    /**     * The default Logger instance for this class.     */    private static final Logger log = LoggerFactory.getLogger(EventConsumer.class);    /**     * The <code>Session</code> associated with this <code>EventConsumer</code>.     */    private final SessionImpl session;    /**     * The listener part of this <code>EventConsumer</code>.     */    private final EventListener listener;    /**     * The <code>EventFilter</code> for this <code>EventConsumer</code>.     */    private final EventFilter filter;    /**     * A map of <code>Set</code> objects that hold references to     * <code>ItemId</code>s of denied <code>ItemState</code>s. The map uses the     * <code>EventStateCollection</code> as the key to reference a deny Set.     */    private final Map accessDenied = Collections.synchronizedMap(new WeakHashMap());    /**     * cached hash code value     */    private int hashCode;    /**     * An <code>EventConsumer</code> consists of a <code>Session</code>, the     * attached <code>EventListener</code> and an <code>EventFilter</code>.     *     * @param session  the <code>Session</code> that created this     *                 <code>EventConsumer</code>.     * @param listener the actual <code>EventListener</code> to call back.     * @param filter   only pass an <code>Event</code> to the listener if the     *                 <code>EventFilter</code> allows the <code>Event</code>.     * @throws NullPointerException if <code>session</code>, <code>listener</code>     *                              or <code>filter</code> is<code>null</code>.     */    EventConsumer(SessionImpl session, EventListener listener, EventFilter filter)            throws NullPointerException {        if (session == null) {            throw new NullPointerException("session");        }        if (listener == null) {            throw new NullPointerException("listener");        }        if (filter == null) {            throw new NullPointerException("filter");        }        this.session = session;        this.listener = listener;        this.filter = filter;    }    /**     * Returns the <code>Session</code> that is associated     * with this <code>EventConsumer</code>.     *     * @return the <code>Session</code> of this <code>EventConsumer</code>.     */    Session getSession() {        return session;    }    /**     * Returns the <code>EventListener</code> that is associated with this     * <code>EventConsumer</code>.     *     * @return the <code>EventListener</code> of this <code>EventConsumer</code>.     */    EventListener getEventListener() {        return listener;    }    /**     * Checks for what {@link EventState}s this <code>EventConsumer</code> has     * enough access rights to see the event.     *     * @param events the collection of {@link EventState}s.     */    void prepareEvents(EventStateCollection events) {        Iterator it = events.iterator();        Set denied = null;        while (it.hasNext()) {            EventState state = (EventState) it.next();            if (state.getType() == Event.NODE_REMOVED                    || state.getType() == Event.PROPERTY_REMOVED) {                if (session.equals(state.getSession())) {                    // if we created the event, we can be sure that                    // we have enough access rights to see the event                    continue;                }                // check read permission                ItemId targetId = state.getTargetId();                boolean granted = false;                try {                    granted = session.getAccessManager().isGranted(targetId, AccessManager.READ);                } catch (RepositoryException e) {                    log.warn("Unable to check access rights for item: " + targetId);                }                if (!granted) {                    if (denied == null) {                        denied = new HashSet();                    }                    denied.add(targetId);                }            }        }        if (denied != null) {            accessDenied.put(events, denied);        }    }    /**     * Checks for which deleted <code>ItemStates</code> this     * <code>EventConsumer</code> has enough access rights to see the event.     *     * @param events       the collection of {@link EventState}s.     * @param deletedItems Iterator of deleted <code>ItemState</code>s.     */    void prepareDeleted(EventStateCollection events, Iterator deletedItems) {        Set denied = null;        while (deletedItems.hasNext()) {            ItemState item = (ItemState) deletedItems.next();            // check read permission            boolean granted = false;            try {                granted = session.getAccessManager().isGranted(item.getId(), AccessManager.READ);            } catch (RepositoryException e) {                log.warn("Unable to check access rights for item: " + item.getId());            }            if (!granted) {                if (denied == null) {                    denied = new HashSet();                }                denied.add(item.getId());            }        }        if (denied != null) {            accessDenied.put(events, denied);        }    }    /**     * Dispatches the events to the <code>EventListener</code>.     *     * @param events a collection of {@link EventState}s     *               to dispatch.     */    void consumeEvents(EventStateCollection events) throws RepositoryException {        // Set of ItemIds of denied ItemStates        Set denied = (Set) accessDenied.remove(events);        // check permissions        for (Iterator it = events.iterator(); it.hasNext() && session.isLive();) {            EventState state = (EventState) it.next();            if (state.getType() == Event.NODE_ADDED                    || state.getType() == Event.PROPERTY_ADDED                    || state.getType() == Event.PROPERTY_CHANGED) {                ItemId targetId = state.getTargetId();                if (!session.getAccessManager().isGranted(targetId, AccessManager.READ)) {                    if (denied == null) {                        denied = new HashSet();                    }                    denied.add(targetId);                }            }        }        // only deliver if session is still live        if (!session.isLive()) {            return;        }        // check if filtered iterator has at least one event        EventIterator it = new FilteredEventIterator(events, filter, denied);        if (it.hasNext()) {            listener.onEvent(it);        } else {            // otherwise skip this listener        }    }    /**     * Returns <code>true</code> if this <code>EventConsumer</code> is equal to     * some other object, <code>false</code> otherwise.     * <p/>     * Two <code>EventConsumer</code>s are considered equal if they refer to the     * same <code>Session</code> and the <code>EventListener</code>s they     * reference are equal. Note that the <code>EventFilter</code> is ignored in     * this check.     *     * @param obj the reference object with which to compare.     * @return <code>true</code> if this <code>EventConsumer</code> is equal the     *         other <code>EventConsumer</code>.     */    public boolean equals(Object obj) {        if (this == obj) {            return true;        }        if (obj instanceof EventConsumer) {            EventConsumer other = (EventConsumer) obj;            return session.equals(other.session)                    && listener.equals(other.listener);        }        return false;    }    /**     * Returns the hash code for this <code>EventConsumer</code>.     *     * @return the hash code for this <code>EventConsumer</code>.     */    public int hashCode() {        if (hashCode == 0) {            hashCode = session.hashCode() ^ listener.hashCode();        }        return hashCode;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?