You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2006/09/29 16:44:40 UTC

svn commit: r451313 [2/2] - in /jackrabbit/trunk/contrib/spi: jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/observation/ jcr2spi/src/ma...

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=diff&rev=451313&r1=451312&r2=451313
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Fri Sep 29 07:44:39 2006
@@ -20,13 +20,11 @@
 import org.apache.commons.httpclient.HostConfiguration;
 import org.apache.commons.httpclient.URI;
 import org.apache.commons.httpclient.URIException;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.HttpState;
 import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 import org.apache.commons.httpclient.auth.AuthScope;
 import org.apache.commons.httpclient.methods.HeadMethod;
 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
-import org.apache.commons.collections.map.LRUMap;
 import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
 import org.apache.jackrabbit.webdav.property.DavPropertySet;
 import org.apache.jackrabbit.webdav.property.DavPropertyName;
@@ -58,15 +56,20 @@
 import org.apache.jackrabbit.webdav.client.methods.DavMethod;
 import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
 import org.apache.jackrabbit.webdav.client.methods.MergeMethod;
+import org.apache.jackrabbit.webdav.client.methods.SubscribeMethod;
+import org.apache.jackrabbit.webdav.client.methods.UnSubscribeMethod;
+import org.apache.jackrabbit.webdav.client.methods.PollMethod;
 import org.apache.jackrabbit.webdav.DavConstants;
 import org.apache.jackrabbit.webdav.MultiStatusResponse;
 import org.apache.jackrabbit.webdav.DavServletResponse;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.MultiStatus;
+import org.apache.jackrabbit.webdav.DavMethods;
 import org.apache.jackrabbit.webdav.observation.SubscriptionInfo;
 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.EventDiscovery;
 import org.apache.jackrabbit.webdav.security.SecurityConstants;
 import org.apache.jackrabbit.webdav.security.CurrentUserPrivilegeSetProperty;
 import org.apache.jackrabbit.webdav.security.Privilege;
@@ -91,9 +94,7 @@
 import org.apache.jackrabbit.webdav.jcr.property.NamespacesProperty;
 import org.apache.jackrabbit.webdav.jcr.observation.SubscriptionImpl;
 import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
-import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
-import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.NameFormat;
 import org.apache.jackrabbit.spi.Batch;
@@ -115,6 +116,7 @@
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.IdFactory;
 import org.apache.jackrabbit.spi.LockInfo;
+import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.uuid.UUID;
 import org.apache.jackrabbit.value.ValueFormat;
 import org.apache.jackrabbit.value.QValue;
@@ -138,7 +140,6 @@
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
-import javax.jcr.SimpleCredentials;
 import javax.jcr.LoginException;
 import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.ConstraintViolationException;
@@ -153,6 +154,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Collections;
 import java.io.InputStream;
 import java.io.IOException;
@@ -162,12 +164,24 @@
  */
 // TODO: encapsulate URI building, escaping, unescaping...
 // TODO: cache info objects
-// TODO: improve handling of HttpClient
 // TODO: TO-BE-FIXED. caches don't get adjusted upon removal/move of items
 public class RepositoryServiceImpl implements RepositoryService, DavConstants {
 
     private static Logger log = LoggerFactory.getLogger(RepositoryServiceImpl.class);
 
+
+    private static final EventType[] ALL_EVENTS = new EventType[5];
+    static {
+        ALL_EVENTS[0] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.NODE_ADDED);
+        ALL_EVENTS[1] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.NODE_REMOVED);
+        ALL_EVENTS[2] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_ADDED);
+        ALL_EVENTS[3] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_CHANGED);
+        ALL_EVENTS[4] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_REMOVED);
+    }
+    private static final SubscriptionInfo S_INFO = new SubscriptionInfo(ALL_EVENTS, true, DavConstants.INFINITE_TIMEOUT);
+
+    private static long POLL_INTERVAL = 30000;  // TODO: make configurable
+
     private final IdFactory idFactory;
     private final ValueFactory valueFactory;
 
@@ -175,9 +189,7 @@
     private final NamespaceResolverImpl nsResolver;
     private final URIResolverImpl uriResolver;
 
-    private final HostConfiguration hostConfig;
-    // remember most frequently used http clients
-    private final Map clientCache = Collections.synchronizedMap(new LRUMap());
+    private final HttpClient client;
 
     public RepositoryServiceImpl(String uri, IdFactory idFactory, ValueFactory valueFactory) throws RepositoryException {
         if (uri == null || "".equals(uri)) {
@@ -190,61 +202,38 @@
         this.valueFactory = valueFactory;
 
         try {
+            domFactory = DomUtil.BUILDER_FACTORY.newDocumentBuilder().newDocument();
+        } catch (ParserConfigurationException e) {
+            throw new RepositoryException(e);
+        }
+
+        try {
             URI repositoryUri = new URI((uri.endsWith("/")) ? uri : uri+"/", true);
-            hostConfig = new HostConfiguration();
+            HostConfiguration hostConfig = new HostConfiguration();
             hostConfig.setHost(repositoryUri);
 
-            domFactory = DomUtil.BUILDER_FACTORY.newDocumentBuilder().newDocument();
+            client = new HttpClient(new MultiThreadedHttpConnectionManager());
+            client.setHostConfiguration(hostConfig);
+            // always send authentication not waiting for 401
+            client.getParams().setAuthenticationPreemptive(true);
 
             nsResolver = new NamespaceResolverImpl();
             uriResolver = new URIResolverImpl(repositoryUri, this, nsResolver, domFactory);
 
         } catch (URIException e) {
             throw new RepositoryException(e);
-        } catch (ParserConfigurationException e) {
-            throw new RepositoryException(e);
         }
     }
 
-    private HttpClient getClient(Credentials credentials) {
-        if (clientCache.containsKey(credentials)) {
-            return (HttpClient) clientCache.get(credentials);
-        } else {
-            HttpClient client = new HttpClient();
-            client.setHostConfiguration(hostConfig);
-            UsernamePasswordCredentials creds;
-            if (credentials == null) {
-                // NOTE: null credentials only work if 'missing-auth-mapping' param is set on the server
-                creds = null;
-            } else if (credentials instanceof SimpleCredentials) {
-                SimpleCredentials sCred = (SimpleCredentials) credentials;
-                creds = new UsernamePasswordCredentials(sCred.getUserID(),
-                    String.valueOf(sCred.getPassword()));
-            } else {
-                creds = new UsernamePasswordCredentials(credentials.toString());
-            }
-            HttpState httpState = client.getState();
-
-            // set authentication scope and credentials
-            AuthScope authscope = new AuthScope(hostConfig.getHost(), hostConfig.getPort());
-            httpState.setCredentials(authscope, creds);
-
-            // always send authentication not waiting for 401
-            client.getParams().setAuthenticationPreemptive(true);
-
-            clientCache.put(credentials, client);
-            return client;
+    private static void checkSessionInfo(SessionInfo sessionInfo) throws RepositoryException {
+        if (!(sessionInfo instanceof SessionInfoImpl)) {
+            throw new RepositoryException("Unknown SessionInfo implementation.");
         }
     }
 
-    HttpClient getClient(SessionInfo sessionInfo) {
-        Credentials credentials = null;
-        if (sessionInfo instanceof SessionInfoImpl) {
-            credentials = ((SessionInfoImpl) sessionInfo).getCredentials();
-        } else {
-            log.warn("Unexpected SessionInfo implementation. Using 'null' credentials for connection.");
-        }
-        return getClient(credentials);
+    private static boolean isLockMethod(DavMethod method) {
+        int code = DavMethods.getMethodCode(method.getName());
+        return DavMethods.DAV_LOCK == code || DavMethods.DAV_UNLOCK == code;
     }
 
     private static void initMethod(DavMethod method, SessionInfo sessionInfo, boolean addIfHeader) {
@@ -256,47 +245,28 @@
                 method.setRequestHeader(ifH.getHeaderName(), ifH.getHeaderValue());
             }
         }
-        if (sessionInfo instanceof SessionInfoImpl) {
-            String txId = ((SessionInfoImpl) sessionInfo).getBatchId();
-            if (txId != null) {
-                CodedUrlHeader ch = new CodedUrlHeader(TransactionConstants.HEADER_TRANSACTIONID, txId);
-                method.setRequestHeader(ch.getHeaderName(), ch.getHeaderValue());
-            }
-        }
-    }
-
-    private URIResolver getURIResolver() {
-        return uriResolver;
     }
 
-    private NamespaceResolver getNamespaceResolver() {
-        return nsResolver;
+    private HttpClient getClient(org.apache.commons.httpclient.Credentials credentials) {
+        // NOTE: null credentials only work if 'missing-auth-mapping' param is
+        // set on the server
+        client.getState().setCredentials(AuthScope.ANY, credentials);
+        return client;
     }
 
-    private String getRepositoryUri() {
-        return uriResolver.getRepositoryUri();
-    }
-
-    private String getWorkspaceUri(String workspaceName) {
-        return uriResolver.getWorkspaceUri(workspaceName);
-    }
-
-    private String getRootItemUri(String workspaceName) {
-        return uriResolver.getRootItemUri(workspaceName);
+    HttpClient getClient(SessionInfo sessionInfo) throws RepositoryException {
+        checkSessionInfo(sessionInfo);
+        return getClient(((SessionInfoImpl) sessionInfo).getCredentials().getCredentials());
     }
 
     private String getItemUri(ItemId itemId, SessionInfo sessionInfo) throws RepositoryException {
         return uriResolver.getItemUri(itemId, sessionInfo.getWorkspaceName(), sessionInfo);
     }
 
-    private String getItemUri(ItemId itemId, String workspaceName, SessionInfo sessionInfo) throws RepositoryException {
-        return uriResolver.getItemUri(itemId, workspaceName, sessionInfo);
-    }
-
     private String getItemUri(NodeId parentId, QName childName, SessionInfo sessionInfo) throws RepositoryException {
         String parentUri = uriResolver.getItemUri(parentId, sessionInfo.getWorkspaceName(), sessionInfo);
         try {
-            return parentUri + NameFormat.format(childName, getNamespaceResolver());
+            return parentUri + NameFormat.format(childName, nsResolver);
         } catch (NoPrefixDeclaredException e) {
             throw new RepositoryException(e);
         }
@@ -309,7 +279,7 @@
             HrefProperty parentProp = new HrefProperty(propSet.get(ItemResourceConstants.JCR_PARENT));
             String parentHref = parentProp.getHrefs().get(0).toString();
             if (parentHref != null && parentHref.length() > 0) {
-                parentId = getURIResolver().getNodeId(parentHref, sessionInfo);
+                parentId = uriResolver.getNodeId(parentHref, sessionInfo);
             }
         }
         return parentId;
@@ -317,9 +287,40 @@
 
     //--------------------------------------------------------------------------
 
-    private EventIterator retrieveEvents() {
-        // todo
-        return null;
+    /**
+     * Execute a 'Workspace' operation that immediately needs to return events.
+     *
+     * @param method
+     * @param sessionInfo
+     * @return
+     * @throws RepositoryException
+     */
+    private EventIterator execute(DavMethod method, SessionInfo sessionInfo) throws RepositoryException {
+        // TODO: build specific subscrUri
+        // TODO: check if 'all event' subscription is ok
+        String subscrUri = uriResolver.getRootItemUri(sessionInfo.getWorkspaceName());
+        String subscrId = subscribe(subscrUri, S_INFO, null, sessionInfo);
+        try {
+            if (isLockMethod(method)) {
+                initMethod(method, sessionInfo, false);
+            } else {
+                initMethod(method, sessionInfo, true);
+            }
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+
+            EventIterator events = poll(subscrUri, subscrId, sessionInfo);
+            return events;
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        } finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+            unsubscribe(subscrUri, subscrId, sessionInfo);
+        }
     }
 
 
@@ -338,9 +339,9 @@
         ReportInfo info = new ReportInfo(RepositoryDescriptorsReport.REPOSITORY_DESCRIPTORS_REPORT, DavConstants.DEPTH_0);
         ReportMethod method = null;
         try {
-            method = new ReportMethod(getRepositoryUri(), info);
+            method = new ReportMethod(uriResolver.getRepositoryUri(), info);
 
-            getClient((Credentials) null).executeMethod(method);
+            getClient((org.apache.commons.httpclient.Credentials) null).executeMethod(method);
             method.checkSuccess();
             Document doc = method.getResponseBodyAsDocument();
             Properties descriptors = new Properties();
@@ -376,30 +377,30 @@
      */
     public SessionInfo login(Credentials credentials, String workspaceName)
             throws LoginException, NoSuchWorkspaceException, RepositoryException {
-        if (credentials == null) {
-            // no credentials provided, use JAAS
-            throw new RepositoryException("JAAS authentication not implemented");
-        }
-
-        // interested in workspace href property only, which allows to retrieve the
-        // name of the workspace in case 'workspaceName' is 'null'.
-        DavPropertyNameSet nameSet = new DavPropertyNameSet();
-        nameSet.add(DeltaVConstants.WORKSPACE);
+        // check if the workspace with the given name is accessible
         PropFindMethod method = null;
         try {
-            method = new PropFindMethod(getWorkspaceUri(workspaceName), nameSet, DavConstants.DEPTH_0);
-            getClient(credentials).executeMethod(method);
+            DavPropertyNameSet nameSet = new DavPropertyNameSet();
+            nameSet.add(DeltaVConstants.WORKSPACE);
+            method = new PropFindMethod(uriResolver.getWorkspaceUri(workspaceName), nameSet, DavConstants.DEPTH_0);
+            CredentialsWrapper dc = new CredentialsWrapper(credentials);
+            getClient(dc.getCredentials()).executeMethod(method);
+
             MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
             if (responses.length != 1) {
-                throw new RepositoryException("Unable to retrieve default workspace name.");
+                throw new LoginException("Login failed: Unknown workspace '" + workspaceName+ " '.");
             }
+
             DavPropertySet props = responses[0].getProperties(DavServletResponse.SC_OK);
             if (props.contains(DeltaVConstants.WORKSPACE)) {
                 String wspHref = new HrefProperty(props.get(DeltaVConstants.WORKSPACE)).getHrefs().get(0).toString();
-                String wspName = Text.getName(wspHref, true);
-                return new SessionInfoImpl(credentials, wspName);
+                String wspName = Text.unescape(Text.getName(wspHref, true));
+                if (!wspName.equals(workspaceName)) {
+                    throw new LoginException("Login failed: Invalid workspace name " + workspaceName);
+                }
+                return new SessionInfoImpl(dc, workspaceName, new SubscriptionMgrImpl());
             } else {
-                throw new RepositoryException("Unable to retrieve default workspace name.");
+                throw new LoginException("Login failed: Unknown workspace '" + workspaceName+ " '.");
             }
         } catch (IOException e) {
             throw new RepositoryException(e.getMessage());
@@ -420,7 +421,7 @@
         nameSet.add(DeltaVConstants.WORKSPACE);
         PropFindMethod method = null;
         try {
-            method = new PropFindMethod(getRepositoryUri(), nameSet, DEPTH_1);
+            method = new PropFindMethod(uriResolver.getRepositoryUri(), nameSet, DEPTH_1);
             getClient(sessionInfo).executeMethod(method);
             MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
             Set ids = new HashSet();
@@ -455,7 +456,7 @@
             ReportInfo reportInfo = new ReportInfo(JcrPrivilegeReport.PRIVILEGES_REPORT);
             reportInfo.setContentElement(DomUtil.hrefToXml(uri, domFactory));
 
-            method = new ReportMethod(getWorkspaceUri(sessionInfo.getWorkspaceName()), reportInfo);
+            method = new ReportMethod(uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName()), reportInfo);
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
 
@@ -495,8 +496,8 @@
      * @see RepositoryService#getRootId(SessionInfo)
      */
     public NodeId getRootId(SessionInfo sessionInfo) throws RepositoryException {
-        String rootUri = getRootItemUri(sessionInfo.getWorkspaceName());
-        return getURIResolver().getNodeId(rootUri, sessionInfo);
+        String rootUri = uriResolver.getRootItemUri(sessionInfo.getWorkspaceName());
+        return uriResolver.getNodeId(rootUri, sessionInfo);
     }
 
     /**
@@ -534,21 +535,30 @@
 
             MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
             if (responses.length < 1) {
-                throw new ItemNotFoundException("Unable to retrieve the item with id " + itemId);
+                throw new ItemNotFoundException("Unable to retrieve the item definition for " + itemId);
+            }
+            if (responses.length > 1) {
+                throw new RepositoryException("Internal error: ambigous item definition found '" + itemId + "'.");
             }
-            // todo: make sure the server only sent a single response...
-            // todo: make sure the resourcetype matches the itemId type
-            QItemDefinition definition = null;
             DavPropertySet propertySet = responses[0].getProperties(DavServletResponse.SC_OK);
+
+            // check if definition matches the type of the id
+            DavProperty rType = propertySet.get(DavPropertyName.RESOURCETYPE);
+            if (rType.getValue() == null && itemId.denotesNode()) {
+                throw new RepositoryException("Internal error: requested node definition and got property definition.");
+            }
+
+            // build the definition
+            QItemDefinition definition = null;
             if (propertySet.contains(ItemResourceConstants.JCR_DEFINITION)) {
                 DavProperty prop = propertySet.get(ItemResourceConstants.JCR_DEFINITION);
                 Object value = prop.getValue();
                 if (value != null && value instanceof Element) {
                     Element idfElem = (Element) value;
                     if (itemId.denotesNode()) {
-                        definition = new QNodeDefinitionImpl(null, idfElem, getNamespaceResolver());
+                        definition = new QNodeDefinitionImpl(null, idfElem, nsResolver);
                     } else {
-                        definition = new QPropertyDefinitionImpl(null, idfElem, getNamespaceResolver());
+                        definition = new QPropertyDefinitionImpl(null, idfElem, nsResolver);
                     }
                 }
             }
@@ -636,7 +646,7 @@
             NodeId parentId = getParentId(propSet, sessionInfo);
             NodeId id = uriResolver.buildNodeId(parentId, nodeResponse, sessionInfo.getWorkspaceName());
 
-            NodeInfoImpl nInfo = new NodeInfoImpl(id, parentId, propSet, getNamespaceResolver());
+            NodeInfoImpl nInfo = new NodeInfoImpl(id, parentId, propSet, nsResolver);
 
             for (Iterator it = childResponses.iterator(); it.hasNext();) {
                 MultiStatusResponse resp = (MultiStatusResponse) it.next();
@@ -657,7 +667,7 @@
                 Iterator hrefIter = refProp.getHrefs().iterator();
                 while(hrefIter.hasNext()) {
                     String propertyHref = hrefIter.next().toString();
-                    PropertyId propertyId = getURIResolver().getPropertyId(propertyHref, sessionInfo);
+                    PropertyId propertyId = uriResolver.getPropertyId(propertyHref, sessionInfo);
                     nInfo.addReference(propertyId);
                 }
             }
@@ -669,7 +679,7 @@
             throw ExceptionConverter.generate(e);
         } finally {
             if (method != null) {
-                //method.releaseConnection();
+                method.releaseConnection();
             }
         }
     }
@@ -704,7 +714,7 @@
             NodeId parentId = getParentId(propSet, sessionInfo);
             PropertyId id = uriResolver.buildPropertyId(parentId, responses[0], sessionInfo.getWorkspaceName());
 
-            PropertyInfo pInfo = new PropertyInfoImpl(id, parentId, propSet, getNamespaceResolver(), valueFactory);
+            PropertyInfo pInfo = new PropertyInfoImpl(id, parentId, propSet, nsResolver, valueFactory);
             return pInfo;
         } catch (IOException e) {
             throw new RepositoryException(e);
@@ -718,14 +728,10 @@
     }
 
     /**
-     * @see RepositoryService#createBatch(SessionInfo)
+     * @see RepositoryService#createBatch(ItemId, SessionInfo)
      */
-    public Batch createBatch(SessionInfo sessionInfo) throws RepositoryException {
-        if (sessionInfo instanceof SessionInfoImpl) {
-            return new BatchImpl((SessionInfoImpl)sessionInfo);
-        } else {
-            throw new RepositoryException("Unknown SessionInfo implementation.");
-        }
+    public Batch createBatch(ItemId itemId, SessionInfo sessionInfo) throws RepositoryException {
+        return new BatchImpl(itemId, sessionInfo);
     }
 
     /**
@@ -738,31 +744,33 @@
         BatchImpl batchImpl = (BatchImpl) batch;
         if (batchImpl.isEmpty()) {
             batchImpl.dispose();
-            // TODO build empty eventIterator
-            return null;
+            return IteratorHelper.EMPTY;
         }
         // send batched information
         try {
             HttpClient client = batchImpl.start();
+            EventIterator events;
             boolean success = false;
             try {
                 Iterator it = batchImpl.methods();
                 while (it.hasNext()) {
                     DavMethod method = (DavMethod) it.next();
                     initMethod(method, batchImpl.sessionInfo, true);
+                    // add batchId as separate header
+                    CodedUrlHeader ch = new CodedUrlHeader(TransactionConstants.HEADER_TRANSACTIONID, batchImpl.batchId);
+                    method.setRequestHeader(ch.getHeaderName(), ch.getHeaderValue());
 
                     client.executeMethod(method);
-                    if (!(success = method.succeeded())) {
-                        throw method.getResponseException();
-                    }
+                    method.checkSuccess();
                 }
+                success = true;
             } finally {
                 // make sure the lock is removed. if any of the methods
                 // failed the unlock is used to abort any pending changes
                 // on the server.
-                batchImpl.end(client, success);
+                events = batchImpl.end(client, success);
             }
-            return retrieveEvents();
+            return events;
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
@@ -776,80 +784,33 @@
      * @see RepositoryService#importXml(SessionInfo, NodeId, InputStream, int)
      */
     public EventIterator importXml(SessionInfo sessionInfo, NodeId parentId, InputStream xmlStream, int uuidBehaviour) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        MkColMethod method = null;
-        try {
-            // TODO: improve. currently random name is built instead of retrieving name of new resource from top-level xml element within stream
-            QName nodeName = new QName(QName.NS_DEFAULT_URI, UUID.randomUUID().toString());
-            String uri = getItemUri(parentId, nodeName, sessionInfo);
-            method = new MkColMethod(uri);
-            initMethod(method, sessionInfo, true);
-            method.setRequestEntity(new InputStreamRequestEntity(xmlStream, "text/xml"));
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
+        // TODO: improve. currently random name is built instead of retrieving name of new resource from top-level xml element within stream
+        QName nodeName = new QName(QName.NS_DEFAULT_URI, UUID.randomUUID().toString());
+        String uri = getItemUri(parentId, nodeName, sessionInfo);
+        MkColMethod method = new MkColMethod(uri);
+        method.setRequestEntity(new InputStreamRequestEntity(xmlStream, "text/xml"));
 
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        return execute(method, sessionInfo);
     }
 
     /**
      * @see RepositoryService#move(SessionInfo, NodeId, NodeId, QName)
      */
     public EventIterator move(SessionInfo sessionInfo, NodeId srcNodeId, NodeId destParentNodeId, QName destName) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        MoveMethod method = null;
-        try {
-            String uri = getItemUri(srcNodeId, sessionInfo);
-            String destUri = getItemUri(destParentNodeId, destName, sessionInfo);
-            method = new MoveMethod(uri, destUri, true);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        String uri = getItemUri(srcNodeId, sessionInfo);
+        String destUri = getItemUri(destParentNodeId, destName, sessionInfo);
+        MoveMethod method = new MoveMethod(uri, destUri, true);
+        return execute(method, sessionInfo);
     }
 
     /**
      * @see RepositoryService#copy(SessionInfo, String, NodeId, NodeId, QName)
      */
     public EventIterator copy(SessionInfo sessionInfo, String srcWorkspaceName, NodeId srcNodeId, NodeId destParentNodeId, QName destName) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
-        CopyMethod method = null;
-        try {
-            String uri = getItemUri(srcNodeId, srcWorkspaceName, sessionInfo);
-            String destUri = getItemUri(destParentNodeId, destName, sessionInfo);
-            method = new CopyMethod(uri, destUri, true, false);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        String uri = uriResolver.getItemUri(srcNodeId, srcWorkspaceName, sessionInfo);
+        String destUri = getItemUri(destParentNodeId, destName, sessionInfo);
+        CopyMethod method = new CopyMethod(uri, destUri, true, false);
+        return execute(method, sessionInfo);
     }
 
     /**
@@ -857,7 +818,7 @@
      */
     public EventIterator update(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
         String uri = getItemUri(nodeId, sessionInfo);
-        String workspUri = getWorkspaceUri(srcWorkspaceName);
+        String workspUri = uriResolver.getWorkspaceUri(srcWorkspaceName);
 
         return update(uri, new String[] {workspUri}, UpdateInfo.UPDATE_BY_WORKSPACE, false, sessionInfo);
     }
@@ -867,7 +828,7 @@
      */
     public EventIterator clone(SessionInfo sessionInfo, String srcWorkspaceName, NodeId srcNodeId, NodeId destParentNodeId, QName destName, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
         // TODO: missing implementation
-        return null;
+        throw new UnsupportedOperationException("Missing implementation");
     }
 
     /**
@@ -913,30 +874,20 @@
      * @see RepositoryService#lock(SessionInfo, NodeId, boolean)
      */
     public EventIterator lock(SessionInfo sessionInfo, NodeId nodeId, boolean deep) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
-        LockMethod method = null;
         try {
             String uri = getItemUri(nodeId, sessionInfo);
-            method = new LockMethod(uri, Scope.EXCLUSIVE, Type.WRITE, null, DavConstants.INFINITE_TIMEOUT, true);
-            initMethod(method, sessionInfo, false);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
+            LockMethod method = new LockMethod(uri, Scope.EXCLUSIVE, Type.WRITE, null, DavConstants.INFINITE_TIMEOUT, true);
+            EventIterator events = execute(method, sessionInfo);
 
             String lockToken = method.getLockToken();
             sessionInfo.addLockToken(lockToken);
 
             // TODO: ev. need to take care of 'timeout' ?
             // TODO: ev. evaluate lock response, if depth and type is according to request?
+            return events;
 
-            return retrieveEvents();
         } catch (IOException e) {
             throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
 
@@ -944,112 +895,51 @@
      * @see RepositoryService#refreshLock(SessionInfo, NodeId)
      */
     public EventIterator refreshLock(SessionInfo sessionInfo, NodeId nodeId) throws LockException, RepositoryException {
-        LockMethod method = null;
-        try {
-            String uri = getItemUri(nodeId, sessionInfo);
-            // since sessionInfo does not allow to retrieve token by NodeId,
-            // pass all available lock tokens to the LOCK method (TODO: correct?)
-            method = new LockMethod(uri, DavConstants.INFINITE_TIMEOUT, sessionInfo.getLockTokens());
-            initMethod(method, sessionInfo, false);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        String uri = getItemUri(nodeId, sessionInfo);
+        // since sessionInfo does not allow to retrieve token by NodeId,
+        // pass all available lock tokens to the LOCK method (TODO: correct?)
+        LockMethod method = new LockMethod(uri, DavConstants.INFINITE_TIMEOUT, sessionInfo.getLockTokens());
+        return execute(method, sessionInfo);
     }
 
     /**
      * @see RepositoryService#unlock(SessionInfo, NodeId)
      */
     public EventIterator unlock(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
-        UnLockMethod method = null;
-        try {
-            String uri = getItemUri(nodeId, sessionInfo);
-            // Note: since sessionInfo does not allow to identify the id of the
-            // lock holding node, we need to access the token via lockInfo
-            // TODO: review this.
-            LockInfo lInfo = getLockInfo(sessionInfo, nodeId);
-            String lockToken = lInfo.getLockToken();
-
-            // TODO: ev. additional check if lt is present on the sessionInfo?
+        String uri = getItemUri(nodeId, sessionInfo);
+        // Note: since sessionInfo does not allow to identify the id of the
+        // lock holding node, we need to access the token via lockInfo
+        // TODO: review this.
+        LockInfo lInfo = getLockInfo(sessionInfo, nodeId);
+        String lockToken = lInfo.getLockToken();
 
-            method = new UnLockMethod(uri, lockToken);
-            initMethod(method, sessionInfo, false);
+        // TODO: ev. additional check if lt is present on the sessionInfo?
 
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
+        UnLockMethod method = new UnLockMethod(uri, lockToken);
+        EventIterator events = execute(method, sessionInfo);
 
-            sessionInfo.removeLockToken(lockToken);
-
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        sessionInfo.removeLockToken(lockToken);
+        return events;
     }
 
     /**
      * @see RepositoryService#checkin(SessionInfo, NodeId)
      */
     public EventIterator checkin(SessionInfo sessionInfo, NodeId nodeId) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
-        CheckinMethod method = null;
-        try {
-            String uri = getItemUri(nodeId, sessionInfo);
-            method = new CheckinMethod(uri);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
+        String uri = getItemUri(nodeId, sessionInfo);
+        CheckinMethod method = new CheckinMethod(uri);
 
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        return execute(method, sessionInfo);
     }
 
     /**
      * @see RepositoryService#checkout(SessionInfo, NodeId)
      */
     public EventIterator checkout(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
-        CheckoutMethod method = null;
-        try {
-            String uri = getItemUri(nodeId, sessionInfo);
-            method = new CheckoutMethod(uri);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
+        String uri = getItemUri(nodeId, sessionInfo);
+        CheckoutMethod method = new CheckoutMethod(uri);
 
-            return retrieveEvents();
-        } catch (IOException e) {
-            throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
-        }
+        return execute(method, sessionInfo);
     }
 
     /**
@@ -1066,7 +956,7 @@
      * @see RepositoryService#restore(SessionInfo, NodeId[], boolean)
      */
     public EventIterator restore(SessionInfo sessionInfo, NodeId[] versionIds, boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
-        String uri = getWorkspaceUri(sessionInfo.getWorkspaceName());
+        String uri = uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName());
         String[] vUris = new String[versionIds.length];
         for (int i = 0; i < versionIds.length; i++) {
             vUris[i] = getItemUri(versionIds[i], sessionInfo);
@@ -1076,7 +966,6 @@
     }
 
     private EventIterator update(String uri, String[] updateSource, int updateType, boolean removeExisting, SessionInfo sessionInfo) throws RepositoryException {
-        UpdateMethod method = null;
         try {
             UpdateInfo uInfo;
             if (removeExisting) {
@@ -1087,49 +976,30 @@
                 uInfo = new UpdateInfo(updateSource, updateType, new DavPropertyNameSet());
             }
 
-            method = new UpdateMethod(uri, uInfo);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
+            UpdateMethod method = new UpdateMethod(uri, uInfo);
+            return execute(method, sessionInfo);
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
     /**
      * @see RepositoryService#merge(SessionInfo, NodeId, String, boolean)
      */
     public EventIterator merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
-        MergeMethod method = null;
         try {
-            String wspHref = getWorkspaceUri(srcWorkspaceName);
+            String wspHref = uriResolver.getWorkspaceUri(srcWorkspaceName);
             Element mElem = MergeInfo.createMergeElement(new String[] {wspHref}, bestEffort, false, domFactory);
             MergeInfo mInfo = new MergeInfo(mElem);
 
-            method = new MergeMethod(getItemUri(nodeId, sessionInfo), mInfo);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
+            MergeMethod method = new MergeMethod(getItemUri(nodeId, sessionInfo), mInfo);
             // TODO: need to evaluate response?
-            return retrieveEvents();
+            return execute(method, sessionInfo);
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
 
@@ -1137,7 +1007,6 @@
      * @see RepositoryService#resolveMergeConflict(SessionInfo, NodeId, NodeId[], NodeId[])
      */
     public EventIterator resolveMergeConflict(SessionInfo sessionInfo, NodeId nodeId, NodeId[] mergeFailedIds, NodeId[] predecessorIds) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
-        PropPatchMethod method = null;
         try {
             List changeList = new ArrayList();
             String[] mergeFailedHref = new String[mergeFailedIds.length];
@@ -1154,22 +1023,11 @@
                 changeList.add(new HrefProperty(VersionControlledResource.PREDECESSOR_SET, pdcHrefs, false));
             }
 
-            method = new PropPatchMethod(getItemUri(nodeId, sessionInfo), changeList);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
+            PropPatchMethod method = new PropPatchMethod(getItemUri(nodeId, sessionInfo), changeList);
             // TODO: ev. evaluate response
-            return retrieveEvents();
+            return execute(method, sessionInfo);
         } catch (IOException e) {
             throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
 
@@ -1177,26 +1035,14 @@
      * @see RepositoryService#addVersionLabel(SessionInfo,NodeId,NodeId,QName,boolean)
      */
     public EventIterator addVersionLabel(SessionInfo sessionInfo, NodeId versionHistoryId, NodeId versionId, QName label, boolean moveLabel) throws VersionException, RepositoryException {
-        LabelMethod method = null;
-        try {
+         try {
             String uri = getItemUri(versionId, sessionInfo);
-            method = new LabelMethod(uri, NameFormat.format(label, getNamespaceResolver()), (moveLabel) ? LabelInfo.TYPE_SET : LabelInfo.TYPE_ADD);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
+            LabelMethod method = new LabelMethod(uri, NameFormat.format(label, nsResolver), (moveLabel) ? LabelInfo.TYPE_SET : LabelInfo.TYPE_ADD);
+            return execute(method, sessionInfo);
         } catch (IOException e) {
             throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
         } catch (NoPrefixDeclaredException e) {
             throw new RepositoryException(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
 
@@ -1204,26 +1050,14 @@
      * @see RepositoryService#removeVersionLabel(SessionInfo,NodeId,NodeId,QName)
      */
     public EventIterator removeVersionLabel(SessionInfo sessionInfo, NodeId versionHistoryId, NodeId versionId, QName label) throws VersionException, RepositoryException {
-        LabelMethod method = null;
         try {
             String uri = getItemUri(versionId, sessionInfo);
-            method = new LabelMethod(uri, NameFormat.format(label, getNamespaceResolver()), LabelInfo.TYPE_REMOVE);
-            initMethod(method, sessionInfo, true);
-
-            getClient(sessionInfo).executeMethod(method);
-            method.checkSuccess();
-
-            return retrieveEvents();
+            LabelMethod method = new LabelMethod(uri, NameFormat.format(label, nsResolver), LabelInfo.TYPE_REMOVE);
+            return execute(method, sessionInfo);
         } catch (IOException e) {
             throw new RepositoryException(e);
-        } catch (DavException e) {
-            throw ExceptionConverter.generate(e);
         } catch (NoPrefixDeclaredException e) {
             throw new RepositoryException(e);
-        } finally {
-            if (method != null) {
-                method.releaseConnection();
-            }
         }
     }
 
@@ -1231,7 +1065,7 @@
      * @see RepositoryService#getSupportedQueryLanguages(SessionInfo)
      */
     public String[] getSupportedQueryLanguages(SessionInfo sessionInfo) throws RepositoryException {
-        OptionsMethod method = new OptionsMethod(getWorkspaceUri(sessionInfo.getWorkspaceName()));
+        OptionsMethod method = new OptionsMethod(uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName()));
         try {
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
@@ -1243,6 +1077,10 @@
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
+        } finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
         }
     }
 
@@ -1250,23 +1088,29 @@
      * @see RepositoryService#executeQuery(SessionInfo, String, String)
      */
     public QueryInfo executeQuery(SessionInfo sessionInfo, String statement, String language) throws RepositoryException {
+        SearchMethod method = null;
         try {
-            SearchMethod method = new SearchMethod(getWorkspaceUri(sessionInfo.getWorkspaceName()), statement, language);
+            String uri = uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName());
+            method = new SearchMethod(uri, statement, language);
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
 
             MultiStatus ms = method.getResponseBodyAsMultiStatus();
-            return new QueryInfoImpl(ms, sessionInfo, getURIResolver(),
-                getNamespaceResolver(), valueFactory);
+            return new QueryInfoImpl(ms, sessionInfo, uriResolver,
+                nsResolver, valueFactory);
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
+        }  finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
         }
     }
 
     /**
-     * @see RepositoryService#addEventListener(SessionInfo, NodeId, EventListener, int, boolean, String[], QName[])
+     * @see RepositoryService#addEventListener(SessionInfo,NodeId,EventListener,int,boolean,String[],QName[])
      */
     public void addEventListener(SessionInfo sessionInfo, NodeId nodeId, EventListener listener, int eventTypes, boolean isDeep, String[] uuids, QName[] nodeTypeIds) throws RepositoryException {
         // build event types
@@ -1290,31 +1134,116 @@
 
         // build filters from params
         List filters = new ArrayList();
-        for (int i = 0; i < uuids.length; i++) {
+        for (int i = 0; uuids != null && i < uuids.length; i++) {
             filters.add(new Filter(ObservationConstants.XML_UUID, ObservationConstants.NAMESPACE, uuids[i]));
         }
-        for (int i = 0; i < nodeTypeIds.length; i++) {
+        for (int i = 0; nodeTypeIds != null && i < nodeTypeIds.length; i++) {
             try {
-                String ntName = NameFormat.format(nodeTypeIds[i], getNamespaceResolver());
+                String ntName = NameFormat.format(nodeTypeIds[i], nsResolver);
                 filters.add(new Filter(ObservationConstants.XML_NODETYPE_NAME, ObservationConstants.NAMESPACE, ntName));
             } catch (NoPrefixDeclaredException e) {
                 throw new RepositoryException(e);
             }
         }
         Filter[] ftArr = (Filter[]) filters.toArray(new Filter[filters.size()]);
-        // always 'noLocal' since local changes are reported by return values
-        boolean noLocal = true;
 
+        boolean noLocal = true;
         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(etArr, ftArr, noLocal, isDeep, DavConstants.UNDEFINED_TIMEOUT);
+        String uri = getItemUri(nodeId, sessionInfo);
 
-        // TODO: missing implementation
+        checkSessionInfo(sessionInfo);
+        SubscriptionManager sMgr = ((SessionInfoImpl)sessionInfo).getSubscriptionManager();
+
+        if (sMgr.subscriptionExists(listener)) {
+            String subscriptionId = sMgr.getSubscriptionId(listener);
+            subscribe(uri, subscriptionInfo, subscriptionId, sessionInfo);
+            log.debug("Subscribed on server for listener " + listener);
+        } else {
+            String subscriptionId = subscribe(uri, subscriptionInfo, null, sessionInfo);
+            log.debug("Subscribed on server for listener " + listener);
+            sMgr.addSubscription(uri, subscriptionId, listener);
+            log.debug("Added subscription for listener " + listener);
+        }
     }
 
     /**
      * @see RepositoryService#removeEventListener(SessionInfo, NodeId, EventListener)
      */
     public void removeEventListener(SessionInfo sessionInfo, NodeId nodeId, EventListener listener) throws RepositoryException {
-        // TODO: missing implementation
+        checkSessionInfo(sessionInfo);
+        SubscriptionManager sMgr = ((SessionInfoImpl)sessionInfo).getSubscriptionManager();
+        String subscriptionId = sMgr.getSubscriptionId(listener);
+
+        String uri = getItemUri(nodeId, sessionInfo);
+        sMgr.removeSubscription(listener);
+        log.debug("Removed subscription for listener " + listener);
+        unsubscribe(uri, subscriptionId, sessionInfo);
+        log.debug("Unsubscribed on server for listener " + listener);
+    }
+
+
+    private String subscribe(String uri, SubscriptionInfo subscriptionInfo, String subscriptionId, SessionInfo sessionInfo) throws RepositoryException {
+        SubscribeMethod method = null;
+        try {
+            if (subscriptionId != null) {
+                method = new SubscribeMethod(uri, subscriptionInfo, subscriptionId);
+            } else {
+                method = new SubscribeMethod(uri, subscriptionInfo);
+            }
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+            return method.getSubscriptionId();
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        }  finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
+    }
+
+    private void unsubscribe(String uri, String subscriptionId, SessionInfo sessionInfo) throws RepositoryException {
+        UnSubscribeMethod method = null;
+        try {
+            method = new UnSubscribeMethod(uri, subscriptionId);
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        }  finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
+    }
+
+    private EventIterator poll(String uri, String subscriptionId,  SessionInfo sessionInfo) throws RepositoryException {
+        PollMethod method = null;
+        try {
+            method = new PollMethod(uri, subscriptionId);
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+
+            EventDiscovery disc = method.getResponseAsEventDiscovery();
+            if (disc.isEmpty()) {
+                return IteratorHelper.EMPTY;
+            } else {
+                Element discEl = disc.toXml(domFactory);
+                return new EventIteratorImpl(discEl, uriResolver, sessionInfo);
+            }
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        }  finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
     }
 
     /**
@@ -1324,7 +1253,7 @@
         ReportInfo info = new ReportInfo(RegisteredNamespacesReport.REGISTERED_NAMESPACES_REPORT, DEPTH_0);
         ReportMethod method = null;
         try {
-            method = new ReportMethod(getWorkspaceUri(sessionInfo.getWorkspaceName()), info);
+            method = new ReportMethod(uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName()), info);
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
 
@@ -1407,7 +1336,7 @@
 
         PropPatchMethod method = null;
         try {
-            String uri = getWorkspaceUri(sessionInfo.getWorkspaceName());
+            String uri = uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName());
 
             method = new PropPatchMethod(uri, setProperties, new DavPropertyNameSet());
             initMethod(method, sessionInfo, true);
@@ -1434,7 +1363,8 @@
 
         ReportMethod method = null;
         try {
-            method = new ReportMethod(getWorkspaceUri(sessionInfo.getWorkspaceName()), info);
+            String workspaceUri = uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName());
+            method = new ReportMethod(workspaceUri, info);
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
 
@@ -1442,7 +1372,7 @@
             ElementIterator it = DomUtil.getChildren(reportDoc.getDocumentElement(), NodeTypeConstants.NODETYPE_ELEMENT, null);
             List ntDefs = new ArrayList();
             while (it.hasNext()) {
-                ntDefs.add(new QNodeTypeDefinitionImpl(it.nextElement(), getNamespaceResolver()));
+                ntDefs.add(new QNodeTypeDefinitionImpl(it.nextElement(), nsResolver));
             }
             return new IteratorHelper(ntDefs);
         } catch (IOException e) {
@@ -1480,22 +1410,38 @@
         throw new UnsupportedRepositoryOperationException("JSR170 does not defined methods to unregister nodetypes.");
     }
 
+    /**
+     * The XML elements and attributes used in serialization
+     */
+    private static final Namespace SV_NAMESPACE = Namespace.getNamespace(QName.NS_SV_PREFIX, QName.NS_SV_URI);
+    private static final String NODE_ELEMENT = "node";
+    private static final String PROPERTY_ELEMENT = "property";
+    private static final String VALUE_ELEMENT = "value";
+    private static final String NAME_ATTRIBUTE = "name";
+    private static final String TYPE_ATTRIBUTE = "type";
+
     //------------------------------------------------< Inner Class 'Batch' >---
     private class BatchImpl implements Batch {
 
-        private final SessionInfoImpl sessionInfo;
+        private final SessionInfo sessionInfo;
+        private final ItemId targetId;
         private final List methods = new ArrayList();
 
+        private String batchId;
+        private String subscriptionId;
+
         private boolean isConsumed = false;
 
-        private BatchImpl(SessionInfoImpl sessionInfo) {
+        private BatchImpl(ItemId targetId, SessionInfo sessionInfo) {
+            this.targetId = targetId;
             this.sessionInfo = sessionInfo;
         }
 
         private HttpClient start() throws RepositoryException {
             checkConsumed();
             try {
-                String uri = getRootItemUri(sessionInfo.getWorkspaceName());
+                String uri = getItemUri(targetId, sessionInfo);
+                // start special 'lock'
                 LockMethod method = new LockMethod(uri, TransactionConstants.LOCAL, TransactionConstants.TRANSACTION, null, DavConstants.INFINITE_TIMEOUT, true);
                 initMethod(method, sessionInfo, false);
 
@@ -1503,8 +1449,11 @@
                 client.executeMethod(method);
                 method.checkSuccess();
 
-                String batchId = method.getLockToken();
-                sessionInfo.setBatchId(batchId);
+                batchId = method.getLockToken();
+
+                // register subscription
+                String subscrUri = (targetId.denotesNode() ? uri : getItemUri(((PropertyId) targetId).getParentId(), sessionInfo));
+                subscriptionId = subscribe(subscrUri, S_INFO, null, sessionInfo);
                 return client;
             } catch (IOException e) {
                 throw new RepositoryException(e);
@@ -1513,11 +1462,11 @@
             }
         }
 
-        private void end(HttpClient client, boolean discard) throws RepositoryException {
+        private EventIterator end(HttpClient client, boolean commit) throws RepositoryException {
             checkConsumed();
             try {
-                String uri = getRootItemUri(sessionInfo.getWorkspaceName());
-                UnLockMethod method = new UnLockMethod(uri, sessionInfo.getBatchId());
+                String uri = getItemUri(targetId, sessionInfo);
+                UnLockMethod method = new UnLockMethod(uri, batchId);
                 // todo: check if 'initmethod' would work (ev. conflict with TxId header).
                 String[] locktokens = sessionInfo.getLockTokens();
                 if (locktokens != null && locktokens.length > 0) {
@@ -1526,12 +1475,17 @@
                 }
                 // in contrast to standard UNLOCK, the tx-unlock provides a
                 // request body.
-                method.setRequestBody(new TransactionInfo(!discard));
+                method.setRequestBody(new TransactionInfo(commit));
 
                 client.executeMethod(method);
                 method.checkSuccess();
-                // make sure the batchId on the sessionInfo is reset.
-                sessionInfo.setBatchId(null);
+
+                // retrieve events && unsubscribe
+                String subscrUri = (targetId.denotesNode() ? uri : getItemUri(((PropertyId) targetId).getParentId(), sessionInfo));
+                EventIterator events = poll(subscrUri, subscriptionId, sessionInfo);
+                unsubscribe(subscrUri, subscriptionId, sessionInfo);
+
+                return events;
             } catch (IOException e) {
                 throw new RepositoryException(e);
             } catch (DavException e) {
@@ -1560,16 +1514,6 @@
 
         //----------------------------------------------------------< Batch >---
         /**
-         * The XML elements and attributes used in serialization
-         */
-        private final Namespace SV_NAMESPACE = Namespace.getNamespace(QName.NS_SV_PREFIX, QName.NS_SV_URI);
-        private final String NODE_ELEMENT = "node";
-        private final String PROPERTY_ELEMENT = "property";
-        private final String VALUE_ELEMENT = "value";
-        private final String NAME_ATTRIBUTE = "name";
-        private final String TYPE_ATTRIBUTE = "type";
-
-        /**
          * @see Batch#addNode(NodeId, QName, QName, String)
          */
         public void addNode(NodeId parentId, QName nodeName, QName nodetypeName, String uuid) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, NoSuchNodeTypeException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
@@ -1586,13 +1530,13 @@
 
                     if (nodetypeName != null) {
                         Element propElement = DomUtil.addChildElement(nodeElement, PROPERTY_ELEMENT, SV_NAMESPACE);
-                        DomUtil.setAttribute(propElement, NAME_ATTRIBUTE, SV_NAMESPACE, NameFormat.format(QName.JCR_PRIMARYTYPE, getNamespaceResolver()));
+                        DomUtil.setAttribute(propElement, NAME_ATTRIBUTE, SV_NAMESPACE, NameFormat.format(QName.JCR_PRIMARYTYPE, nsResolver));
                         DomUtil.setAttribute(propElement, TYPE_ATTRIBUTE, SV_NAMESPACE, PropertyType.nameFromValue(PropertyType.NAME));
-                        DomUtil.addChildElement(propElement, VALUE_ELEMENT, SV_NAMESPACE, NameFormat.format(nodetypeName, getNamespaceResolver()));
+                        DomUtil.addChildElement(propElement, VALUE_ELEMENT, SV_NAMESPACE, NameFormat.format(nodetypeName, nsResolver));
                     }
                     if (uuid != null) {
                         Element propElement = DomUtil.addChildElement(nodeElement, PROPERTY_ELEMENT, SV_NAMESPACE);
-                        DomUtil.setAttribute(propElement, NAME_ATTRIBUTE, SV_NAMESPACE, NameFormat.format(QName.JCR_UUID, getNamespaceResolver()));
+                        DomUtil.setAttribute(propElement, NAME_ATTRIBUTE, SV_NAMESPACE, NameFormat.format(QName.JCR_UUID, nsResolver));
                         DomUtil.setAttribute(propElement, TYPE_ATTRIBUTE, SV_NAMESPACE, PropertyType.nameFromValue(PropertyType.STRING));
                         DomUtil.addChildElement(propElement, VALUE_ELEMENT, SV_NAMESPACE, uuid);
                     }
@@ -1615,7 +1559,7 @@
         public void addProperty(NodeId parentId, QName propertyName, String value, int propertyType) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
             checkConsumed();
             QValue qV = QValue.create(value, propertyType);
-            Value jcrValue = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+            Value jcrValue = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
             ValuesProperty vp = new ValuesProperty(jcrValue);
             internalAddProperty(parentId, propertyName, vp);
         }
@@ -1628,7 +1572,7 @@
             Value[] jcrValues = new Value[values.length];
             for (int i = 0; i < values.length; i++) {
                 QValue v = QValue.create(values[i], propertyType);
-                jcrValues[i] = ValueFormat.getJCRValue(v, getNamespaceResolver(), valueFactory);
+                jcrValues[i] = ValueFormat.getJCRValue(v, nsResolver, valueFactory);
             }
             ValuesProperty vp = new ValuesProperty(jcrValues);
             internalAddProperty(parentId, propertyName, vp);
@@ -1642,7 +1586,7 @@
             QValue qV = null;
             try {
                 qV = QValue.create(value, propertyType);
-                Value jcrValue = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                Value jcrValue = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                 ValuesProperty vp = new ValuesProperty(jcrValue);
                 internalAddProperty(parentId, propertyName, vp);
             } catch (IOException e) {
@@ -1659,7 +1603,7 @@
                 Value[] jcrValues = new Value[values.length];
                 for (int i = 0; i < values.length; i++) {
                     QValue qV = QValue.create(values[i], propertyType);
-                    jcrValues[i] = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                    jcrValues[i] = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                 }
                 ValuesProperty vp = new ValuesProperty(jcrValues);
                 internalAddProperty(parentId, propertyName, vp);
@@ -1693,7 +1637,7 @@
             } else {
                 // qualified value must be converted to jcr value
                 QValue qV = QValue.create(value, propertyType);
-                Value jcrValue = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                Value jcrValue = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                 ValuesProperty vp = new ValuesProperty(jcrValue);
                 setProperties.add(vp);
             }
@@ -1714,7 +1658,7 @@
                 Value[] jcrValues = new Value[values.length];
                 for (int i = 0; i < values.length; i++) {
                     QValue qV = QValue.create(values[i], propertyType);
-                    jcrValues[i] = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                    jcrValues[i] = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                 }
                 setProperties.add(new ValuesProperty(jcrValues));
             }
@@ -1734,7 +1678,7 @@
                 } else {
                     // qualified value must be converted to jcr value
                     QValue qV = QValue.create(value, propertyType);
-                    Value jcrValue = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                    Value jcrValue = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                     ValuesProperty vp = new ValuesProperty(jcrValue);
                     setProperties.add(vp);
                 }
@@ -1759,7 +1703,7 @@
                     Value[] jcrValues = new Value[values.length];
                     for (int i = 0; i < values.length; i++) {
                         QValue qV = QValue.create(values[i], propertyType);
-                        jcrValues[i] = ValueFormat.getJCRValue(qV, getNamespaceResolver(), valueFactory);
+                        jcrValues[i] = ValueFormat.getJCRValue(qV, nsResolver, valueFactory);
                     }
                     setProperties.add(new ValuesProperty(jcrValues));
                 }
@@ -1837,7 +1781,7 @@
                 } else {
                     String[] ntNames = new String[mixinNodeTypeIds.length];
                     for (int i = 0; i < mixinNodeTypeIds.length; i++) {
-                        ntNames[i] = NameFormat.format(mixinNodeTypeIds[i], getNamespaceResolver());
+                        ntNames[i] = NameFormat.format(mixinNodeTypeIds[i], nsResolver);
                     }
                     setProperties = new DavPropertySet();
                     setProperties.add(new NodeTypeProperty(ItemResourceConstants.JCR_MIXINNODETYPES, ntNames, false));
@@ -1866,6 +1810,100 @@
             MoveMethod method = new MoveMethod(uri, destUri, true);
 
             methods.add(method);
+        }
+    }
+
+    /**
+     * <code>SubscriptionManager</code>...
+     */
+    private class SubscriptionMgrImpl implements SubscriptionManager {
+
+        private SessionInfo sessionInfo;
+
+        private final Map subscriptions = new HashMap();
+        private final Object subscriptionsLock = new Object();
+        private Map currentSubscriptions;
+
+        private Thread t;
+
+        public void setSessionInfo(SessionInfo sessionInfo) {
+            this.sessionInfo = sessionInfo;
+        }
+
+        public boolean subscriptionExists(EventListener listener) {
+            return getSubscriptions().containsKey(listener);
+        }
+
+        public String getSubscriptionId(EventListener listener) {
+            if (getSubscriptions().containsKey(listener)) {
+                return ((String[]) getSubscriptions().get(listener))[1];
+            } else {
+                return null;
+            }
+        }
+
+        public void addSubscription(String uri, String subscriptionId, EventListener listener) {
+            synchronized (subscriptionsLock) {
+                boolean doStart = subscriptions.isEmpty();
+                subscriptions.put(listener, new String[] {uri,subscriptionId});
+                currentSubscriptions = null;
+                if (doStart) {
+                    startPolling();
+                }
+            }
+        }
+
+        public synchronized void removeSubscription(EventListener listener) {
+            synchronized (subscriptionsLock) {
+                subscriptions.remove(listener);
+                currentSubscriptions = null;
+                if (subscriptions.isEmpty()) {
+                    stopPolling();
+                }
+            }
+        }
+
+        private Map getSubscriptions() {
+            synchronized (subscriptionsLock) {
+                if (currentSubscriptions == null) {
+                    currentSubscriptions = Collections.unmodifiableMap(new HashMap(subscriptions));
+                }
+                return currentSubscriptions;
+            }
+        }
+
+        private void startPolling() {
+            Runnable r = new Runnable() {
+                public void run() {
+                    while (t == Thread.currentThread()) {
+                        try {
+                            // sleep
+                            Thread.sleep(POLL_INTERVAL);
+                            // poll
+                            Iterator lstnIterator = getSubscriptions().keySet().iterator();
+                            while (lstnIterator.hasNext()) {
+                                EventListener listener = (EventListener) lstnIterator.next();
+                                String[] value = (String[]) getSubscriptions().get(listener);
+                                String uri = value[0];
+                                String subscriptionId = value[1];
+                                EventIterator eventIterator = poll(uri, subscriptionId, sessionInfo);
+                                listener.onEvent(eventIterator);
+                            }
+                        } catch (InterruptedException e) {
+                            log.debug("Polling thread interrupted: " + e.getMessage());
+                            return;
+                        } catch (RepositoryException e) {
+                            log.warn("Polling failed: ", e.getMessage());
+                        }
+                    }
+                }
+            };
+            t = new Thread(r);
+            t.start();
+        }
+
+        private void stopPolling() {
+            t.interrupt();
         }
     }
 }

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java?view=diff&rev=451313&r1=451312&r2=451313
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java Fri Sep 29 07:44:39 2006
@@ -20,8 +20,7 @@
 import org.slf4j.Logger;
 
 import org.apache.jackrabbit.spi.SessionInfo;
-import javax.jcr.Credentials;
-import javax.jcr.SimpleCredentials;
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -32,50 +31,61 @@
 
     private static Logger log = LoggerFactory.getLogger(SessionInfoImpl.class);
 
-    private final Credentials credentials;
+    private final CredentialsWrapper credentials;
     private final String workspaceName;
-    private String batchId;
+    private final SubscriptionManager subscrMgr;
 
     private final Set lockTokens = new HashSet();
 
-    SessionInfoImpl(Credentials creds, String workspaceName) {
+    SessionInfoImpl(CredentialsWrapper creds, String workspaceName, SubscriptionManager subscrMgr) {
         this.credentials = creds;
         this.workspaceName = workspaceName;
+        this.subscrMgr = subscrMgr;
+        subscrMgr.setSessionInfo(this);
     }
 
+    //--------------------------------------------------------< SessionInfo >---
+    /**
+     * @inheritDoc
+     */
     public String getUserID() {
-        if (credentials instanceof SimpleCredentials) {
-            return ((SimpleCredentials) credentials).getUserID();
-        } else {
-            return null;
-        }
+        return credentials.getUserId();
     }
 
+    /**
+     * @inheritDoc
+     */
     public String getWorkspaceName() {
         return workspaceName;
     }
 
+    /**
+     * @inheritDoc
+     */
     public String[] getLockTokens() {
         return (String[]) lockTokens.toArray(new String[lockTokens.size()]);
     }
 
+    /**
+     * @inheritDoc
+     */
     public void addLockToken(String lockToken) {
         lockTokens.add(lockToken);
     }
 
+    /**
+     * @inheritDoc
+     */
     public void removeLockToken(String lockToken) {
         lockTokens.remove(lockToken);
     }
 
-    public String getBatchId() {
-        return batchId;
-    }
-
-    public void setBatchId(String id) {
-        batchId = id;
+    //--------------------------------------------------------------------------
+    CredentialsWrapper getCredentials() {
+        return credentials;
     }
 
-    Credentials getCredentials() {
-        return credentials;
+    SubscriptionManager getSubscriptionManager() {
+        return subscrMgr;
     }
 }

Added: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java?view=auto&rev=451313
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java (added)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java Fri Sep 29 07:44:39 2006
@@ -0,0 +1,36 @@
+/*
+ * 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.spi2dav;
+
+import org.apache.jackrabbit.spi.SessionInfo;
+import org.apache.jackrabbit.spi.EventListener;
+
+/**
+ * <code>SubscriptionManager</code>...
+ */
+interface SubscriptionManager {
+
+    public void setSessionInfo(SessionInfo sessionInfo);
+
+        public boolean subscriptionExists(EventListener listener);
+
+        public String getSubscriptionId(EventListener listener);
+
+        public void addSubscription(String uri, String subscriptionId, EventListener listener);
+
+        public void removeSubscription(EventListener listener);
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SubscriptionManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/URIResolverImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/URIResolverImpl.java?view=diff&rev=451313&r1=451312&r2=451313
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/URIResolverImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/URIResolverImpl.java Fri Sep 29 07:44:39 2006
@@ -39,14 +39,11 @@
 import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
 import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 import org.apache.jackrabbit.webdav.client.methods.ReportMethod;
-import org.apache.jackrabbit.webdav.client.methods.DavMethod;
 import org.apache.jackrabbit.webdav.MultiStatusResponse;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.MultiStatus;
 import org.apache.jackrabbit.webdav.DavServletResponse;
 import org.apache.jackrabbit.webdav.DavConstants;
-import org.apache.jackrabbit.webdav.transaction.TransactionConstants;
-import org.apache.jackrabbit.webdav.header.CodedUrlHeader;
 import org.apache.jackrabbit.webdav.xml.DomUtil;
 import org.apache.jackrabbit.webdav.version.report.ReportInfo;
 import org.apache.jackrabbit.BaseException;
@@ -83,16 +80,6 @@
         this.domFactory = domFactory;
     }
 
-    private static void initMethod(DavMethod method, SessionInfo sessionInfo) {
-        if (sessionInfo instanceof SessionInfoImpl) {
-            String txId = ((SessionInfoImpl) sessionInfo).getBatchId();
-            if (txId != null) {
-                CodedUrlHeader ch = new CodedUrlHeader(TransactionConstants.HEADER_TRANSACTIONID, txId);
-                method.setRequestHeader(ch.getHeaderName(), ch.getHeaderValue());
-            }
-        }
-    }
-
     private IdURICache getCache(String workspaceName) {
         if (idURICaches.containsKey(workspaceName)) {
             return (IdURICache) idURICaches.get(workspaceName);
@@ -144,7 +131,6 @@
                     try {
                         String wspUri = getWorkspaceUri(workspaceName);
                         ReportMethod rm = new ReportMethod(wspUri, rInfo);
-                        initMethod(rm, sessionInfo);
 
                         service.getClient(sessionInfo).executeMethod(rm);
 
@@ -307,7 +293,6 @@
             DavMethodBase method = null;
             try {
                 method = new PropFindMethod(uri, nameSet, DavConstants.DEPTH_0);
-                initMethod(method, sessionInfo);
 
                 service.getClient(sessionInfo).executeMethod(method);
                 MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();