⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subscriptionmanagerimpl.java

📁 jsr170接口的java实现。是个apache的开源项目。
💻 JAVA
字号:
/* * 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.webdav.jcr.observation;import org.apache.jackrabbit.webdav.DavException;import org.apache.jackrabbit.webdav.DavResourceLocator;import org.apache.jackrabbit.webdav.DavServletResponse;import org.apache.jackrabbit.webdav.transaction.TransactionResource;import org.apache.jackrabbit.webdav.jcr.JcrDavException;import org.apache.jackrabbit.webdav.jcr.JcrDavSession;import org.apache.jackrabbit.webdav.jcr.transaction.TransactionListener;import org.apache.jackrabbit.webdav.observation.EventDiscovery;import org.apache.jackrabbit.webdav.observation.ObservationResource;import org.apache.jackrabbit.webdav.observation.Subscription;import org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery;import org.apache.jackrabbit.webdav.observation.SubscriptionInfo;import org.apache.jackrabbit.webdav.observation.SubscriptionManager;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.w3c.dom.Element;import org.w3c.dom.Document;import javax.jcr.RepositoryException;import javax.jcr.Session;import javax.jcr.observation.ObservationManager;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import java.util.Map;import java.util.List;import java.util.ArrayList;/** * <code>SubscriptionManager</code> collects all subscriptions requested, handles * the subscription timeout and provides METHODS to discover subscriptions * present on a given resource as well as events for an specific subscription. */// todo: make sure all expired subscriptions are removed!public class SubscriptionManagerImpl implements SubscriptionManager, TransactionListener {    private static Logger log = LoggerFactory.getLogger(SubscriptionManager.class);    /**     * Map containing all {@link org.apache.jackrabbit.webdav.observation.Subscription subscriptions}.     */    private final SubscriptionMap subscriptions = new SubscriptionMap();    private final Map transactionListenerById = new HashMap();    /**     * Retrieve the {@link org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery}     * object for the given resource. Note, that the discovery object will be empty     * if there are no subscriptions present.<br>     * Note that all subscriptions present on the given resource are returned.     * However, the subscription id will not be visible in order to avoid abuse     * by clients not having registered the subscription originally.     *     * @param resource     */    public SubscriptionDiscovery getSubscriptionDiscovery(ObservationResource resource) {        Subscription[] subsForResource = subscriptions.getByPath(resource.getLocator());        return new SubscriptionDiscovery(subsForResource);    }    /**     * Create a new <code>Subscription</code> or update an existing <code>Subscription</code>     * and add it as eventlistener to the {@link javax.jcr.observation.ObservationManager}.     *     * @param info     * @param subscriptionId     * @param resource     * @return <code>Subscription</code> that has been added to the {@link javax.jcr.observation.ObservationManager}     * @throws DavException if the subscription fails     */    public Subscription subscribe(SubscriptionInfo info, String subscriptionId,                                  ObservationResource resource)            throws DavException {        Subscription subscription;        if (subscriptionId == null) {            // new subscription            SubscriptionImpl newSubs = new SubscriptionImpl(info, resource);            registerSubscription(newSubs, resource);            // ajust references to this subscription            subscriptions.put(newSubs.getSubscriptionId(), newSubs);            resource.getSession().addReference(newSubs.getSubscriptionId());            subscription = newSubs;        } else {            // refresh/modify existing one            SubscriptionImpl existing = validate(subscriptionId, resource);            existing.setInfo(info);            registerSubscription(existing, resource);            subscription = new WrappedSubscription(existing);        }        return subscription;    }    /**     * Register the event listener defined by the given subscription to the     * repository's observation manager.     *     * @param subscription     * @param resource     * @throws DavException     */    private void registerSubscription(SubscriptionImpl subscription,                                      ObservationResource resource) throws DavException {        try {            Session session = getRepositorySession(resource);            ObservationManager oMgr = session.getWorkspace().getObservationManager();            String itemPath = subscription.getLocator().getRepositoryPath();            oMgr.addEventListener(subscription, subscription.getJcrEventTypes(),                    itemPath, subscription.isDeep(),                    subscription.getUuidFilters(),                    subscription.getNodetypeNameFilters(),                    subscription.isNoLocal());        } catch (RepositoryException e) {            log.error("Unable to register eventlistener: "+e.getMessage());            throw new JcrDavException(e);        }    }    /**     * Unsubscribe the <code>Subscription</code> with the given id and remove it     * from the {@link javax.jcr.observation.ObservationManager} as well as     * from the internal map.     *     * @param subscriptionId     * @param resource     * @throws DavException     */    public void unsubscribe(String subscriptionId, ObservationResource resource)            throws DavException {        SubscriptionImpl subs = validate(subscriptionId, resource);        unregisterSubscription(subs, resource);    }    /**     * Remove the event listener defined by the specified subscription from     * the repository's observation manager and clean up the references present     * on the <code>DavSession</code>.     *     * @param subscription     * @param resource     * @throws DavException     */    private void unregisterSubscription(SubscriptionImpl subscription,                                        ObservationResource resource) throws DavException {        try {            Session session = getRepositorySession(resource);            session.getWorkspace().getObservationManager().removeEventListener(subscription);            String sId = subscription.getSubscriptionId();            // clean up any references            subscriptions.remove(sId);            resource.getSession().removeReference(sId);        } catch (RepositoryException e) {            log.error("Unable to remove eventlistener: "+e.getMessage());            throw new JcrDavException(e);        }    }    /**     * Retrieve all event bundles accumulated since for the subscription specified     * by the given id.     *     * @param subscriptionId     * @param timeout timeout in milliseconds     * @param resource     * @return object encapsulating the events.     */    public EventDiscovery poll(String subscriptionId, long timeout, ObservationResource resource)            throws DavException {        SubscriptionImpl subs = validate(subscriptionId, resource);        return subs.discoverEvents(timeout);    }    /**     * Validate the given subscription id. The validation will fail under the following     * conditions:<ul>     * <li>The subscription with the given id does not exist,</li>     * <li>DavResource path does not match the subscription id,</li>     * <li>The subscription with the given id is already expired.</li>     * </ul>     *     * @param subscriptionId     * @param resource     * @return <code>Subscription</code> with the given id.     * @throws DavException if an error occured while retrieving the <code>Subscription</code>     */    private SubscriptionImpl validate(String subscriptionId, ObservationResource resource)            throws DavException {        SubscriptionImpl subs;        if (subscriptions.contains(subscriptionId)) {            subs = (SubscriptionImpl) subscriptions.get(subscriptionId);            if (!subs.isSubscribedToResource(resource)) {                throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "Attempt to operate on subscription with invalid resource path.");            }            if (subs.isExpired()) {                unregisterSubscription(subs, resource);                throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "Attempt to  operate on expired subscription.");            }            return subs;        } else {            throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "Attempt to modify or to poll for non-existing subscription.");        }    }    /**     * @param resource     * @return JCR session     */    private static Session getRepositorySession(ObservationResource resource) throws DavException {        return JcrDavSession.getRepositorySession(resource.getSession());    }    //---------------------------< TransactionListener >------------------------    /**     * {@inheritDoc}     */    public synchronized void beforeCommit(TransactionResource resource,                                          String lockToken) {        // suspend regular subscriptions during a commit        List transactionListeners = new ArrayList();        for (Iterator it = subscriptions.iterator(); it.hasNext(); ) {            SubscriptionImpl sub = (SubscriptionImpl) it.next();            TransactionListener tl = sub.createTransactionListener();            tl.beforeCommit(resource, lockToken);            transactionListeners.add(tl);        }        transactionListenerById.put(lockToken, transactionListeners);    }    /**     * {@inheritDoc}     */    public void afterCommit(TransactionResource resource, String lockToken, boolean success) {        List transactionListeners = (List) transactionListenerById.remove(lockToken);        if (transactionListeners != null) {            for (Iterator it = transactionListeners.iterator(); it.hasNext(); ) {                TransactionListener txListener = (TransactionListener) it.next();                txListener.afterCommit(resource, lockToken, success);            }        }    }    //----------------------------------------------< private inner classes >---    /**     * Private inner class wrapping around an <code>Subscription</code> as     * present in the internal map. This allows to hide the subscription Id     * from other sessions, that did create the subscription.     */    private class WrappedSubscription implements Subscription {        private final Subscription delegatee;        private WrappedSubscription(Subscription subsc) {            this.delegatee = subsc;        }        public String getSubscriptionId() {            // always return null, since the subscription id must not be exposed            // but to the client, that created the subscription.            return null;        }        public Element toXml(Document document) {            return delegatee.toXml(document);        }    }    /**     * Private inner class <code>SubscriptionMap</code> that allows for quick     * access by resource path as well as by subscription id.     */    private class SubscriptionMap {        private HashMap subscriptions = new HashMap();        private HashMap ids = new HashMap();        private boolean contains(String subscriptionId) {            return subscriptions.containsKey(subscriptionId);        }        private Subscription get(String subscriptionId) {            return (Subscription) subscriptions.get(subscriptionId);        }        private Iterator iterator() {            return subscriptions.values().iterator();        }        private void put(String subscriptionId, SubscriptionImpl subscription) {            subscriptions.put(subscriptionId, subscription);            DavResourceLocator key = subscription.getLocator();            Set idSet;            if (ids.containsKey(key)) {                idSet = (Set) ids.get(key);            } else {                idSet = new HashSet();                ids.put(key, idSet);            }            if (!idSet.contains(subscriptionId)) {                idSet.add(subscriptionId);            }        }        private void remove(String subscriptionId) {            SubscriptionImpl sub = (SubscriptionImpl) subscriptions.remove(subscriptionId);            ((Set)ids.get(sub.getLocator())).remove(subscriptionId);        }        private Subscription[] getByPath(DavResourceLocator locator) {            Set idSet = (Set) ids.get(locator);            if (idSet != null && !idSet.isEmpty()) {                Iterator idIterator = idSet.iterator();                Subscription[] subsForResource = new Subscription[idSet.size()];                int i = 0;                while (idIterator.hasNext()) {                    SubscriptionImpl s = (SubscriptionImpl) subscriptions.get(idIterator.next());                    subsForResource[i] = new WrappedSubscription(s);                }                return subsForResource;            } else {                return new Subscription[0];            }        }    }}

⌨️ 快捷键说明

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