jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r180346 [7/9] - in /incubator/jackrabbit/trunk/contrib/jcr-server: ./ client/ client/src/java/org/apache/jackrabbit/client/ client/src/java/org/apache/jackrabbit/webdav/client/methods/ commons/ commons/src/ commons/src/java/ commons/src/java/org/ commons/src/java/org/apache/ commons/src/java/org/apache/jackrabbit/ commons/src/java/org/apache/jackrabbit/nodetype/ commons/src/java/org/apache/jackrabbit/nodetype/xml/ commons/src/java/org/apache/jackrabbit/util/ commons/src/java/org/apache/jackrabbit/util/uuid/ commons/src/java/org/apache/jackrabbit/value/ server/ server/src/java/org/apache/jackrabbit/server/ server/src/java/org/apache/jackrabbit/server/io/ server/src/java/org/apache/jackrabbit/server/jcr/ server/src/java/org/apache/jackrabbit/server/simple/ server/src/java/org/apache/jackrabbit/webdav/jcr/ server/src/java/org/apache/jackrabbit/webdav/jcr/lock/ server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/ server/src/java/org/apache/jackrabbit/webdav/jcr/observation/ server/src/java/org/apache/jackrabbit/webdav/jcr/property/ server/src/java/org/apache/jackrabbit/webdav/jcr/search/ server/src/java/org/apache/jackrabbit/webdav/jcr/transaction/ server/src/java/org/apache/jackrabbit/webdav/jcr/version/ server/src/java/org/apache/jackrabbit/webdav/jcr/version/report/ server/src/java/org/apache/jackrabbit/webdav/simple/ webapp/ webapp/src/java/ webapp/src/java/org/ webapp/src/java/org/apache/ webapp/src/java/org/apache/jackrabbit/ webapp/src/java/org/apache/jackrabbit/j2ee/ webapp/src/webapp/ webapp/src/webapp/WEB-INF/ webdav/ webdav/src/java/org/apache/jackrabbit/webdav/ webdav/src/java/org/apache/jackrabbit/webdav/jcr/ webdav/src/java/org/apache/jackrabbit/webdav/lock/ webdav/src/java/org/apache/jackrabbit/webdav/property/ webdav/src/java/org/apache/jackrabbit/webdav/util/ webdav/src/java/org/apache/jackrabbit/webdav/version/report/
Date Mon, 06 Jun 2005 17:36:13 GMT
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.nodetype;
+
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+
+import javax.jcr.nodetype.NodeType;
+
+/**
+ * <code>NodeTypeElement</code>...
+ */
+public class NodeTypeElement extends Element implements NodeTypeConstants {
+
+    private static Logger log = Logger.getLogger(NodeTypeElement.class);
+
+    public NodeTypeElement(NodeType nt) {
+        super(XML_NODETYPE, NodeTypeConstants.NAMESPACE);
+        addNodeTypeNameElement(nt.getName());
+    }
+
+    public NodeTypeElement(Element ntElement) {
+        super(XML_NODETYPE, NodeTypeConstants.NAMESPACE);
+        if (!XML_NODETYPE.equals(ntElement.getName())) {
+            throw new IllegalArgumentException("jcr:nodetype element expected.");
+        }
+        addNodeTypeNameElement(ntElement.getChildText(XML_NODETYPENAME, NodeTypeConstants.NAMESPACE));
+    }
+
+    private void addNodeTypeNameElement(String nodeTypeName) {
+        if (nodeTypeName != null) {
+        addContent(new Element(XML_NODETYPENAME, NodeTypeConstants.NAMESPACE).setText(nodeTypeName));
+        }
+    }
+
+    public String getNodeTypeName() {
+        return getChildText(XML_NODETYPENAME, NodeTypeConstants.NAMESPACE);
+    }
+    
+    public static NodeTypeElement[] create(NodeType[] nts) {
+        NodeTypeElement[] elems = new NodeTypeElement[nts.length];
+        for (int i = 0; i < nts.length; i++) {
+            elems[i] = new NodeTypeElement(nts[i]);
+        }
+        return elems;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.nodetype;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.jdom.Element;
+
+import javax.jcr.nodetype.NodeType;
+import java.util.*;
+
+/**
+ * <code>NodeTypeProperty</code>...
+ */
+public class NodeTypeProperty extends AbstractDavProperty {
+
+    private static Logger log = Logger.getLogger(NodeTypeProperty.class);
+
+    private final NodeTypeElement[] value;
+
+    public NodeTypeProperty(DavPropertyName name, NodeType nodeType, boolean isProtected) {
+        super(name, isProtected);
+        value = new NodeTypeElement[] {new NodeTypeElement(nodeType)};
+    }
+
+    public NodeTypeProperty(DavPropertyName name, NodeType[] nodeTypes, boolean isProtected) {
+        super(name, isProtected);
+        value = NodeTypeElement.create(nodeTypes);
+    }
+
+    /**
+     * Create a new <code>NodeTypeProperty</code> from the specified general
+     * DavProperty object.
+     *
+     * @param property
+     * @throws IllegalArgumentException if the content of the specified property
+     * contains elements other than {@link NodeTypeConstants#XML_NODETYPE}.
+     */
+    public NodeTypeProperty(DavProperty property) {
+        super(property.getName(), property.isProtected());
+
+        if (property.getValue() instanceof List) {
+            List ntElemList = new ArrayList();
+            Iterator it = ((List) property.getValue()).iterator();
+            while (it.hasNext()) {
+                Object content = it.next();
+                if (content instanceof Element) {
+                    ntElemList.add(new NodeTypeElement((Element)content));
+                }
+            }
+            value = (NodeTypeElement[]) ntElemList.toArray(new NodeTypeElement[ntElemList.size()]);
+        } else if (property.getValue() instanceof Element) {
+	    NodeTypeElement ntElem = new NodeTypeElement((Element)property.getValue());
+	    value = new NodeTypeElement [] {ntElem};
+	} else {
+            value = new NodeTypeElement[0];
+        }
+    }
+
+    /**
+     * Return a set of nodetype names present in this property.
+     *
+     * @return set of nodetype names
+     */
+    public Set getNodeTypeNames() {
+        HashSet names = new HashSet();
+        Object val = getValue();
+        if (val instanceof NodeTypeElement[]) {
+            NodeTypeElement[] elems = (NodeTypeElement[])val;
+            for (int i = 0; i < elems.length; i++) {
+                String ntName = elems[i].getNodeTypeName();
+                if (ntName != null) {
+                    names.add(ntName);
+                }
+            }
+        }
+        return names;
+    }
+
+    /**
+     * Returns the value of this property which is an array of {@link NodeTypeElement}
+     * objects.
+     *
+     * @return an array of {@link NodeTypeElement}s
+     */
+    public Object getValue() {
+        return value;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/NodeTypeProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.nodetype;
+
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.Value;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>PropertyDefinitionImpl</code>...
+ */
+public final class PropertyDefinitionImpl extends ItemDefinitionImpl implements PropertyDefinition {
+
+    private static Logger log = Logger.getLogger(PropertyDefinitionImpl.class);
+
+    private final int type;
+    private final String[] valueConstraints;
+    private final Value[] defaultValues;
+    private final boolean isMultiple;
+
+    private PropertyDefinitionImpl(PropertyDefinition definition) {
+	super(definition);
+
+	type = definition.getRequiredType();
+	valueConstraints = definition.getValueConstraints();
+	defaultValues = definition.getDefaultValues();
+	isMultiple = definition.isMultiple();
+    }
+
+    public static PropertyDefinitionImpl create(PropertyDefinition definition) {
+	if (definition instanceof PropertyDefinitionImpl) {
+	    return (PropertyDefinitionImpl)definition;
+	} else {
+	    return new PropertyDefinitionImpl(definition);
+	}
+    }
+
+    //----------------------------------------< PropertyDefintion interface >---
+    /**
+     * @see PropertyDefinition#getRequiredType()
+     */
+    public int getRequiredType() {
+	return type;
+    }
+
+    /**
+     * @see PropertyDefinition#getValueConstraints()
+     */
+    public String[] getValueConstraints() {
+	return valueConstraints;
+    }
+
+    /**
+     * @see PropertyDefinition#getDefaultValues()
+     */
+    public Value[] getDefaultValues() {
+	return defaultValues;
+    }
+
+    /**
+     * @see PropertyDefinition#isMultiple()
+     */
+    public boolean isMultiple() {
+	return isMultiple;
+    }
+
+    //-------------------------------------< implementation specific method >---
+    /**
+     * Return xml representation
+     *
+     * @return xml representation
+     */
+    public Element toXml() {
+	Element elem = super.toXml();
+
+        elem.setAttribute(MULTIPLE_ATTRIBUTE, Boolean.toString(isMultiple()));
+        elem.setAttribute(REQUIREDTYPE_ATTRIBUTE, PropertyType.nameFromValue(getRequiredType()));
+
+        // default values may be 'null'
+        Value[] values = getDefaultValues();
+        if (values != null) {
+            Element dvElement = new Element(DEFAULTVALUES_ELEMENT);
+            for (int i = 0; i < values.length; i++) {
+                try {
+                    Element valElem = new Element(DEFAULTVALUE_ELEMENT).setText(values[i].getString());
+                    dvElement.addContent(valElem);
+                } catch (RepositoryException e) {
+                    // should not occur
+                    log.error(e.getMessage());
+                }
+            }
+            elem.addContent(dvElement);
+        }
+        // value constraints array is never null.
+        Element constrElem = new Element(VALUECONSTRAINTS_ELEMENT);
+        String[] constraints = getValueConstraints();
+        for (int i = 0; i < constraints.length; i++) {
+            constrElem.addContent(new Element(VALUECONSTRAINT_ELEMENT).setText(constraints[i]));
+        }
+        elem.addContent(constrElem);
+
+        return elem;
+    }
+
+    /**
+     * Returns {@link #PROPERTYDEFINITION_ELEMENT}.
+     * 
+     * @return always returns {@link #PROPERTYDEFINITION_ELEMENT}
+     */
+    public String getElementName() {
+	return PROPERTYDEFINITION_ELEMENT;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/nodetype/PropertyDefinitionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.observation.*;
+import org.apache.jackrabbit.webdav.util.XmlUtil;
+import org.apache.jackrabbit.util.uuid.UUID;
+import org.jdom.Element;
+
+import javax.jcr.observation.*;
+import javax.jcr.observation.EventListener;
+import javax.jcr.RepositoryException;
+import java.util.*;
+
+/**
+ * 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 = Logger.getLogger(SubscriptionImpl.class);
+    private static final long DEFAULT_TIMEOUT = 300000; // 5 minutes
+
+    private SubscriptionInfo info;
+
+    private final DavResourceLocator locator;
+    private final String subscriptionId = UUID.randomUUID().toString();
+    private final List eventBundles = new ArrayList();
+
+    /**
+     * Create a new <code>Subscription</code> with the given {@link SubscriptionInfo}
+     * and {@link org.apache.jackrabbit.webdav.observation.ObservationResource resource}.
+     *
+     * @param info
+     * @param resource
+     */
+    public SubscriptionImpl(SubscriptionInfo info, ObservationResource resource) {
+        setInfo(info);
+        locator = resource.getLocator();
+    }
+
+    /**
+     * Returns the id of this subscription.
+     *
+     * @return subscriptionId
+     */
+    public String getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    /**
+     * 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
+     */
+    public Element toXml() {
+        Element subscr = new Element(XML_SUBSCRIPTION, NAMESPACE);
+        Element[] elems = info.toXml();
+        for (int i = 0; i < elems.length; i++) {
+            subscr.addContent(elems[i]);
+        }
+
+        Element id = new Element(XML_SUBSCRIPTIONID);
+        id.addContent(XmlUtil.hrefToXml(subscriptionId));
+        subscr.addContent(id);
+        return subscr;
+    }
+
+    /**
+     * 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 == DavConstants.UNDEFINED_TIMEOUT) {
+            info.setTimeOut(DEFAULT_TIMEOUT);
+        }
+    }
+
+    /**
+     * @return JCR compliant integer representation of the event types defined
+     * for this {@link SubscriptionInfo}.
+     */
+    int getEventTypes() {
+        Iterator xmlTypes = info.getEventTypes().iterator();
+        int eventTypes = 0;
+        while (xmlTypes.hasNext()) {
+            eventTypes |= nametoTypeConstant(((Element)xmlTypes.next()).getName());
+        }
+        return eventTypes;
+    }
+
+    /**
+     * @return a String array with size > 0 or <code>null</code>
+     */
+    String[] getUuidFilters() {
+        return info.getFilters(XML_UUID);
+    }
+
+    /**
+     * @return a String array with size > 0 or <code>null</code>
+     */
+    String[] getNodetypeNameFilters() {
+        return info.getFilters(XML_NODETYPE_NAME);
+    }
+
+    /**
+     *
+     * @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.equals(resource.getLocator());
+    }
+
+    /**
+     * 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() > info.getTimeOut() + System.currentTimeMillis();
+    }
+
+    /**
+     * 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.
+     *
+     * @return object listing all events that were recorded.
+     * @see #onEvent(EventIterator)
+     */
+    synchronized EventDiscovery discoverEvents() {
+        EventDiscovery ed = new EventDiscovery();
+        Iterator it = eventBundles.iterator();
+        while (it.hasNext()) {
+            EventBundle eb = (EventBundle) it.next();
+            ed.addEventBundle(eb.toXml());
+        }
+        // clear list
+        eventBundles.clear();
+        return ed;
+    }
+
+    //--------------------------------------------< EventListener interface >---
+    /**
+     * Records the events passed as a new event bundle in order to make them
+     * available with the next {@link #discoverEvents()} request.
+     *
+     * @param events to be recorded.
+     * @see EventListener#onEvent(EventIterator)
+     * @see #discoverEvents()
+     */
+    public synchronized void onEvent(EventIterator events) {
+        // TODO: correct not to accept events after expiration? without unsubscribing?
+        if (!isExpired()) {
+            eventBundles.add(new EventBundle(events));
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    /**
+     * Static utility method in order to convert the types defined by
+     * {@link javax.jcr.observation.Event} into their Xml representation.
+     *
+     * @param jcrEventType
+     * @return Xml representation of the event type.
+     */
+    static Element typeConstantToXml(int jcrEventType) {
+        String eventName;
+        switch (jcrEventType) {
+            case Event.NODE_ADDED:
+                eventName = EVENT_NODEADDED;
+                break;
+            case Event.NODE_REMOVED:
+                eventName = EVENT_NODEREMOVED;
+                break;
+            case Event.PROPERTY_ADDED:
+                eventName = EVENT_PROPERTYADDED;
+                break;
+            case Event.PROPERTY_CHANGED:
+                eventName = EVENT_PROPERTYCHANGED;
+                break;
+            default:
+                //Event.PROPERTY_REMOVED:
+                eventName = EVENT_PROPERTYREMOVED;
+                break;
+        }
+        return new Element(eventName, NAMESPACE);
+    }
+
+    /**
+     * Static utility method to convert an event type name as present in the
+     * Xml request body into the corresponding constant defined by
+     * {@link javax.jcr.observation.Event}.
+     *
+     * @param eventTypeName
+     * @return event type as defined by {@link javax.jcr.observation.Event}.
+     * @throws IllegalArgumentException if the given element cannot be translated
+     * to any of the events defined by {@link javax.jcr.observation.Event}.
+     */
+    static int nametoTypeConstant(String eventTypeName) {
+        int eType;
+        if (EVENT_NODEADDED.equals(eventTypeName)) {
+            eType = Event.NODE_ADDED;
+        } else if (EVENT_NODEREMOVED.equals(eventTypeName)) {
+            eType = Event.NODE_REMOVED;
+        } else if (EVENT_PROPERTYADDED.equals(eventTypeName)) {
+            eType = Event.PROPERTY_ADDED;
+        } else if (EVENT_PROPERTYCHANGED.equals(eventTypeName)) {
+            eType = Event.PROPERTY_CHANGED;
+        } else if (EVENT_PROPERTYREMOVED.equals(eventTypeName)) {
+            eType = Event.PROPERTY_REMOVED;
+        } else {
+            throw new IllegalArgumentException("Invalid event type: "+eventTypeName);
+        }
+        return eType;
+    }
+
+    /**
+     * Inner class <code>EventBundle</code> encapsulats an event bundle as
+     * recorded {@link SubscriptionImpl#onEvent(EventIterator) on event} and
+     * provides the possibility to retrieve the Xml representation of the
+     * bundle and the events included in order to respond to a POLL request.
+     *
+     * @see SubscriptionImpl#discoverEvents()
+     */
+    private class EventBundle {
+
+        private final EventIterator events;
+
+        private EventBundle(EventIterator events) {
+            this.events = events;
+        }
+
+        private Element toXml() {
+            Element bundle = new Element(XML_EVENTBUNDLE, NAMESPACE);
+            while (events.hasNext()) {
+                Event event = events.nextEvent();
+
+                Element eventElem = new Element(XML_EVENT, NAMESPACE);
+                // href
+                String eHref = "";
+                try {
+                    boolean isCollection = (event.getType() == Event.NODE_ADDED || event.getType() == Event.NODE_REMOVED);
+                    eHref = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), event.getPath()).getHref(isCollection);
+                } catch (RepositoryException e) {
+                    // should not occur....
+                    log.error(e.getMessage());
+                }
+                eventElem.addContent(XmlUtil.hrefToXml(eHref));
+                // eventtype
+                Element eType = new Element(XML_EVENTTYPE, NAMESPACE).addContent(typeConstantToXml(event.getType()));
+                eventElem.addContent(eType);
+                // user id
+                Element eUserId = new Element(XML_EVENTUSERID, NAMESPACE).setText(event.getUserID());
+                eventElem.addContent(eUserId);
+            }
+            return bundle;
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.log4j.Logger;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.jcr.JcrDavException;
+import org.apache.jackrabbit.webdav.observation.*;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.observation.ObservationManager;
+import java.util.*;
+
+/**
+ * <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 {
+
+    private static Logger log = Logger.getLogger(SubscriptionManager.class);
+
+    /**
+     * Map containing all {@link org.apache.jackrabbit.webdav.observation.Subscription subscriptions}.
+     */
+    private final SubscriptionMap subscriptions = new SubscriptionMap();
+
+    /**
+     * 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.
+     *
+     * @param resource
+     * @todo is it correct to return subscriptions made by another session?
+     */
+    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 {
+
+        SubscriptionImpl subscription;
+        DavSession session = resource.getSession();
+        if (subscriptionId == null) {
+            // new subscription
+            subscription = new SubscriptionImpl(info, resource);
+            registerSubscription(subscription, session);
+
+            // ajust references to this subscription
+            subscriptions.put(subscription.getSubscriptionId(), subscription);
+            session.addReference(subscription.getSubscriptionId());
+        } else {
+            // refresh/modify existing one
+            subscription = validate(subscriptionId, resource);
+            subscription.setInfo(info);
+            registerSubscription(subscription, session);
+        }
+        return subscription;
+    }
+
+    /**
+     * Register the event listener defined by the given subscription to the
+     * repository's observation manager.
+     *
+     * @param subscription
+     * @param session
+     * @throws DavException
+     */
+    private void registerSubscription(SubscriptionImpl subscription, DavSession session)
+            throws DavException {
+        try {
+            ObservationManager oMgr = session.getRepositorySession().getWorkspace().getObservationManager();
+            oMgr.addEventListener(subscription, subscription.getEventTypes(),
+                    subscription.getLocator().getResourcePath(), 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.getSession());
+    }
+
+    /**
+     * Remove the event listener defined by the specified subscription from
+     * the repository's observation manager.
+     *
+     * @param subscription
+     * @param session
+     * @throws DavException
+     */
+    private void unregisterSubscription(SubscriptionImpl subscription,
+                                        DavSession session) throws DavException {
+        try {
+            session.getRepositorySession().getWorkspace().getObservationManager().removeEventListener(subscription);
+            String sId = subscription.getSubscriptionId();
+
+            // clean up any references
+            subscriptions.remove(sId);
+            session.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 resource
+     * @return object encapsulating the events.
+     */
+    public EventDiscovery poll(String subscriptionId, ObservationResource resource)
+            throws DavException {
+
+        SubscriptionImpl subs = validate(subscriptionId, resource);
+        return subs.discoverEvents();
+    }
+
+    /**
+     * 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.getSession());
+                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.");
+        }
+    }
+
+    /**
+     * 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 paths = new HashMap();
+
+        private boolean contains(String subscriptionId) {
+            return subscriptions.containsKey(subscriptionId);
+        }
+
+        private Subscription get(String subscriptionId) {
+            return (Subscription) subscriptions.get(subscriptionId);
+        }
+
+        private void put(String subscriptionId, SubscriptionImpl subscription) {
+            subscriptions.put(subscriptionId, subscription);
+            DavResourceLocator key = subscription.getLocator();
+            Set idSet;
+            if (paths.containsKey(key)) {
+                idSet = (Set) paths.get(key);
+            } else {
+                idSet = new HashSet();
+                paths.put(key, idSet);
+            }
+            if (!idSet.contains(subscriptionId)) {
+                idSet.add(subscriptionId);
+            }
+        }
+
+        private void remove(String subscriptionId) {
+            SubscriptionImpl sub = (SubscriptionImpl) subscriptions.remove(subscriptionId);
+            ((Set)paths.get(sub.getLocator())).remove(subscriptionId);
+        }
+
+        private Subscription[] getByPath(DavResourceLocator locator) {
+            Set idSet = (Set) paths.get(locator);
+            if (idSet != null && !idSet.isEmpty()) {
+                Iterator idIterator = idSet.iterator();
+                Subscription[] subsForResource = new Subscription[idSet.size()];
+                int i = 0;
+                while (idIterator.hasNext()) {
+                    subsForResource[i] = (Subscription) subscriptions.get(idIterator.next());
+                }
+                return subsForResource;
+            } else {
+                return new Subscription[0];
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/package.html
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/package.html?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/package.html (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/package.html Mon Jun  6 10:36:09 2005
@@ -0,0 +1,3 @@
+<body>
+Contains JCR specific implementations.
+</body>
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,56 @@
+/*
+* Copyright 2004 The Apache Software Foundation.
+*
+* Licensed 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.property;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
+import org.jdom.Element;
+
+/**
+ * <code>LengthsProperty</code> extends {@link org.apache.jackrabbit.webdav.property.DavProperty} providing
+ * utilities to handle the multiple lengths of the property item represented
+ * by this resource.
+ */
+public class LengthsProperty extends AbstractDavProperty implements ItemResourceConstants {
+
+    private final Element[] value;
+
+    /**
+     * Create a new <code>LengthsProperty</code> from the given long array.
+     *
+     * @param lengths as retrieved from the JCR property
+     */
+    public LengthsProperty(long[] lengths) {
+	super(JCR_LENGTHS, false);
+
+	Element[] elems = new Element[lengths.length];
+	for (int i = 0; i < lengths.length; i++) {
+	    elems[i] = new Element(XML_LENGTH, ItemResourceConstants.NAMESPACE);
+	    elems[i].addContent(String.valueOf(lengths[i]));
+	}
+	this.value = elems;
+    }
+
+    /**
+     * Returns an array of {@link Element}s representing the value of this
+     * property.
+     *
+     * @return an array of {@link Element}s
+     */
+    public Object getValue() {
+	return value;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/LengthsProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,119 @@
+/*
+* Copyright 2004 The Apache Software Foundation.
+*
+* Licensed 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.property;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
+import org.apache.jackrabbit.value.ValueHelper;
+import org.jdom.Element;
+
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFactory;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * <code>ValuesProperty</code> extends {@link org.apache.jackrabbit.webdav.property.DavProperty} providing
+ * utilities to handle the multiple values of the property item represented
+ * by this resource.
+ */
+public class ValuesProperty extends AbstractDavProperty implements ItemResourceConstants {
+
+    private final Element[] value;
+
+    /**
+     * Create a new <code>ValuesProperty</code> from the given {@link javax.jcr.Value Value
+     * array}.
+     *
+     * @param values Array of Value objects as obtained from the JCR property.
+     */
+    public ValuesProperty(Value[] values) throws ValueFormatException, RepositoryException {
+	super(JCR_VALUES, false);
+
+	Element[] propValue = new Element[values.length];
+	for (int i = 0; i < values.length; i++) {
+	    propValue[i] = new Element(XML_VALUE, ItemResourceConstants.NAMESPACE);
+	    propValue[i].addContent(ValueHelper.serialize(values[i], false));
+	}
+	// finally set the value to the DavProperty
+	value = propValue;
+    }
+    
+    /**
+     * Wrap the specified <code>DavProperty</code> in a new <code>ValuesProperty</code>.
+     *
+     * @param property
+     */
+    public ValuesProperty(DavProperty property) {
+	super(JCR_VALUES, false);
+
+	if (!JCR_VALUES.equals(property.getName())) {
+	    throw new IllegalArgumentException("ValuesProperty may only be created with a property that has name="+JCR_VALUES.getName());
+	}
+
+	Element[] elems = new Element[0];
+	if (property.getValue() instanceof List) {
+	    Iterator elemIt = ((List)property.getValue()).iterator();
+	    ArrayList valueElements = new ArrayList();
+	    while (elemIt.hasNext()) {
+		Object el = elemIt.next();
+		/* make sure, only Elements with name 'value' are used for
+		* the 'value' field. any other content (other elements, text,
+		* comment etc.) is ignored. NO bad-request/conflict error is
+		* thrown.
+		*/
+		if (el instanceof Element && XML_VALUE.equals(((Element)el).getName())) {
+		    valueElements.add(el);
+		}
+	    }
+	    /* fill the 'value' with the valid 'value' elements found before */
+	    elems = (Element[])valueElements.toArray(new Element[valueElements.size()]);
+	} else {
+	    new IllegalArgumentException("ValuesProperty may only be created with a property that has a list of 'value' elements as content.");
+	}
+	// finally set the value to the DavProperty
+	value = elems;
+    }
+
+    /**
+     * Converts the value of this property to a {@link javax.jcr.Value value array}.
+     *
+     * @return Array of Value objects
+     * @throws RepositoryException
+     */
+    public Value[] getValues(ValueFactory fac, int propertyType) throws ValueFormatException, RepositoryException {
+	Element[] propValue = (Element[])getValue();
+	Value[] values = new Value[propValue.length];
+	for (int i = 0; i < propValue.length; i++) {
+	    values[i] = ValueHelper.deserialize(fac, propValue[i].getText(), propertyType, false);
+	}
+	return values;
+    }
+
+    /**
+     * Returns an array of {@link Element}s representing the value of this
+     * property.
+     *
+     * @return an array of {@link Element}s
+     */
+    public Object getValue() {
+	return value;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/property/ValuesProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.search;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.search.SearchResource;
+import org.apache.jackrabbit.webdav.search.QueryGrammerSet;
+import org.apache.jackrabbit.webdav.search.SearchInfo;
+import org.apache.jackrabbit.webdav.jcr.JcrDavException;
+import org.apache.jackrabbit.JcrConstants;
+import org.jdom.Namespace;
+
+import javax.jcr.*;
+import javax.jcr.query.*;
+
+/**
+ * <code>SearchResourceImpl</code>...
+ */
+public class SearchResourceImpl implements SearchResource {
+
+    private static Logger log = Logger.getLogger(SearchResourceImpl.class);
+
+    private final DavSession session;
+    private final DavResourceLocator locator;
+
+    public SearchResourceImpl(DavResourceLocator locator, DavSession session) {
+        this.session = session;
+        this.locator = locator;
+    }
+
+    //-------------------------------------------< SearchResource interface >---
+    /**
+     * @see SearchResource#getQueryGrammerSet()
+     */
+    public QueryGrammerSet getQueryGrammerSet()  {
+        QueryGrammerSet qgs;
+        try {
+            QueryManager qMgr = session.getRepositorySession().getWorkspace().getQueryManager();
+            String[] langs = qMgr.getSupportedQueryLanguages();
+            qgs = new QueryGrammerSet();
+            for (int i = 0; i < langs.length; i++) {
+                // todo: define proper namespace
+                qgs.addQueryLanguage(langs[i], Namespace.NO_NAMESPACE);
+            }
+        } catch (RepositoryException e) {
+            qgs = new QueryGrammerSet(new String[0]);
+        }
+        return qgs;
+    }
+
+    /**
+     * Execute the query defined by the given <code>sInfo</code>.
+     *
+     * @see SearchResource#search(org.apache.jackrabbit.webdav.search.SearchInfo)
+     */
+    public MultiStatus search(SearchInfo sInfo) throws DavException {
+        try {
+            Query q = getQuery(sInfo);
+            QueryResult qR = q.execute();
+            return queryResultToMultiStatus(qR);
+
+        } catch (RepositoryException e) {
+            throw new JcrDavException(e);
+        }
+    }
+
+    /**
+     * Create a query from the information present in the <code>sInfo</code>
+     * object.<br>The following JCR specific logic is applied:
+     * <ul>
+     * <li>If the requested resource represents a node with nodetype nt:query, the
+     * request body is ignored and the query defined with the node is executed
+     * instead.</li>
+     * <li>If the requested resource does not represent an existing item, the
+     * specified query is persisted by calling {@link Query#storeAsNode(String)}.</li>
+     * </ul>
+     * @param sInfo defining the query to be executed
+     * @return <code>Query</code> object.
+     * @throws InvalidQueryException if the query defined by <code>sInfo</code> is invalid
+     * @throws RepositoryException the query manager cannot be accessed or if
+     * another error occurs.
+     * @throws DavException if <code>sInfo</code> is <code>null</code> and
+     * the underlaying repository item is not an nt:query node or if an error
+     * occurs when calling {@link Query#storeAsNode(String)}/
+     */
+    private Query getQuery(SearchInfo sInfo)
+            throws InvalidQueryException, RepositoryException, DavException {
+
+        Node rootNode = session.getRepositorySession().getRootNode();
+        QueryManager qMgr = session.getRepositorySession().getWorkspace().getQueryManager();
+        String resourcePath = locator.getResourcePath();
+
+        // test if query is defined by requested repository node
+        if (!rootNode.getPath().equals(resourcePath)) {
+            String qNodeRelPath = resourcePath.substring(1);
+            if (rootNode.hasNode(qNodeRelPath)) {
+                Node qNode = rootNode.getNode(qNodeRelPath);
+                if (qNode.isNodeType(JcrConstants.NT_QUERY)) {
+                    return qMgr.getQuery(qNode);
+                }
+            }
+        }
+
+        Query q;
+        if (sInfo != null) {
+            q = qMgr.createQuery(sInfo.getQuery(), sInfo.getLanguageName());
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, resourcePath + " is not a nt:query node -> searchRequest body required.");
+        }
+
+        /* test if resource path does not exist -> thus indicating that
+        the query must be made persistent by calling Query.save(String) */
+        if (!session.getRepositorySession().itemExists(resourcePath)) {
+            try {
+                q.storeAsNode(resourcePath);
+            } catch (RepositoryException e) {
+                // ItemExistsException should never occur.
+                new JcrDavException(e);
+            }
+        }
+        return q;
+    }
+
+    /**
+     * Build a <code>MultiStatus</code> object from the specified query result.
+     *
+     * @param qResult <code>QueryResult</code> as obtained from {@link javax.jcr.query.Query#execute()}.
+     * @return <code>MultiStatus</code> object listing the query result in
+     * Webdav compatible form.
+     * @throws RepositoryException
+     */
+    private MultiStatus queryResultToMultiStatus(QueryResult qResult)
+            throws RepositoryException {
+        MultiStatus ms = new MultiStatus();
+
+        String[] columnNames = qResult.getColumnNames();
+        RowIterator rowIter = qResult.getRows();
+        while (rowIter.hasNext()) {
+            Row row = rowIter.nextRow();
+            Value[] values = row.getValues();
+
+            // get the jcr:path column indicating the node path
+            String nodePath = row.getValue(JcrConstants.JCR_PATH).getString();
+            // create a new ms-response for this row of the result set
+            DavResourceLocator loc = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), nodePath);
+            String nodeHref = loc.getHref(true);
+            MultiStatusResponse resp = new MultiStatusResponse(nodeHref);
+            // build the s-r-property
+            SearchResultProperty srp = new SearchResultProperty(columnNames, values);
+            resp.add(srp);
+            ms.addResponse(resp);
+        }
+        return ms;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java Mon Jun  6 10:36:09 2005
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.search;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
+import org.apache.jackrabbit.value.ValueHelper;
+import org.jdom.Element;
+
+import javax.jcr.Value;
+import javax.jcr.RepositoryException;
+import javax.jcr.PropertyType;
+import javax.jcr.ValueFactory;
+import java.util.*;
+
+/**
+ * <code>SearchResultProperty</code>...
+ */
+public class SearchResultProperty extends AbstractDavProperty implements ItemResourceConstants {
+
+    private static Logger log = Logger.getLogger(SearchResultProperty.class);
+
+    public static final DavPropertyName SEARCH_RESULT_PROPERTY = DavPropertyName.create("search-result-property", ItemResourceConstants.NAMESPACE);
+
+    private final String[] columnNames;
+    private final Value[] values;
+
+    /**
+     * Creates a new <code>SearchResultProperty</code>.
+     *
+     * @param columnNames the column names of the search row represented by this
+     * dav property.
+     * @param values the values present in the columns
+     */
+    public SearchResultProperty(String[] columnNames, Value[] values) {
+        super(SEARCH_RESULT_PROPERTY, true);
+        this.columnNames = columnNames;
+        this.values = values;
+    }
+
+    /**
+     * Wrap the specified <code>DavProperty</code> in a new <code>SearchResultProperty</code>.
+     *
+     * @param property
+     * @throws RepositoryException if an error occurs while build the property value
+     * @throws IllegalArgumentException if the specified property does have the
+     * required form.
+     */
+    public SearchResultProperty(ValueFactory fac, DavProperty property) throws RepositoryException {
+        super(SEARCH_RESULT_PROPERTY, true);
+        if (!SEARCH_RESULT_PROPERTY.equals(property.getName())) {
+	    throw new IllegalArgumentException("SearchResultProperty may only be created with a property that has name="+SEARCH_RESULT_PROPERTY.getName());
+	}
+
+        List colList = new ArrayList();
+        List valList = new ArrayList();
+
+        if (property.getValue() instanceof List) {
+            List l = (List) property.getValue();
+
+            String name = null;
+            String value = null;
+            int i = 0;
+            Iterator elemIt = l.iterator();
+            while (elemIt.hasNext()) {
+                Object el = elemIt.next();
+                if (el instanceof Element) {
+                    String txt = ((Element)el).getText();
+                    if (JCR_NAME.getName().equals(((Element)el).getName())) {
+                        name = txt;
+                    } else if (JCR_VALUE.getName().equals(((Element)el).getName())) {
+                        value = txt;
+                    } else if (JCR_TYPE.getName().equals(((Element)el).getName())) {
+                        int type = PropertyType.valueFromName(txt);
+                        if (name == null) {
+                            throw new IllegalArgumentException("SearchResultProperty requires a set of 'jcr:name','jcr:value' and 'jcr:type' xml elements.");
+                        }
+                        colList.add(name);
+                        valList.add((value == null) ? null : ValueHelper.deserialize(fac, value, type, false));
+                        // reset...
+                        name = null;
+                        value = null;
+                        i++;
+                    }
+                }
+            }
+        } else {
+            new IllegalArgumentException("SearchResultProperty requires a set of 'jcr:name','jcr:value' and 'jcr:type' xml elements.");
+        }
+
+        columnNames = (String[]) colList.toArray(new String[colList.size()]);
+        values = (Value[]) valList.toArray(new Value[valList.size()]);
+    }
+
+    /**
+     * Return the column names representing the names of the properties present
+     * in the {@link #getValues() values}.
+     *
+     * @return columnNames
+     */
+    public String[] getColumnNames() {
+        return columnNames;
+    }
+
+    /**
+     * Return the values representing the values of that row in the search
+     * result table.
+     *
+     * @return values
+     * @see javax.jcr.query.Row#getValues()
+     */
+    public Value[] getValues() {
+        return values;
+    }
+
+    /**
+     * Return the value of this webdav property i.e. an list of xml
+     * {@link Element}s. For every value in the query result row represented by
+     * this webdav property a jcr:name, jcr:value and jcr:type element is created.
+     * Example:
+     * <pre>
+     * -----------------------------------------------------------
+     *   col-name  |   bla   |   bli   |  jcr:path  |  jcr:score
+     * -----------------------------------------------------------
+     *   value     |   xxx   |   111   |  /aNode    |    1
+     *   type      |    1    |    3    |     8      |    3
+     * -----------------------------------------------------------
+     * </pre>
+     * results in:
+     * <pre>
+     * &lt;jcr:name&gt;bla&lt;jcr:name/&gt;
+     * &lt;jcr:value&gt;xxx&lt;jcr:value/&gt;
+     * &lt;jcr:type&gt;String&lt;jcr:value/&gt;
+     * &lt;jcr:name&gt;bli&lt;jcr:name/&gt;
+     * &lt;jcr:value&gt;111&lt;jcr:value/&gt;
+     * &lt;jcr:type&gt;Long&lt;jcr:value/&gt;
+     * &lt;jcr:name&gt;jcr:path&lt;jcr:name/&gt;
+     * &lt;jcr:value&gt;/aNode&lt;jcr:value/&gt;
+     * &lt;jcr:type&gt;Path&lt;jcr:value/&gt;
+     * &lt;jcr:name&gt;jcr:score&lt;jcr:name/&gt;
+     * &lt;jcr:value&gt;1&lt;jcr:value/&gt;
+     * &lt;jcr:type&gt;Long&lt;jcr:value/&gt;
+     * </pre>
+     *
+     * @return value of this webdav property consisting of an list of xml elements.
+     * @see org.apache.jackrabbit.webdav.property.DavProperty#getValue()
+     */
+    public Object getValue() {
+        List value = new ArrayList();
+        for (int i = 0; i < columnNames.length; i++) {
+            String propertyName = columnNames[i];
+            Value propertyValue = values[i];
+            String valueStr = null;
+            if (propertyValue != null) {
+                try {
+                    valueStr = propertyValue.getString();
+                } catch (RepositoryException e) {
+                    log.error(e.getMessage());
+                }
+            }
+            String type = (propertyValue == null) ? PropertyType.TYPENAME_STRING : PropertyType.nameFromValue(propertyValue.getType());
+
+            value.add(JCR_NAME.toXml().setText(propertyName));
+            value.add(JCR_VALUE.toXml().setText(valueStr));
+            value.add(JCR_TYPE.toXml().setText(type));
+        }
+        return value;
+    }
+}
\ No newline at end of file

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java
------------------------------------------------------------------------------
    svn = 

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResultProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message