Index: src/main/java/org/apache/jackrabbit/server/io/CopyMoveManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/server/io/CopyMoveManager.java (revision )
+++ src/main/java/org/apache/jackrabbit/server/io/CopyMoveManager.java (revision )
@@ -0,0 +1,64 @@
+/*
+ * 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.server.io;
+
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+
+import javax.jcr.Session;
+import java.io.IOException;
+
+/**
+ * CopyMoveManager...
+ */
+public interface CopyMoveManager {
+
+ /**
+ * Handles the copy command
+ *
+ * @param session
+ * @param locator
+ * @param dstPath
+ * @return
+ * @throws IOException
+ */
+ public boolean copyContent(Session session, DavResourceLocator locator, String dstPath) throws IOException;
+
+ /**
+ * Handles the move command
+ *
+ * @param session
+ * @param locator
+ * @param dstPath
+ * @return
+ * @throws IOException
+ */
+ public boolean moveContent(Session session, DavResourceLocator locator, String dstPath) throws IOException;
+
+ /**
+ * Adds the specified handler to the list of handlers.
+ *
+ * @param copyMoveHandler handler to be added
+ */
+ public void addCopyMoveHandler(CopyMoveHandler copyMoveHandler);
+
+ /**
+ * Returns all handlers that have been added to this manager.
+ *
+ * @return Array of all handlers
+ */
+ public CopyMoveHandler[] getCopyMoveHandlers();
+}
Index: src/main/java/org/apache/jackrabbit/server/io/CopyMoveManagerImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/server/io/CopyMoveManagerImpl.java (revision )
+++ src/main/java/org/apache/jackrabbit/server/io/CopyMoveManagerImpl.java (revision )
@@ -0,0 +1,102 @@
+/*
+ * 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.server.io;
+
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Session;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * CopyMoveManagerImpl...
+ */
+public class CopyMoveManagerImpl implements CopyMoveManager {
+
+ private static Logger log = LoggerFactory.getLogger(CopyMoveManagerImpl.class);
+
+ private static CopyMoveManager DEFAULT_MANAGER;
+
+ private final List copyMoveHandlers = new ArrayList();
+
+ /**
+ * Create a new CopyMoveManagerImpl.
+ */
+ public CopyMoveManagerImpl() {
+ }
+
+ /**
+ * @see org.apache.jackrabbit.server.io.CopyMoveManager#copyContent(javax.jcr.Session, org.apache.jackrabbit.webdav.DavResourceLocator, String)
+ */
+ public boolean copyContent(Session session, DavResourceLocator locator, String dstPath) throws IOException {
+ boolean success = false;
+ CopyMoveHandler[] copyMoveHandlers = getCopyMoveHandlers();
+ for (int i = 0; i < copyMoveHandlers.length && !success; i++) {
+ CopyMoveHandler cmh = copyMoveHandlers[i];
+ if (cmh.canCopy(locator, dstPath)) {
+ success = cmh.copyContent(session, locator, dstPath);
+ }
+ }
+ return success;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.server.io.CopyMoveManager#moveContent(javax.jcr.Session, org.apache.jackrabbit.webdav.DavResourceLocator, String)
+ */
+ public boolean moveContent(Session session, DavResourceLocator locator, String dstPath) throws IOException {
+ boolean success = false;
+ CopyMoveHandler[] copyMoveHandlers = getCopyMoveHandlers();
+ for (int i = 0; i < copyMoveHandlers.length && !success; i++) {
+ CopyMoveHandler cmh = copyMoveHandlers[i];
+ if (cmh.canMove(locator, dstPath)) {
+ success = cmh.moveContent(session, locator, dstPath);
+ }
+ }
+ return success;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.server.io.CopyMoveManager#addCopyMoveHandler(CopyMoveHandler)
+ */
+ public void addCopyMoveHandler(CopyMoveHandler copyMoveHandler) {
+ if (copyMoveHandler == null) {
+ throw new IllegalArgumentException("'null' is not a valid copyMoveHandler.");
+ }
+ copyMoveHandlers.add(copyMoveHandler);
+ }
+
+ /**
+ * @see CopyMoveManager#getCopyMoveHandlers()
+ */
+ public CopyMoveHandler[] getCopyMoveHandlers() {
+ return copyMoveHandlers.toArray(new CopyMoveHandler[copyMoveHandlers.size()]);
+ }
+
+ /**
+ * @return an instance of CopyMoveManager populated with default handlers.
+ */
+ public static CopyMoveManager getDefaultManager() {
+ if (DEFAULT_MANAGER == null) {
+ DEFAULT_MANAGER = new CopyMoveManagerImpl();
+ DEFAULT_MANAGER.addCopyMoveHandler(new DefaultHandler());
+ }
+ return DEFAULT_MANAGER;
+ }
+}
Index: src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java
===================================================================
--- src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java (revision 1155390)
+++ src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java (revision )
@@ -20,7 +20,11 @@
import org.apache.jackrabbit.commons.NamespaceHelper;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;
+import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.DavSession;
+import org.apache.jackrabbit.webdav.jcr.JcrDavException;
import org.apache.jackrabbit.webdav.xml.Namespace;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavProperty;
@@ -67,7 +71,7 @@
* 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, PropertyHandler {
+public class DefaultHandler implements IOHandler, PropertyHandler, CopyMoveHandler {
private static Logger log = LoggerFactory.getLogger(DefaultHandler.class);
@@ -671,6 +675,33 @@
}
}
+ //--------------------------------------------------< CopyMoveHandler >---
+ public boolean canCopy(DavResourceLocator locator, String dstPath) throws IOException {
+ return true;
+ }
+
+ public boolean copyContent(Session session, DavResourceLocator locator, String dstPath) throws IOException {
+ try {
+ session.getWorkspace().copy(locator.getRepositoryPath(), dstPath);
+ return true;
+ } catch (RepositoryException e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public boolean canMove(DavResourceLocator locator, String dstPath) throws IOException {
+ return true;
+ }
+
+ public boolean moveContent(Session session, DavResourceLocator locator, String dstPath) throws IOException {
+ try {
+ session.getWorkspace().move(locator.getRepositoryPath(), dstPath);
+ return true;
+ } catch (RepositoryException e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
//------------------------------------------------------------< private >---
/**
* Builds a webdav property name from the given jcrName. In case the jcrName
Index: src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (revision 1155286)
+++ src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (revision )
@@ -68,7 +68,6 @@
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
-import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
@@ -599,13 +598,17 @@
}
// make sure, that src and destination belong to the same workspace
checkSameWorkspace(destination.getLocator());
- try {
- String destItemPath = destination.getLocator().getRepositoryPath();
+ String destItemPath = destination.getLocator().getRepositoryPath();
- getJcrSession().getWorkspace().move(locator.getRepositoryPath(), destItemPath);
- } catch (RepositoryException e) {
- throw new JcrDavException(e);
+ try {
+ if (!config.getCopyMoveManager().moveContent(getJcrSession(), locator, destItemPath)) {
+ throw new DavException(DavServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
- }
+ }
+ } catch (IOException ioe) {
+ // TODO: correct?
+ log.error("Error while moving resource: " + ioe.toString());
+ throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, ioe.getMessage());
- }
+ }
+ }
/**
* @see DavResource#copy(DavResource, boolean)
@@ -628,16 +631,17 @@
}
// make sure, that src and destination belong to the same workspace
checkSameWorkspace(destination.getLocator());
- try {
- String destItemPath = destination.getLocator().getRepositoryPath();
+ String destItemPath = destination.getLocator().getRepositoryPath();
- getJcrSession().getWorkspace().copy(locator.getRepositoryPath(), destItemPath);
- } catch (PathNotFoundException e) {
- // according to rfc 2518: missing parent
- throw new DavException(DavServletResponse.SC_CONFLICT, e.getMessage());
- } catch (RepositoryException e) {
- throw new JcrDavException(e);
+ try {
+ if (!config.getCopyMoveManager().copyContent(getJcrSession(), locator, destItemPath)) {
+ throw new DavException(DavServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
- }
+ }
+ } catch (IOException ioe) {
+ // TODO: correct?
+ log.error("Error while copying resource: " + ioe.toString());
+ throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, ioe.getMessage());
- }
+ }
+ }
/**
* @param type
Index: src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java
===================================================================
--- src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java (revision 1156078)
+++ src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java (revision )
@@ -31,6 +31,9 @@
import javax.jcr.RepositoryException;
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.jackrabbit.server.io.CopyMoveHandler;
+import org.apache.jackrabbit.server.io.CopyMoveManager;
+import org.apache.jackrabbit.server.io.CopyMoveManagerImpl;
import org.apache.jackrabbit.server.io.DefaultIOManager;
import org.apache.jackrabbit.server.io.IOHandler;
import org.apache.jackrabbit.server.io.IOManager;
@@ -59,6 +62,9 @@
private static final String ELEMENT_PROPERTYMANAGER = "propertymanager";
private static final String ELEMENT_PROPERTYHANDLER = "propertyhandler";
+ private static final String ELEMENT_COPYMOVEMANAGER = "copymovemanager";
+ private static final String ELEMENT_COPYMOVEHANDLER = "copymovehandler";
+
private static final String ELEMENT_CLASS = "class";
private static final String ELEMENT_PARAM = "param";
@@ -72,6 +78,7 @@
private ItemFilter itemFilter;
private IOManager ioManager;
+ private CopyMoveManager cmManager;
private PropertyManager propManager;
private String[] nodetypeNames = new String[0];
private boolean collectionNames = false;
@@ -225,6 +232,33 @@
log.debug("'propertymanager' element is missing.");
}
+ // copymovemanager config entry
+ el = DomUtil.getChildElement(config, ELEMENT_COPYMOVEMANAGER, null);
+ if (el != null) {
+ Object inst = buildClassFromConfig(el);
+ if (inst != null && inst instanceof CopyMoveManager) {
+ cmManager = (CopyMoveManager)inst;
+ // get optional 'iohandler' child elements and populate the
+ // ioManager with the instances
+ ElementIterator iohElements = DomUtil.getChildren(el, ELEMENT_COPYMOVEHANDLER, null);
+ while (iohElements.hasNext()) {
+ Element iohEl = iohElements.nextElement();
+ inst = buildClassFromConfig(iohEl);
+ if (inst != null && inst instanceof CopyMoveHandler) {
+ CopyMoveHandler handler = (CopyMoveHandler) inst;
+ setParameters(handler, iohEl);
+ cmManager.addCopyMoveHandler(handler);
+ } else {
+ log.warn("Not a valid CopyMoveHandler : " + getClassName(iohEl));
+ }
+ }
+ } else {
+ log.warn("'copymovemanager' element does not define a valid CopyMoveManager.");
+ }
+ } else {
+ log.debug("'copymovemanager' element is missing.");
+ }
+
// collection/non-collection config entry
el = DomUtil.getChildElement(config, "collection", null);
if (el != null) {
@@ -427,6 +461,18 @@
}
/**
+ *
+ * @return
+ */
+ public CopyMoveManager getCopyMoveManager() {
+ if (cmManager == null) {
+ log.debug("Missing copymove-manager > building default.");
+ cmManager = CopyMoveManagerImpl.getDefaultManager();
+ }
+ return cmManager;
+ }
+
+ /**
* Returns true, if the given item represents a {@link Node node} that is
* either any of the nodetypes specified to represent a collection or
* none of the nodetypes specified to represent a non-collection, respectively.
Index: src/main/java/org/apache/jackrabbit/server/io/CopyMoveHandler.java
===================================================================
--- src/main/java/org/apache/jackrabbit/server/io/CopyMoveHandler.java (revision )
+++ src/main/java/org/apache/jackrabbit/server/io/CopyMoveHandler.java (revision )
@@ -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.server.io;
+
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+
+import javax.jcr.Session;
+import java.io.IOException;
+
+/**
+ * CopyMoveHandler...
+ */
+public interface CopyMoveHandler {
+
+ public boolean canCopy(DavResourceLocator locator, String dstPath) throws IOException;
+
+ public boolean copyContent(Session session, DavResourceLocator locator, String dstPath) throws IOException;
+
+ public boolean canMove(DavResourceLocator locator, String dstPath) throws IOException;
+
+ public boolean moveContent(Session session, DavResourceLocator locator, String dstPath) throws IOException;
+}