📄 subscriptionimpl.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.uuid.UUID;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.transaction.TransactionListener;import org.apache.jackrabbit.webdav.jcr.JcrDavSession;import org.apache.jackrabbit.webdav.jcr.JcrDavException;import org.apache.jackrabbit.webdav.observation.EventBundle;import org.apache.jackrabbit.webdav.observation.EventDiscovery;import org.apache.jackrabbit.webdav.observation.EventType;import org.apache.jackrabbit.webdav.observation.Filter;import org.apache.jackrabbit.webdav.observation.ObservationConstants;import org.apache.jackrabbit.webdav.observation.ObservationResource;import org.apache.jackrabbit.webdav.observation.Subscription;import org.apache.jackrabbit.webdav.observation.SubscriptionInfo;import org.apache.jackrabbit.webdav.observation.DefaultEventType;import org.apache.jackrabbit.webdav.xml.DomUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import javax.jcr.RepositoryException;import javax.jcr.Session;import javax.jcr.observation.Event;import javax.jcr.observation.EventIterator;import javax.jcr.observation.EventListener;import javax.jcr.observation.ObservationManager;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * The <code>Subscription</code> class encapsulates a single subscription with * the following responsibilities:<ul> * <li>Providing access to the subscription info,</li> * <li>Recording events this subscription is interested in,</li> * <li>Providing access to the events.</li> * </ul> */public class SubscriptionImpl implements Subscription, ObservationConstants, EventListener { private static Logger log = LoggerFactory.getLogger(SubscriptionImpl.class); private static final long DEFAULT_TIMEOUT = 300000; // 5 minutes /** * Element representing the 'nodeadded' event type. * @see javax.jcr.observation.Event#NODE_ADDED */ private static final String EVENT_NODEADDED = "nodeadded"; /** * Element representing the 'noderemoved' event type. * @see javax.jcr.observation.Event#NODE_REMOVED */ private static final String EVENT_NODEREMOVED = "noderemoved"; /** * Element representing the 'propertyadded' event type. * @see javax.jcr.observation.Event#PROPERTY_ADDED */ private static final String EVENT_PROPERTYADDED = "propertyadded"; /** * Element representing the 'propertyremoved' event type. * @see javax.jcr.observation.Event#PROPERTY_REMOVED */ private static final String EVENT_PROPERTYREMOVED = "propertyremoved"; /** * Element representing the 'propertychanged' event type. * @see javax.jcr.observation.Event#PROPERTY_CHANGED */ private static final String EVENT_PROPERTYCHANGED = "propertychanged"; private SubscriptionInfo info; private long expirationTime; private final DavResourceLocator locator; private final String subscriptionId = UUID.randomUUID().toString(); private final List eventBundles = new ArrayList(); private final ObservationManager obsMgr; /** * Create a new <code>Subscription</code> with the given {@link SubscriptionInfo} * and {@link org.apache.jackrabbit.webdav.observation.ObservationResource resource}. * * @param info * @param resource * @throws DavException if resource is not based on a JCR repository or * the repository does not support observation. */ public SubscriptionImpl(SubscriptionInfo info, ObservationResource resource) throws DavException { setInfo(info); locator = resource.getLocator(); Session s = JcrDavSession.getRepositorySession(resource.getSession()); try { obsMgr = s.getWorkspace().getObservationManager(); } catch (RepositoryException e) { throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, e); } } //-------------------------------------------------------< Subscription >--- /** * Returns the id of this subscription. * * @return subscriptionId */ public String getSubscriptionId() { return subscriptionId; } //----------------------------------------------------< XmlSerializable >--- /** * Return the Xml representation of this <code>Subscription</code> as required * for the {@link org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery} * webdav property that in included in the response body of a sucessful SUBSCRIBE * request or as part of a PROPFIND response. * * @return Xml representation * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(Document) * @param document */ public Element toXml(Document document) { Element subscr = DomUtil.createElement(document, XML_SUBSCRIPTION, NAMESPACE); subscr.appendChild(info.toXml(document)); subscr.appendChild(DomUtil.depthToXml(info.isDeep(), document)); subscr.appendChild(DomUtil.timeoutToXml(info.getTimeOut(), document)); if (getSubscriptionId() != null) { Element id = DomUtil.addChildElement(subscr, XML_SUBSCRIPTIONID, NAMESPACE); id.appendChild(DomUtil.hrefToXml(getSubscriptionId(), document)); } return subscr; } //--------------------------------------------< implementation specific >--- /** * Modify the {@link SubscriptionInfo} for this subscription. * * @param info */ void setInfo(SubscriptionInfo info) { this.info = info; // validate the timeout and adjust value, if it is invalid or missing long timeout = info.getTimeOut(); if (timeout <= 0) { timeout = DEFAULT_TIMEOUT; } expirationTime = System.currentTimeMillis() + timeout; } /** * @return JCR compliant integer representation of the event types defined * for this {@link SubscriptionInfo}. */ int getJcrEventTypes() throws DavException { EventType[] eventTypes = info.getEventTypes(); int events = 0; for (int i = 0; i < eventTypes.length; i++) { events |= getJcrEventType(eventTypes[i]); } return events; } /** * @return a String array with size > 0 or <code>null</code> */ String[] getUuidFilters() { return getFilterValues(XML_UUID); } /** * @return a String array with size > 0 or <code>null</code> */ String[] getNodetypeNameFilters() { return getFilterValues(XML_NODETYPE_NAME); } private String[] getFilterValues(String filterLocalName) { Filter[] filters = info.getFilters(filterLocalName, NAMESPACE); List values = new ArrayList(); for (int i = 0; i < filters.length; i++) { String val = filters[i].getValue(); if (val != null) { values.add(val); } } return (values.size() > 0) ? (String[])values.toArray(new String[values.size()]) : null; } /** * * @return true if a {@link ObservationConstants#XML_NOLOCAL} element * is present in the {@link SubscriptionInfo}. */ boolean isNoLocal() { return info.isNoLocal(); } /** * @return true if this subscription is intended to be deep. */ boolean isDeep() { return info.isDeep(); } /** * @return the locator of the {@link ObservationResource resource} this * <code>Subscription</code> was requested for. */ DavResourceLocator getLocator() { return locator; } /** * Returns true if this <code>Subscription</code> matches the given * resource. * * @param resource * @return true if this <code>Subscription</code> matches the given * resource. */ boolean isSubscribedToResource(ObservationResource resource) { return locator.getResourcePath().equals(resource.getResourcePath()); } /** * Returns true if this <code>Subscription</code> is expired and therefore * stopped recording events. * * @return true if this <code>Subscription</code> is expired */ boolean isExpired() { return System.currentTimeMillis() > expirationTime; } /** * Returns a {@link org.apache.jackrabbit.webdav.observation.EventDiscovery} object listing all events that were * recorded since the last call to this method and clears the list of event * bundles. * * @param timeout time in milliseconds to wait at most for events if none * are present currently. * @return object listing all events that were recorded. * @see #onEvent(EventIterator) */ synchronized EventDiscovery discoverEvents(long timeout) { EventDiscovery ed = new EventDiscovery(); if (eventBundles.isEmpty() && timeout > 0) { try { wait(timeout); } catch (InterruptedException e) { // continue and possibly return empty event discovery } } Iterator it = eventBundles.iterator(); while (it.hasNext()) { EventBundle eb = (EventBundle) it.next(); ed.addEventBundle(eb); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -