jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r331281 [1/3] - in /incubator/jackrabbit/trunk/contrib/jcr-server: ./ client/ 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/sr...
Date Mon, 07 Nov 2005 15:28:23 GMT
Author: angela
Date: Mon Nov  7 07:26:33 2005
New Revision: 331281

URL: http://svn.apache.org/viewcvs?rev=331281&view=rev
Log:
JCR-249, JCR-253

Added:
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOListener.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOManager.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOUtil.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ImportContextImpl.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/XmlHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ZipHandler.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/io/InputContextImpl.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/io/OutputContext.java   (with props)
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/io/OutputContextImpl.java   (with props)
Removed:
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractContext.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractImportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AddMixinCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AddNodeCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/CheckinCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportCollectionChain.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportResourceChain.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/FileExportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/FileImportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ImportCollectionChain.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ImportResourceChain.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/PrimaryItemExportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/SaveCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/SetContentTypeCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/XMLExportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/XMLImportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ZIPImportCommand.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/util/
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/simple/NodeResource.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/webapp/WEB-INF/catalog.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/webapp/WEB-INF/simple_catalog.xml
Modified:
    incubator/jackrabbit/trunk/contrib/jcr-server/README.txt
    incubator/jackrabbit/trunk/contrib/jcr-server/client/project.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContext.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ImportContext.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/package.html
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractItemResource.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/AbstractResource.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/DefaultItemResource.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/RootCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/RootItemCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/search/SearchResourceImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/transaction/TxLockManagerImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/version/VersionHistoryItemCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/version/VersionItemCollection.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/simple/DavSessionImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/simple/DavSessionProviderImpl.java
    incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java
    incubator/jackrabbit/trunk/contrib/jcr-server/todo.txt
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/project.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/java/org/apache/jackrabbit/j2ee/JCRWebdavServerServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/java/org/apache/jackrabbit/j2ee/LoggingServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/java/org/apache/jackrabbit/j2ee/RepositoryAccessServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/java/org/apache/jackrabbit/j2ee/RepositoryStartupServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/java/org/apache/jackrabbit/j2ee/SimpleWebdavServlet.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/webapp/WEB-INF/config.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/webapp/src/webapp/WEB-INF/web.xml
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavConstants.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavResource.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavSession.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/io/InputContext.java
    incubator/jackrabbit/trunk/contrib/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/search/SearchConstants.java

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/README.txt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/README.txt?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/README.txt (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/README.txt Mon Nov  7 07:26:33 2005
@@ -9,17 +9,15 @@
 into your maven repository. If this is not the case, go back to the root
 project and launch
 
-  api:      maven jar:install
   commons:  maven jar:install
-  core:     maven jar:install
 
-which will build and copy Jackrabbit into ~/.maven/repository/jackrabbit/jars
+which will build and copy Jackrabbit into ~/.maven/repository/org.apache.jackrabbit/jars
 
 Also go to the contrib project jcr-rmi and launch
 
   maven jar:install
 
-which will build and copy jcr-rmi to ~/.maven/repository/jcr-rmi/jars
+which will build and copy jcr-rmi to ~/.maven/repository/org.apache.jackrabbit/jars
 
 After building all dependencies one can build the actual server webapp
 

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/client/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/client/project.xml?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/client/project.xml (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/client/project.xml Mon Nov  7 07:26:33 2005
@@ -22,7 +22,6 @@
     <extend>${basedir}/../project.xml</extend>
     <id>jcr-client</id>
     <groupId>org.apache.jackrabbit</groupId>
-    <type>jar</type>
     <name>JCRWebdavServer Client Library</name>
 
     <!-- ====================================================================== -->

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml Mon Nov  7 07:26:33 2005
@@ -64,19 +64,9 @@
             <version>2.3</version>
         </dependency>
         <dependency>
-            <groupId>commons-chain</groupId>
-            <artifactId>commons-chain</artifactId>
-            <version>1.0</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-digester</groupId>
-            <artifactId>commons-digester</artifactId>
-            <version>1.6</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-            <version>1.7.0</version>
+            <groupId>xerces</groupId>
+            <artifactId>xercesImpl</artifactId>
+            <version>2.6.2</version>
         </dependency>
     </dependencies>
 

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java Mon Nov  7 07:26:33 2005
@@ -16,7 +16,11 @@
 package org.apache.jackrabbit.server;
 
 import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.server.io.IOUtil;
+import org.apache.jackrabbit.webdav.io.InputContextImpl;
+import org.apache.jackrabbit.webdav.io.OutputContextImpl;
 import org.apache.jackrabbit.webdav.io.InputContext;
+import org.apache.jackrabbit.webdav.io.OutputContext;
 import org.apache.jackrabbit.webdav.lock.ActiveLock;
 import org.apache.jackrabbit.webdav.lock.LockInfo;
 import org.apache.jackrabbit.webdav.observation.EventDiscovery;
@@ -51,8 +55,8 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -356,69 +360,21 @@
             return;
         }
 
+        long modSince = request.getDateHeader("If-Modified-Since");
+        if (modSince > IOUtil.UNDEFINED_TIME) {
+            // test if resource has been modified
         long modTime = resource.getModificationTime();
-        if (modTime != DavResource.UNDEFINED_MODIFICATIONTIME && modTime <= request.getDateHeader("If-Modified-Since")) {
+            if (modTime != IOUtil.UNDEFINED_TIME && modTime <= modSince) {
             // resource has not been modified since the time indicated in the
             // 'If-Modified-Since' header.
             response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
             return;
         }
-
-        DavProperty lastMod = resource.getProperty(DavPropertyName.GETLASTMODIFIED);
-        if (lastMod != null) {
-            response.setHeader(HEADER_LAST_MODIFIED, String.valueOf(lastMod.getValue()));
-        }
-
-        DavProperty etag = resource.getProperty(DavPropertyName.GETETAG);
-        if (etag != null) {
-            response.setHeader(HEADER_ETAG, String.valueOf(etag.getValue()));
-        }
-
-        DavProperty contentType = resource.getProperty(DavPropertyName.GETCONTENTTYPE);
-        if (contentType != null) {
-            response.setHeader(HEADER_CONTENT_TYPE, String.valueOf(contentType.getValue()));
-        }
-
-        DavProperty contentLength = resource.getProperty(DavPropertyName.GETCONTENTLENGTH);
-        if (contentLength != null) {
-            try {
-                int length = Integer.parseInt(contentLength.getValue() + "");
-                if (length > 0) {
-                    response.setIntHeader(HEADER_CONTENT_LENGTH, length);
-                }
-            } catch (NumberFormatException e) {
-                log.error("Could not build content length from property value '" + contentLength.getValue() + "'");
-            }
         }
 
-        DavProperty contentLanguage = resource.getProperty(DavPropertyName.GETCONTENTLANGUAGE);
-        if (contentLanguage != null) {
-            response.setHeader(HEADER_CONTENT_LANGUAGE, contentLanguage.getValue().toString());
-        }
-
-        // spool content in case of 'GET' request
-        InputStream in = resource.getStream();
-        try {
-            if (sendContent) {
-                if (in != null) {
-                    OutputStream out = response.getOutputStream();
-                    byte[] buffer = new byte[8192];
-                    int read;
-                    while ((read = in.read(buffer)) >= 0) {
-                        out.write(buffer, 0, read);
-                    }
-                }
-            }
-        } finally {
-            // also close stream if not sending content
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
+        // spool resource properties and ev. resource content.
+        OutputStream out = (sendContent) ? response.getOutputStream() : null;
+        resource.spool(getOutputContext(response, out));
         response.flushBuffer();
     }
 
@@ -522,7 +478,7 @@
             status = DavServletResponse.SC_CREATED;
         }
 
-        parentResource.addMember(resource, getInputContext(request));
+        parentResource.addMember(resource, getInputContext(request, request.getInputStream()));
         response.setStatus(status);
     }
 
@@ -550,29 +506,14 @@
         }
 
         if (request.getContentLength() > 0 || request.getHeader("Transfer-Encoding") != null) {
-            parentResource.addMember(resource, getInputContext(request));
+            parentResource.addMember(resource, getInputContext(request, request.getInputStream()));
         } else {
-            parentResource.addMember(resource);
+            parentResource.addMember(resource, getInputContext(request, null));
         }
         response.setStatus(DavServletResponse.SC_CREATED);
     }
 
     /**
-     * Build an InputContext for the given request
-     *
-     * @param request
-     * @return
-     * @throws IOException
-     */
-    protected InputContext getInputContext(WebdavRequest request) throws IOException {
-        InputContext cxt = new InputContext();
-        cxt.setContentType(request.getHeader(DavConstants.HEADER_CONTENT_TYPE));
-        cxt.setContentLanguage(request.getHeader(DavConstants.HEADER_CONTENT_LANGUAGE));
-        cxt.setInputStream(request.getInputStream());
-        return cxt;
-    }
-
-    /**
      * The DELETE method
      *
      * @param request
@@ -1075,5 +1016,32 @@
             response.sendError(DavServletResponse.SC_BAD_REQUEST);
             return;
         }
+    }
+
+    /**
+     * Return a new <code>InputContext</code> used for adding resource members
+     *
+     * @param request
+     * @param in
+     * @return
+     * @see #spoolResource(WebdavRequest, WebdavResponse, DavResource, boolean)
+     */
+    protected InputContext getInputContext(DavServletRequest request, InputStream in) {
+        return new InputContextImpl(request, in);
+    }
+
+    /**
+     * Return a new <code>OutputContext</code> used for spooling resource properties and
+     * the resource content
+     *
+     * @param response
+     * @param out
+     * @return
+     * @see #doPut(WebdavRequest, WebdavResponse, DavResource)
+     * @see #doPost(WebdavRequest, WebdavResponse, DavResource)
+     * @see #doMkCol(WebdavRequest, WebdavResponse, DavResource)
+     */
+    protected OutputContext getOutputContext(DavServletResponse response, OutputStream out) {
+        return new OutputContextImpl(response, out);
     }
 }

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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.server;
+
+import org.apache.jackrabbit.util.Base64;
+import org.apache.jackrabbit.webdav.DavConstants;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * This Class implements a credentials provider that extracts the credentials
+ * from the 'WWW-Authenticate' header and only supports 'Basic' authentication.
+ */
+public class BasicCredentialsProvider implements CredentialsProvider {
+
+    private final String defaultHeaderValue;
+
+    /**
+     * Constructs a new BasicCredentialsProvider with the given default
+     * value {@see #getCredentials} for details.
+     *
+     * @param defaultHeaderValue
+     */
+    public BasicCredentialsProvider(String defaultHeaderValue) {
+        this.defaultHeaderValue = defaultHeaderValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Build a {@link Credentials} object for the given authorization header.
+     * The creds may be used to login to the repository. If the specified header
+     * string is <code>null</code> or not of the required format the behaviour
+     * depends on the {@link #defaultHeaderValue} field:<br>
+     * <ul>
+     * <li> if this field is <code>null</code>, a LoginException is thrown.
+     *      This is suiteable for clients (eg. webdav clients) for with
+     *      sending a proper authorization header is not possible, if the
+     *      server never send a 401.
+     * <li> if this an empty string, null-credentials are returned, thus
+     *      forcing an null login on the repository
+     * <li> if this field has a 'user:password' value, the respective
+     *      simple credentials are generated.
+     * </ul>
+     *
+     * @param request the servlet request
+     * @return credentials or <code>null</code>.
+     * @throws ServletException If an IOException occured while decoding the
+     *         Authorization header.
+     * @throws LoginException if no suitable auth header and missing-auth-mapping
+     *         is not present
+     */
+    public Credentials getCredentials(HttpServletRequest request)
+            throws LoginException, ServletException {
+        try {
+            String authHeader = request.getHeader(DavConstants.HEADER_AUTHORIZATION);
+            if (authHeader != null) {
+                String[] authStr = authHeader.split(" ");
+                if (authStr.length >= 2 && authStr[0].equalsIgnoreCase(HttpServletRequest.BASIC_AUTH)) {
+                    ByteArrayOutputStream out = new ByteArrayOutputStream();
+                    Base64.decode(authStr[1].toCharArray(), out);
+                    String decAuthStr = out.toString("ISO-8859-1");
+                    int pos = decAuthStr.indexOf(':');
+                    String userid = decAuthStr.substring(0, pos);
+                    String passwd = decAuthStr.substring(pos + 1);
+                    return new SimpleCredentials(userid, passwd.toCharArray());
+                }
+                throw new ServletException("Unable to decode authorization.");
+            } else {
+                // check special handling
+                if (defaultHeaderValue == null) {
+                    throw new LoginException();
+                } else if (defaultHeaderValue.equals("")) {
+                    return null;
+                } else {
+                    int pos = defaultHeaderValue.indexOf(':');
+                    if (pos<0) {
+                        return new SimpleCredentials(defaultHeaderValue, null);
+                    } else {
+                        return new SimpleCredentials(
+                                defaultHeaderValue.substring(0, pos),
+                                defaultHeaderValue.substring(pos+1).toCharArray()
+                        );
+                    }
+                }
+            }
+        } catch (IOException e) {
+            throw new ServletException("Unable to decode authorization: " + e.toString());
+        }
+    }
+
+}

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/BasicCredentialsProvider.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java Mon Nov  7 07:26:33 2005
@@ -41,4 +41,11 @@
     public Session getSession(HttpServletRequest request, Repository rep, String workspace)
             throws LoginException, ServletException, RepositoryException;
 
+    /**
+     * Informs this provider that the session aquired by a previous
+     * {@link #getSession} call is no longer needed.
+     *
+     * @param session
+     */
+    public void releaseSession(Session session);
 }

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java Mon Nov  7 07:26:33 2005
@@ -51,4 +51,11 @@
         Credentials creds = cp.getCredentials(request);
         return repository.login(creds, workspace);
     }
+
+    /**
+     * {@inheritDoc }
+     */
+    public void releaseSession(Session session) {
+        session.logout();
+    }
 }

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,67 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+
+import javax.jcr.Item;
+
+/**
+ * <code>AbstractExportContext</code> covers methods common to most ExportContext
+ * implementations.
+ */
+public abstract class AbstractExportContext implements ExportContext {
+
+    private static Logger log = Logger.getLogger(AbstractExportContext.class);
+
+    private final IOListener ioListener;
+    private final Item exportRoot;
+    private final boolean hasStream;
+
+    protected boolean completed;
+
+    public AbstractExportContext(Item exportRoot, boolean hasStream, IOListener ioListener) {
+        this.exportRoot = exportRoot;
+        this.hasStream = hasStream;
+        this.ioListener = (ioListener != null) ? ioListener : new DefaultIOListener(log);
+    }
+
+    public IOListener getIOListener() {
+        return ioListener;
+    }
+
+    public Item getExportRoot() {
+        return exportRoot;
+    }
+
+    public boolean hasStream() {
+        return hasStream;
+    }
+
+    public void informCompleted(boolean success) {
+        completed = true;
+    }
+
+    public boolean isCompleted() {
+        return completed;
+    }
+
+    protected void checkCompleted() {
+        if (completed) {
+            throw new IllegalStateException("ExportContext has already been finalized.");
+        }
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractExportContext.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,477 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.webdav.DavResource;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Property;
+import javax.jcr.Item;
+import javax.jcr.NodeIterator;
+import java.util.Calendar;
+import java.util.Date;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <code>DefaultHandler</code> implements a simple IOHandler that creates 'file'
+ * and 'folder' nodes. This handler will create the following nodes:
+ * <ul>
+ * <li>New <b>Collection</b>: creates a new node with the {@link #getCollectionNodeType()
+ * collection nodetype}. The name of the node corresponds to the systemId
+ * present on the import context.</li>
+ *
+ * <li>New <b>Non-Collection</b>: first creates a new node with the {@link #getNodeType()
+ * non-collection nodetype}. The name of the node corresponds to the systemId
+ * present on the import context. Below it creates a node with name
+ * {@link JcrConstants#JCR_CONTENT jcr:content} and the nodetype specified
+ * by {@link #getContentNodeType()}.</li>
+ * </ul>
+ * <p/>
+ * Import of the content:<br>
+ * The content is imported to the {@link JcrConstants#JCR_DATA} property of the
+ * content node. By default this handler will fail on a attempt to create/replace
+ * a collection if {@link ImportContext#hasStream()} is <code>true</code>.
+ * Subclasses therefore should provide their own {@link #importData(ImportContext, boolean, Node)
+ * importData} method, that handles the data according their needs.
+ */
+public class DefaultHandler implements IOHandler {
+
+    private static Logger log = Logger.getLogger(DefaultHandler.class);
+
+    private String collectionNodetype = JcrConstants.NT_FOLDER;
+    private String defaultNodetype = JcrConstants.NT_FILE;
+    private String contentNodetype = JcrConstants.NT_RESOURCE;
+
+    private IOManager ioManager;
+
+    /**
+     * Creates a new <code>DefaultHandler</code> with default nodetype definitions:<br>
+     * <ul>
+     * <li>Nodetype for Collection: {@link JcrConstants#NT_FOLDER nt:folder}</li>
+     * <li>Nodetype for Non-Collection: {@link JcrConstants#NT_FILE nt:file}</li>
+     * <li>Nodetype for Non-Collection content: {@link JcrConstants#NT_RESOURCE nt:resource}</li>
+     * </ul>
+     *
+     * @param ioManager
+     */
+    public DefaultHandler(IOManager ioManager) {
+        this.ioManager = ioManager;
+    }
+
+    /**
+     * Creates a new <code>DefaultHandler</code>. Please note that the specified
+     * nodetypes must match the definitions of the defaults.
+     *
+     * @param ioManager
+     * @param collectionNodetype
+     * @param defaultNodetype
+     * @param contentNodetype
+     */
+    public DefaultHandler(IOManager ioManager, String collectionNodetype, String defaultNodetype, String contentNodetype) {
+        this.ioManager = ioManager;
+        
+        this.collectionNodetype = collectionNodetype;
+        this.defaultNodetype = defaultNodetype;
+        this.contentNodetype = contentNodetype;
+    }
+
+    /**
+     * @see IOHandler#getIOManager()
+     */
+    public IOManager getIOManager() {
+        return ioManager;
+    }
+
+    /**
+     * @see IOHandler#getName()
+     */
+    public String getName() {
+        return getClass().getName();
+    }
+
+    /**
+     * @see IOHandler#canImport(ImportContext, boolean)
+     */
+    public boolean canImport(ImportContext context, boolean isCollection) {
+        if (context == null || context.isCompleted()) {
+            return false;
+        }
+        Item contextItem = context.getImportRoot();
+        return contextItem != null && contextItem.isNode() && context.getSystemId() != null;
+    }
+
+    /**
+     * @see IOHandler#canImport(ImportContext, DavResource)
+     */
+    public boolean canImport(ImportContext context, DavResource resource) {
+        if (resource == null) {
+            return false;
+        }
+        return canImport(context, resource.isCollection());
+    }
+
+    /**
+     * @see IOHandler#importContent(ImportContext, boolean)
+     */
+    public boolean importContent(ImportContext context, boolean isCollection) throws IOException {
+        if (!canImport(context, isCollection)) {
+            throw new IOException(getName() + ": Cannot import " + context.getSystemId());
+        }
+
+        boolean success = false;
+        try {
+            Node contentNode = getContentNode(context, isCollection);
+            success = importData(context, isCollection, contentNode);
+            if (success) {
+                success = importProperties(context, isCollection, contentNode);
+            }
+        } catch (RepositoryException e) {
+            success = false;
+            throw new IOException(e.getMessage());
+        } finally {
+            // revert any changes made in case the import failed.
+            if (!success) {
+                try {
+                    context.getImportRoot().refresh(false);
+                } catch (RepositoryException e) {
+                    throw new IOException(e.getMessage());
+                }
+            }
+        }
+        return success;
+    }
+
+    /**
+     * @see IOHandler#importContent(ImportContext, DavResource)
+     */
+    public boolean importContent(ImportContext context, DavResource resource) throws IOException {
+        if (!canImport(context, resource)) {
+            throw new IOException(getName() + ": Cannot import " + context.getSystemId());
+        }
+        return importContent(context, resource.isCollection());
+    }
+
+    /**
+     * Imports the data present on the import context to the specified content
+     * node.
+     *
+     * @param context
+     * @param isCollection
+     * @param contentNode
+     * @return
+     * @throws IOException
+     */
+    protected boolean importData(ImportContext context, boolean isCollection, Node contentNode) throws IOException, RepositoryException {
+        InputStream in = context.getInputStream();
+        if (in != null) {
+            try {
+                // NOTE: with the default folder-nodetype (nt:folder) no inputstream
+                // is allowed. setting the property will therefore fail.
+                contentNode.setProperty(JcrConstants.JCR_DATA, in);
+            } finally {
+                in.close();
+            }
+        }
+        // success if no data to import.
+        return true;
+    }
+
+    /**
+     * Imports the properties present on the specified context to the content
+     * node.
+     *
+     * @param context
+     * @param isCollection
+     * @param contentNode
+     * @return
+     */
+    protected boolean importProperties(ImportContext context, boolean isCollection, Node contentNode) {
+        try {
+            // if context-mimetype is null -> remove the property
+            contentNode.setProperty(JcrConstants.JCR_MIMETYPE, context.getMimeType());
+        } catch (RepositoryException e) {
+            // ignore: property may not be present on the node
+        }
+        try {
+            // if context-encoding is null -> remove the property
+            contentNode.setProperty(JcrConstants.JCR_ENCODING, context.getEncoding());
+        } catch (RepositoryException e) {
+            // ignore: property may not be present on the node
+        }
+        try {
+            Calendar lastMod = Calendar.getInstance();
+            if (context.getModificationTime() != IOUtil.UNDEFINED_TIME) {
+                lastMod.setTimeInMillis(context.getModificationTime());
+            } else {
+                lastMod.setTime(new Date());
+            }
+            contentNode.setProperty(JcrConstants.JCR_LASTMODIFIED, lastMod);
+        } catch (RepositoryException e) {
+            // ignore: property may not be present on the node.
+            // deliberately not rethrowing as IOException.
+        }
+        return true;
+    }
+
+    /**
+     * Retrieves/creates the node that will be used to import properties and
+     * data. In case of a non-collection this includes and additional content node
+     * to be created beside the 'file' node.<br>
+     * Please note: If the jcr:content node already exists and contains child
+     * nodes, those will be removed in order to make sure, that the import
+     * really replaces the existing content of the file-node.
+     *
+     * @param context
+     * @param isCollection
+     * @return
+     * @throws RepositoryException
+     */
+    protected Node getContentNode(ImportContext context, boolean isCollection) throws RepositoryException {
+        Node parentNode = (Node)context.getImportRoot();
+        String name = context.getSystemId();
+        if (parentNode.hasNode(name)) {
+            parentNode = parentNode.getNode(name);
+        } else {
+            String ntName = (isCollection) ? getCollectionNodeType() : getNodeType();
+            parentNode = parentNode.addNode(name, ntName);
+        }
+        Node contentNode;
+        if (isCollection) {
+            contentNode = parentNode;
+        } else {
+            if (parentNode.hasNode(JcrConstants.JCR_CONTENT)) {
+                contentNode = parentNode.getNode(JcrConstants.JCR_CONTENT);
+                // remove all entries in the jcr:content since replacing content
+                // includes properties (DefaultHandler) and nodes (e.g. ZipHandler)
+                if (contentNode.hasNodes()) {
+                    NodeIterator it = contentNode.getNodes();
+                    while (it.hasNext()) {
+                        it.nextNode().remove();
+                    }
+                }
+            } else {
+                contentNode = parentNode.addNode(JcrConstants.JCR_CONTENT, getContentNodeType());
+            }
+        }
+        return contentNode;
+    }
+
+    /**
+     * Returns true if the export root is a node and if it contains a child node
+     * with name {@link JcrConstants#JCR_CONTENT jcr:content} in case this
+     * export is not intended for a collection.
+     *
+     * @return true if the export root is a node. If the specified boolean paramter
+     * is false (not a collection export) the given export root must contain a
+     * child node with name {@link JcrConstants#JCR_CONTENT jcr:content}.
+     *
+     * @see IOHandler#canExport(ExportContext, boolean)
+     */
+    public boolean canExport(ExportContext context, boolean isCollection) {
+        if (context == null || context.isCompleted()) {
+            return false;
+        }
+        Item exportRoot = context.getExportRoot();
+        boolean success = exportRoot != null && exportRoot.isNode();
+        if (success && !isCollection) {
+            try {
+                Node n = ((Node)exportRoot);
+                success = n.hasNode(JcrConstants.JCR_CONTENT);
+            } catch (RepositoryException e) {
+                // should never occur.
+                success = false;
+            }
+        }
+        return success;
+    }
+
+    /**
+     * @see IOHandler#canExport(ExportContext, DavResource)
+     */
+    public boolean canExport(ExportContext context, DavResource resource) {
+        if (resource == null) {
+            return false;
+        }
+        return canExport(context, resource.isCollection());
+    }
+
+    /**
+     * Retrieves the content node that will be used for exporting properties and
+     * data and calls the corresponding methods.
+     *
+     * @param context
+     * @param isCollection
+     * @see #exportProperties(ExportContext, boolean, Node)
+     * @see #exportData(ExportContext, boolean, Node)
+     */
+    public boolean exportContent(ExportContext context, boolean isCollection) throws IOException {
+        if (!canExport(context, isCollection)) {
+            throw new IOException(getName() + ": Cannot export " + context.getExportRoot());
+        }
+        try {
+            Node contentNode = getContentNode(context, isCollection);
+            exportProperties(context, isCollection, contentNode);
+            if (context.hasStream()) {
+                exportData(context, isCollection, contentNode);
+            } // else: missing stream. ignore.
+            return true;
+        } catch (RepositoryException e) {
+            // should never occur, since the proper structure of the content
+            // node must be asserted in the 'canExport' call.
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    /**
+     * Same as (@link #exportContent(ExportContext, boolean)} where the boolean
+     * values is defined by {@link DavResource#isCollection()}.
+     *
+     * @see IOHandler#exportContent(ExportContext, DavResource)
+     */
+    public boolean exportContent(ExportContext context, DavResource resource) throws IOException {
+        if (!canExport(context, resource)) {
+            throw new IOException(getName() + ": Cannot export " + context.getExportRoot());
+        }
+        return exportContent(context, resource.isCollection());
+    }
+
+    /**
+     * Checks if the given content node contains a jcr:data property
+     * and spools its value to the output stream fo the export context.<br>
+     * Please note, that subclasses that define a different structure of the
+     * content node should create their own
+     * {@link #exportData(ExportContext, boolean, Node) exportData} method.
+     *
+     * @param context
+     * @param isCollection
+     * @param contentNode
+     * @throws IOException
+     */
+    protected void exportData(ExportContext context, boolean isCollection, Node contentNode) throws IOException, RepositoryException {
+        if (contentNode.hasProperty(JcrConstants.JCR_DATA)) {
+            Property p = contentNode.getProperty(JcrConstants.JCR_DATA);
+            IOUtil.spool(p.getStream(), context.getOutputStream());
+        } // else: stream undefined -> contentlength was not set
+    }
+
+    /**
+     * Retrieves mimetype, encoding and modification time from the content node.
+     * The content length is determined by the length of the jcr:data property
+     * if it is present. The creation time however is retrieved from the parent
+     * node (in case of isCollection == false only).
+     *
+     * @param context
+     * @param isCollection
+     * @param contentNode
+     */
+    protected void exportProperties(ExportContext context, boolean isCollection, Node contentNode) throws IOException {
+        try {
+            // only non-collections: 'jcr:created' is present on the parent 'fileNode' only
+            if (!isCollection && contentNode.getDepth() > 0 && contentNode.getParent().hasProperty(JcrConstants.JCR_CREATED)) {
+                context.setCreationTime(contentNode.getParent().getProperty(JcrConstants.JCR_CREATED).getValue().getLong());
+            }
+
+            long length = IOUtil.UNDEFINED_LENGTH;
+            if (contentNode.hasProperty(JcrConstants.JCR_DATA)) {
+                Property p = contentNode.getProperty(JcrConstants.JCR_DATA);
+                length = p.getLength();
+                context.setContentLength(length);
+            }
+
+            String mimeType = null;
+            String encoding = "UTF-8"; // assume default encoding
+            if (contentNode.hasProperty(JcrConstants.JCR_MIMETYPE)) {
+                mimeType = contentNode.getProperty(JcrConstants.JCR_MIMETYPE).getString();
+            }
+            if (contentNode.hasProperty(JcrConstants.JCR_ENCODING)) {
+                encoding = contentNode.getProperty(JcrConstants.JCR_ENCODING).getString();
+                // ignore "" encodings (although this is avoided during import)
+                if ("".equals(encoding)) {
+                    encoding = null;
+                }
+            }
+            context.setContentType(mimeType, encoding);
+
+            long modTime = IOUtil.UNDEFINED_TIME;
+            if (contentNode.hasProperty(JcrConstants.JCR_LASTMODIFIED)) {
+                modTime = contentNode.getProperty(JcrConstants.JCR_LASTMODIFIED).getLong();
+                context.setModificationTime(modTime);
+            } else {
+                context.setModificationTime(System.currentTimeMillis());
+            }
+
+            if (length > IOUtil.UNDEFINED_LENGTH && modTime > IOUtil.UNDEFINED_TIME) {
+                String etag = "\"" + length + "-" + modTime + "\"";
+                context.setETag(etag);
+            }
+        } catch (RepositoryException e) {
+            // should never occur
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    /**
+     * Retrieves the content node that contains the data to be exported. In case
+     * isCollection is true, this corresponds to the export root. Otherwise there
+     * must be a child node with name {@link JcrConstants#JCR_CONTENT jcr:content}.
+     *
+     * @param context
+     * @param isCollection
+     * @return content node used for the export
+     * @throws RepositoryException
+     */
+    protected Node getContentNode(ExportContext context, boolean isCollection) throws RepositoryException {
+        Node contentNode = (Node)context.getExportRoot();
+        // 'file' nodes must have an jcr:content child node (see canExport)
+        if (!isCollection) {
+            contentNode = contentNode.getNode(JcrConstants.JCR_CONTENT);
+        }
+        return contentNode;
+    }
+
+    /**
+     * Name of the nodetype to be used to create a new collection node (folder)
+     *
+     * @return nodetype name
+     */
+    protected String getCollectionNodeType() {
+        return collectionNodetype;
+    }
+
+    /**
+     * Name of the nodetype to be used to create a new non-collection node (file)
+     *
+     * @return nodetype name
+     */
+    protected String getNodeType() {
+        return defaultNodetype;
+    }
+
+    /**
+     * Name of the nodetype to be used to create the content node below
+     * a new non-collection node, whose name is always {@link JcrConstants#JCR_CONTENT
+     * jcr:content}.
+     *
+     * @return nodetype name
+     */
+    protected String getContentNodeType() {
+        return contentNodetype;
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultHandler.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,57 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+
+/**
+ * <code>DefaultIOListener</code> implements an <code>IOListener</code> that
+ * writes debug/error output to the {@link Logger logger} specified in the constructor.
+ */
+public class DefaultIOListener implements IOListener {
+
+    private static Logger log = Logger.getLogger(DefaultIOListener.class);
+
+    private Logger ioLog;
+
+    /**
+     * Creates a new <code>DefaultIOListener</code>
+     */
+    public DefaultIOListener(Logger ioLog) {
+        this.ioLog = (ioLog != null) ? ioLog : log;
+    }
+
+    /**
+     * @see IOListener#onBegin(IOHandler, IOContext)
+     */
+    public void onBegin(IOHandler handler, IOContext ioContext) {
+        ioLog.debug("Starting IOHandler (" + handler.getName() + ")");
+    }
+
+    /**
+     * @see IOListener#onEnd(IOHandler, IOContext, boolean)
+     */
+    public void onEnd(IOHandler handler, IOContext ioContext, boolean success) {
+        ioLog.info("Result for IOHandler (" + handler.getName() + "): " + (success ? "OK" : "Failed"));
+    }
+
+    /**
+     * @see IOListener#onError(IOHandler, IOContext, Exception)
+     */
+    public void onError(IOHandler ioHandler, IOContext ioContext, Exception e) {
+        ioLog.debug("Error: " + e.getMessage());
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOListener.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,146 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.DavResource;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.IOException;
+
+/**
+ * <code>DefaultIOManager</code>...
+ */
+public class DefaultIOManager implements IOManager {
+
+    private static Logger log = Logger.getLogger(DefaultIOManager.class);
+
+    private final List ioHandlers = new ArrayList();
+
+    public DefaultIOManager() {
+        this(true);
+    }
+
+    protected DefaultIOManager(boolean doInit) {
+        if (doInit) {
+           init();
+        }
+    }
+
+    protected void init() {
+        addIOHandler(new ZipHandler(this));
+        addIOHandler(new XmlHandler(this));
+        addIOHandler(new DirListingExportHandler(this));
+        addIOHandler(new DefaultHandler(this));
+    }
+
+    public void addIOHandler(IOHandler ioHandler) {
+        ioHandlers.add(ioHandler);
+    }
+
+    public IOHandler[] getIOHandlers() {
+        return (IOHandler[]) ioHandlers.toArray(new IOHandler[ioHandlers.size()]);
+    }
+
+    public boolean importContent(ImportContext context, boolean isCollection) throws IOException {
+        boolean success = false;
+        if (context != null) {
+            IOListener ioListener = context.getIOListener();
+            if (ioListener == null) {
+                ioListener = new DefaultIOListener(log);
+            }
+
+            Iterator it = ioHandlers.iterator();
+            while (it.hasNext() && !success) {
+                IOHandler ioh = (IOHandler)it.next();
+                if (ioh.canImport(context, isCollection)) {
+                    ioListener.onBegin(ioh, context);
+                    success = ioh.importContent(context, isCollection);
+                    ioListener.onEnd(ioh, context, success);
+                }
+            }
+            context.informCompleted(success);
+        }
+        return success;
+    }
+
+    public boolean importContent(ImportContext context, DavResource resource) throws IOException {
+        boolean success = false;
+        if (context != null && resource != null) {
+            IOListener ioListener = context.getIOListener();
+            if (ioListener == null) {
+                ioListener = new DefaultIOListener(log);
+            }
+            Iterator it = ioHandlers.iterator();
+            while (it.hasNext() && !success) {
+                IOHandler ioh = (IOHandler)it.next();
+                if (ioh.canImport(context, resource)) {
+                    ioListener.onBegin(ioh, context);
+                    success = ioh.importContent(context, resource);
+                    ioListener.onEnd(ioh, context, success);
+                }
+            }
+            context.informCompleted(success);
+        }
+        return success;
+    }
+
+    public boolean exportContent(ExportContext context, boolean isCollection) throws IOException {
+        boolean success = false;
+        if (context != null) {
+            IOListener ioListener = context.getIOListener();
+            if (ioListener == null) {
+                ioListener = new DefaultIOListener(log);
+            }
+
+            Iterator it = ioHandlers.iterator();
+            while (it.hasNext() && !success) {
+                IOHandler ioh = (IOHandler)it.next();
+                if (ioh.canExport(context, isCollection)) {
+                    ioListener.onBegin(ioh, context);
+                    success = ioh.exportContent(context, isCollection);
+                    ioListener.onEnd(ioh, context, success);
+                }
+            }
+            context.informCompleted(success);
+        }
+        return success;
+    }
+
+    public boolean exportContent(ExportContext context, DavResource resource) throws IOException {
+        boolean success = false;
+        if (context != null && resource != null) {
+            IOListener ioListener = context.getIOListener();
+            if (ioListener == null) {
+                ioListener = new DefaultIOListener(log);
+            }
+
+            Iterator it = ioHandlers.iterator();
+            while (it.hasNext() && !success) {
+                IOHandler ioh = (IOHandler)it.next();
+                if (ioh.canExport(context, resource)) {
+                    ioListener.onBegin(ioh, context);
+                    success = ioh.exportContent(context, resource);
+                    ioListener.onEnd(ioh, context, success);
+                }
+            }
+            context.informCompleted(success);
+        }
+        return success;
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DefaultIOManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,252 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.util.Text;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavResourceIterator;
+
+import javax.jcr.Item;
+import javax.jcr.Repository;
+import javax.jcr.NodeIterator;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+import java.util.Date;
+
+/**
+ * <code>DirListingExportHandler</code> represents a simple export for collections:
+ * a human-readable view listing the members.<br>
+ * Note: If {@link #exportContent(ExportContext, boolean)} is called the view list
+ * child nodes only, without respecting their representation as <code>DavResource</code>s.
+ */
+public class DirListingExportHandler implements IOHandler {
+
+    private static Logger log = Logger.getLogger(DirListingExportHandler.class);
+
+    private IOManager ioManager;
+
+    /**
+     * Creates a new <code>DirListingExportHandler</code>
+     *
+     * @param ioManager
+     */
+    public DirListingExportHandler(IOManager ioManager) {
+        this.ioManager = ioManager;
+    }
+
+    /**
+     * Always returns false
+     *
+     * @see IOHandler#canImport(ImportContext, boolean)
+     */
+    public boolean canImport(ImportContext context, boolean isFolder) {
+        return false;
+    }
+
+    /**
+     * Always returns false
+     *
+     * @see IOHandler#canImport(ImportContext, DavResource)
+     */
+    public boolean canImport(ImportContext context, DavResource resource) {
+        return false;
+    }
+
+    /**
+     * Does nothing and returns false
+     *
+     * @see IOHandler#importContent(ImportContext, boolean)
+     */
+    public boolean importContent(ImportContext context, boolean isCollection) throws IOException {
+        // can only handle export
+        return false;
+    }
+
+    /**
+     * Does nothing and returns false
+     *
+     * @see IOHandler#importContent(ImportContext, DavResource)
+     */
+    public boolean importContent(ImportContext context, DavResource resource) throws IOException {
+        return false;
+    }
+
+    /**
+     * @return true if the specified context is still valid and provides a
+     * export root and if 'isCollection' is true. False otherwise
+     * @see IOHandler#canExport(ExportContext, boolean)
+     */
+    public boolean canExport(ExportContext context, boolean isCollection) {
+        if (context == null || context.isCompleted()) {
+            return false;
+        }
+        return isCollection && context.getExportRoot() != null;
+    }
+
+    /**
+     * @return true if the specified context is still valid and provides a
+     * export root and if the specified resource is a collection. False otherwise.
+     * @see IOHandler#canExport(ExportContext, DavResource)
+     * @see DavResource#isCollection()
+     */
+    public boolean canExport(ExportContext context, DavResource resource) {
+        if (resource == null) {
+            return false;
+        }
+        return canExport(context, resource.isCollection());
+    }
+
+    /**
+     * @see IOHandler#exportContent(ExportContext, boolean)
+     */
+    public boolean exportContent(ExportContext context, boolean isCollection) throws IOException {
+        if (!canExport(context, isCollection)) {
+            throw new IOException(getName() + ": Cannot export " + context.getExportRoot());
+        }
+
+        // properties (contentlength undefined)
+        context.setModificationTime(new Date().getTime());
+        context.setContentType("text/html", "UTF-8");
+        context.setETag("");
+
+        // data
+        if (context.hasStream()) {
+            PrintWriter writer = new PrintWriter(new OutputStreamWriter(context.getOutputStream(), "utf8"));
+            try {
+                Item item = context.getExportRoot();
+                Repository rep = item.getSession().getRepository();
+                String repName = rep.getDescriptor(Repository.REP_NAME_DESC);
+                String repURL = rep.getDescriptor(Repository.REP_VENDOR_URL_DESC);
+                String repVersion = rep.getDescriptor(Repository.REP_VERSION_DESC);
+                writer.print("<html><head><title>");
+                writer.print(repName);
+                writer.print(" ");
+                writer.print(repVersion);
+                writer.print(" ");
+                writer.print(item.getPath());
+                writer.print("</title></head>");
+                writer.print("<body><h2>");
+                writer.print(item.getPath());
+                writer.print("</h2><ul>");
+                writer.print("<li><a href=\"..\">..</a></li>");
+                if (item.isNode()) {
+                    NodeIterator iter = ((Node)item).getNodes();
+                    while (iter.hasNext()) {
+                        Node child = iter.nextNode();
+                        String label = Text.getName(child.getPath());
+                        writer.print("<li><a href=\"");
+                        writer.print(Text.escape(label));
+                        if (child.isNode()) {
+                            writer.print("/");
+                        }
+                        writer.print("\">");
+                        writer.print(label);
+                        writer.print("</a></li>");
+                    }
+                }
+                writer.print("</ul><hr size=\"1\"><em>Powered by <a href=\"");
+                writer.print(repURL);
+                writer.print("\">");
+                writer.print(repName);
+                writer.print("</a> version ");
+                writer.print(repVersion);
+                writer.print("</em></body></html>");
+            } catch (RepositoryException e) {
+                // should not occur
+                log.debug(e.getMessage());
+            }
+            writer.close();
+        }
+        return true;
+    }
+
+    /**
+     * @see IOHandler#exportContent(ExportContext, DavResource)
+     */
+    public boolean exportContent(ExportContext context, DavResource resource) throws IOException {
+        if (!canExport(context, resource)) {
+            throw new IOException(getName() + ": Cannot export " + context.getExportRoot());
+        }
+
+        // properties (contentlength undefined)
+        context.setModificationTime(new Date().getTime());
+        context.setContentType("text/html", "UTF-8");
+        context.setETag("");
+
+        // data
+        if (context.hasStream()) {
+            PrintWriter writer = new PrintWriter(new OutputStreamWriter(context.getOutputStream(), "utf8"));
+            try {
+                Item item = context.getExportRoot();
+                Repository rep = item.getSession().getRepository();
+                String repName = rep.getDescriptor(Repository.REP_NAME_DESC);
+                String repURL = rep.getDescriptor(Repository.REP_VENDOR_URL_DESC);
+                String repVersion = rep.getDescriptor(Repository.REP_VERSION_DESC);
+                writer.print("<html><head><title>");
+                writer.print(repName);
+                writer.print(" ");
+                writer.print(repVersion);
+                writer.print(" ");
+                writer.print(resource.getResourcePath());
+                writer.print("</title></head>");
+                writer.print("<body><h2>");
+                writer.print(resource.getResourcePath());
+                writer.print("</h2><ul>");
+                writer.print("<li><a href=\"..\">..</a></li>");
+                DavResourceIterator iter = resource.getMembers();
+                while (iter.hasNext()) {
+                    DavResource child = iter.nextResource();
+                    String label = Text.getName(child.getResourcePath());
+                    writer.print("<li><a href=\"");
+                    writer.print(child.getHref());
+                    writer.print("\">");
+                    writer.print(label);
+                    writer.print("</a></li>");
+                }
+                writer.print("</ul><hr size=\"1\"><em>Powered by <a href=\"");
+                writer.print(repURL);
+                writer.print("\">");
+                writer.print(repName);
+                writer.print("</a> version ");
+                writer.print(repVersion);
+                writer.print("</em></body></html>");
+            } catch (RepositoryException e) {
+                // should not occur
+                log.debug(e.getMessage());
+            }
+            writer.close();
+        }
+        return true;
+    }
+
+    /**
+     * @see IOHandler#getIOManager()
+     */
+    public IOManager getIOManager() {
+        return ioManager;
+    }
+
+    /**
+     * @see IOHandler#getName()
+     */
+    public String getName() {
+        return "DirListing Export";
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/DirListingExportHandler.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContext.java?rev=331281&r1=331280&r2=331281&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContext.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContext.java Mon Nov  7 07:26:33 2005
@@ -16,231 +16,78 @@
  */
 package org.apache.jackrabbit.server.io;
 
-import javax.jcr.Node;
-import java.io.InputStream;
-import java.util.Properties;
+import javax.jcr.Item;
+import java.io.OutputStream;
 
 /**
- * This Class implements a export context which is passed to the respective
- * export commands.
- * </p>
- * Please note, that this export context lacks an explicit
- * {@link org.apache.jackrabbit.webdav.DavResource} member. Currently, this
- * information is not needed in any of the known export commands but leaves this
- * I/O framework more generic.
+ * <code>ExportContext</code>...
  */
-public class ExportContext extends AbstractContext {
+public interface ExportContext extends IOContext {
 
     /**
-     * the node to be exported
-     */
-    private Node node;
-
-    /**
-     * the input stream that needs to be set by the export commands
-     */
-    private InputStream inputStream;
-
-    /**
-     * the content length of the data in the input stream
-     */
-    private long contentLength;
-
-    /**
-     * the last modifiaction time of the resource
-     */
-    private long modificationTime;
-
-    /**
-     * the creation time of the resource
-     */
-    private long creationTime;
-
-    /**
-     * the content type of the resource
-     */
-    private String contentType;
-
-    /**
-     * The content language of the resource
-     */
-    private String contentLanguage;
-
-    /**
-     * the ETag of the resource
-     */
-    private String etag;
-
-    /**
-     * Creates a new ExportContext for the given node
+     * Returns the item to be exported
      *
-     * @param exportRoot
-     */
-    public ExportContext(Node exportRoot) {
-        this(null, exportRoot);
-    }
-
-    /**
-     * Creats a new import context with the given root node and property defaults.
-     * @param props
-     * @param exportRoot
-     */
-    public ExportContext(Properties props, Node exportRoot) {
-        super(props);
-        if (exportRoot == null) {
-            throw new IllegalArgumentException("exportRoot can not be null.");
-        }
-        this.node = exportRoot;
-    }
-
-    /**
-     * Creates a new sub context which bases on this contexts properties
-     * @param node
      * @return
      */
-    public ExportContext createSubContext(Node node) {
-        return new ExportContext(this, node);
-    }
-
+    public Item getExportRoot();
 
     /**
-     * Returns the input stream
+     * Return the output stream to be used for the export or <code>null</code>
      *
-     * @return the input stream
+     * @return output stream or <code>null</code>
      */
-    public InputStream getInputStream() {
-        return inputStream;
-    }
+    public OutputStream getOutputStream();
 
     /**
-     * Sets a the inpurt stream to the data to be exported. A successfull
-     * export command must set this memeber.
+     * Set the content type for the resource content
      *
-     * @param inputStream
+     * @param mimeType
+     * @param encoding
      */
-    public void setInputStream(InputStream inputStream) {
-        this.inputStream = inputStream;
-    }
+    public void setContentType(String mimeType, String encoding);
 
     /**
-     * Returns the node to be exported
-     *
-     * @return
-     */
-    public Node getNode() {
-        return node;
-    }
-
-    /**
-     * Returns the length of the data to be exported
+     * Sets the content language.
      *
-     * @return the content length
+     * @param contentLanguage
      */
-    public long getContentLength() {
-        return contentLength;
-    }
+    public void setContentLanguage(String contentLanguage);
 
     /**
-     * Sets the length of the data to be exported. A successfull export command
-     * must set this memeber.
+     * Sets the length of the data.
      *
      * @param contentLength the content length
      */
-    public void setContentLength(long contentLength) {
-        this.contentLength = contentLength;
-    }
+    public void setContentLength(long contentLength);
 
     /**
-     * Returns the last modification time.
-     *
-     * @return the last modification time.
-     */
-    public long getModificationTime() {
-        return modificationTime;
-    }
-
-    /**
-     * Sets the last modification time. A successfull export command may set
-     * this member.
-     *
-     * @param modificationTime the last modification time
-     */
-    public void setModificationTime(long modificationTime) {
-        this.modificationTime = modificationTime;
-    }
-
-    /**
-     * Returns the creation time of the resource.
-     *
-     * @return the creation time
-     */
-    public long getCreationTime() {
-        return creationTime;
-    }
-
-    /**
-     * Sets the creation time of the resource. A successfull export command may
+     * Sets the creation time of the resource. A successful properties export may
      * set this member.
      *
      * @param creationTime the creation time
      */
-    public void setCreationTime(long creationTime) {
-        this.creationTime = creationTime;
-    }
+    public void setCreationTime(long creationTime);
 
     /**
-     * Returns the content type of the resource.
+     * Sets the modification time of the resource
      *
-     * @return the content type
+     * @param modificationTime the modification time
      */
-    public String getContentType() {
-        return contentType;
-    }
+    public void setModificationTime(long modificationTime);
 
     /**
-     * Sets the content type of the resource. A successfull export command
+     * Sets the ETag of the resource. A successfull export command
      * may set this member.
      * 
-     * @param contentType the content type
-     */
-    public void setContentType(String contentType) {
-        this.contentType = contentType;
-    }
-
-    /**
-     * Returns the content language or <code>null</code>
-     *
-     * @return contentLanguage
-     */
-    public String getContentLanguage() {
-        return contentLanguage;
-    }
-
-    /**
-     * Sets the content language.
-     *
-     * @param contentLanguage
-     */
-    public void setContentLanguage(String contentLanguage) {
-        this.contentLanguage = contentLanguage;
-    }
-
-    /**
-     * Returns the ETag of the resource.
-     *
-     * @return the ETag
+     * @param etag the ETag
      */
-    public String getETag() {
-        return etag;
-    }
+    public void setETag(String etag);
 
     /**
-     * Sets the ETag of the resource. A successfull export command
-     * may set this member.
+     * Sets an arbitrary property to this export context.
      *
-     * @param etag the ETag
+     * @param propertyName
+     * @param propertyValue
      */
-    public void setETag(String etag) {
-        this.etag = etag;
-    }
+    public void setProperty(Object propertyName, Object propertyValue);
 }

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,173 @@
+/*
+ * 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.server.io;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.io.OutputContext;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavResource;
+
+import javax.jcr.Item;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Date;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.FileOutputStream;
+
+/**
+ * <code>ExportContextImpl</code> implements an <code>ExportContext</code> that
+ * wraps around the specified OutputContext as it was passed to
+ * {@link DavResource#spool(OutputContext)}. If a stream is provided a temporary
+ * file is created, which is deleted as soon as {@link #informCompleted(boolean)}
+ * is called on this context. Note however, that the properties and the stream
+ * are written to the  <code>OutputContext</code> but upon successful completion.
+ *
+ * @see #informCompleted(boolean)
+ */
+public class ExportContextImpl extends AbstractExportContext {
+
+    private static Logger log = Logger.getLogger(ExportContextImpl.class);
+
+    private final Map properties = new HashMap();
+    private final OutputContext outputCtx;
+
+    private File outFile;
+
+    public ExportContextImpl(Item exportRoot, OutputContext outputCtx) throws IOException {
+        super(exportRoot, (outputCtx != null) ? outputCtx.hasStream() : false, null);
+        this.outputCtx = outputCtx;
+        if (hasStream()) {
+            // we need a tmp file, since the export could fail
+            outFile = File.createTempFile("__exportcontext", "tmp");
+        }
+    }
+
+    /**
+     * Returns a new <code>OutputStream</code> to the temporary file or
+     * <code>null</code> if this context provides no stream.
+     *
+     * @see ExportContext#getOutputStream()
+     * @see #informCompleted(boolean)
+     */
+    public OutputStream getOutputStream() {
+        checkCompleted();
+        if (hasStream()) {
+            try {
+                return new FileOutputStream(outFile);
+            } catch (IOException e) {
+                // unexpected error... ignore and return null
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see ExportContext#setContentLanguage(String)
+     */
+    public void setContentLanguage(String contentLanguage) {
+        properties.put(DavConstants.HEADER_CONTENT_LANGUAGE, contentLanguage);
+    }
+
+    /**
+     * @see ExportContext#setContentLength(long)
+     */
+    public void setContentLength(long contentLength) {
+        properties.put(DavConstants.HEADER_CONTENT_LENGTH, contentLength + "");
+    }
+
+    /**
+     * @see ExportContext#setContentType(String,String)
+     */
+    public void setContentType(String mimeType, String encoding) {
+        properties.put(DavConstants.HEADER_CONTENT_TYPE, IOUtil.buildContentType(mimeType, encoding));
+    }
+
+    /**
+     * Does nothing since the wrapped output context does not understand
+     * creation time
+     *
+     * @param creationTime
+     * @see ExportContext#setCreationTime(long)
+     */
+    public void setCreationTime(long creationTime) {
+        // ignore since output-ctx does not understand creation time
+    }
+
+    /**
+     * @see ExportContext#setModificationTime(long)
+     */
+    public void setModificationTime(long modificationTime) {
+        if (modificationTime <= IOUtil.UNDEFINED_TIME) {
+            modificationTime = new Date().getTime();
+        }
+        String lastMod = IOUtil.getLastModified(modificationTime);
+        properties.put(DavConstants.HEADER_LAST_MODIFIED, lastMod);
+    }
+
+    /**
+     * @see ExportContext#setETag(String)
+     */
+    public void setETag(String etag) {
+        properties.put(DavConstants.HEADER_ETAG, etag);
+    }
+
+    /**
+     * @see ExportContext#setProperty(Object, Object) 
+     */
+    public void setProperty(Object propertyName, Object propertyValue) {
+        properties.put(propertyName, propertyValue);
+    }
+
+    /**
+     * If success is true, the properties set before an the output stream are
+     * written to the wrapped <code>OutputContext</code>.
+     *
+     * @param success
+     * @see ExportContext#informCompleted(boolean)
+     */
+    public void informCompleted(boolean success) {
+        checkCompleted();
+        completed = true;
+        if (success) {
+            // write properties and data to the output-context
+            if (outputCtx != null) {
+                Iterator it = properties.keySet().iterator();
+                while (it.hasNext()) {
+                    String name = it.next().toString();
+                    String value = properties.get(name).toString();
+                    outputCtx.setProperty(name, value);
+                }
+
+                if (outputCtx.hasStream() && outFile != null) {
+                    OutputStream out = outputCtx.getOutputStream();
+                    try {
+                        FileInputStream in = new FileInputStream(outFile);
+                        IOUtil.spool(in, out);
+                    } catch (IOException e) {
+                        log.error(e);
+                    }
+                }
+            }
+        }
+        if (outFile != null) {
+            outFile.delete();
+        }
+    }
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/ExportContextImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java?rev=331281&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java Mon Nov  7 07:26:33 2005
@@ -0,0 +1,50 @@
+/*
+ * 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.server.io;
+
+/**
+ * <code>IOContext</code> defines the common methods for {@link ImportContext}
+ * and {@link ExportContext}
+ */
+public interface IOContext {
+
+    /**
+     * Returns the IOListener.
+     *
+     * @return
+     */
+    public IOListener getIOListener();
+
+    /**
+     * Return true if the given export context can provide an output stream
+     */
+    public boolean hasStream();
+
+    /**
+     * Informs this context that it will not be used for futher exports any
+     * more. A boolean flag indicates about the success of the export
+     *
+     * @param success
+     */
+    public void informCompleted(boolean success);
+
+    /**
+     * Returns true if this context already has been completed.
+     *
+     * @return true if this context already has been completed.
+     */
+    public boolean isCompleted();
+}
\ No newline at end of file

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

Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/IOContext.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url



Mime
View raw message