diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java index af7da3e..263df2d 100644 --- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java @@ -71,7 +71,7 @@ import java.util.HashMap; * 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, CopyMoveHandler { +public class DefaultHandler implements IOHandler, PropertyHandler, CopyMoveHandler, DeleteHandler { private static Logger log = LoggerFactory.getLogger(DefaultHandler.class); @@ -854,4 +854,27 @@ public class DefaultHandler implements IOHandler, PropertyHandler, CopyMoveHandl public void setContentNodetype(String contentNodetype) { this.contentNodetype = contentNodetype; } + + @Override + public boolean delete(DeleteContext deleteContext, DavResource member) throws DavException { + try { + String itemPath = member.getLocator().getRepositoryPath(); + Item memItem = deleteContext.getSession().getItem(itemPath); + if (memItem instanceof Node) { + ((Node)memItem).removeShare(); + } else { + memItem.remove(); + } + deleteContext.getSession().save(); + log.debug("default handler deleted " + member.getResourcePath()); + return true; + } catch (RepositoryException e) { + throw new JcrDavException(e); + } + } + + @Override + public boolean canDelete(DeleteContext deleteContext, DavResource member) { + return true; + } } diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContext.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContext.java new file mode 100644 index 0000000..7d18ed4 --- /dev/null +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContext.java @@ -0,0 +1,31 @@ +/* + * 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 javax.jcr.Session; + +/** + * The context associated with a DELETE operation + */ +public interface DeleteContext { + /** + * @return the jcr session associated with this context. + */ + Session getSession(); + +} diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContextImpl.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContextImpl.java new file mode 100644 index 0000000..84f9a78 --- /dev/null +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteContextImpl.java @@ -0,0 +1,34 @@ +/* + * 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 javax.jcr.Session; + +public class DeleteContextImpl implements DeleteContext { + + private final Session session; + + public DeleteContextImpl(Session session) { + this.session = session; + } + + @Override + public Session getSession() { + return this.session; + } +} diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteHandler.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteHandler.java new file mode 100644 index 0000000..278dd61 --- /dev/null +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteHandler.java @@ -0,0 +1,51 @@ +/* + * 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.DavException; +import org.apache.jackrabbit.webdav.DavResource; + +/** + * The DeleteHandler is invoked when a webdav DELETE request is received. Implementers of this interface should plugin + * their handling of DELETE request here + */ +public interface DeleteHandler { + + /** + * Executes the delete operation with the given parameters. + * + * @param deleteContext The context of the delete. + * @param resource The resource to be deleted + * @return true if this instance successfully executed the delete operation with the given parameters; + * false otherwise. + * @throws DavException If an error occurs. + */ + public boolean delete(DeleteContext deleteContext, DavResource resource) throws DavException; + + + /** + * Validates if this handler is able to execute a delete operation with the given + * parameters. + * + * @param deleteContext The context of the delete + * @param resource The resource to be deleted + * @return true if this instance can successfully execute the delete operation with the given parameters; + * false otherwise. + */ + public boolean canDelete(DeleteContext deleteContext, DavResource resource); +} diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManager.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManager.java new file mode 100644 index 0000000..c5035d6 --- /dev/null +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManager.java @@ -0,0 +1,51 @@ +/* + * 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.DavException; +import org.apache.jackrabbit.webdav.DavResource; + +/** + *The DeleteManager handles DELETE operation by delegating it to its handlers. It also provides a way + * to register {@link org.apache.jackrabbit.server.io.DeleteHandler} within it. Implementers of this interface + * must invoke the registered delete handlers appropriately when a DELETE operation is to be performed + */ +public interface DeleteManager { + + /** + * + * @param deleteContext The context associated with the DELETE operation + * @param resource The resource to be deleted + * @return true if this instance successfully executed the delete operation with the given parameters; + * false otherwise. + * @throws DavException If an error occurs. + */ + public boolean delete(DeleteContext deleteContext, DavResource resource) throws DavException; + + /** + * + * @param deleteHandler Registers a {@link org.apache.jackrabbit.server.io.DeleteHandler} with this delete manager + */ + public void addDeleteHandler(DeleteHandler deleteHandler); + + /** + * + * @return An array of all the registered delete handlers. + */ + public DeleteHandler[] getDeleteHandlers(); +} diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManagerImpl.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManagerImpl.java new file mode 100644 index 0000000..fb6f7dc --- /dev/null +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DeleteManagerImpl.java @@ -0,0 +1,69 @@ +/* + * 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.DavException; +import org.apache.jackrabbit.webdav.DavResource; + +import java.util.ArrayList; +import java.util.List; + +public class DeleteManagerImpl implements DeleteManager { + + private static DeleteManager DEFAULT_MANAGER; + + private final List deleteHandlers = new ArrayList(); + + + @Override + public boolean delete(DeleteContext deleteContext, DavResource member) throws DavException { + boolean success = false; + DeleteHandler[] deleteHandlers = getDeleteHandlers(); + for (int i = 0; i < deleteHandlers.length && !success; i++) { + DeleteHandler dh = deleteHandlers[i]; + if (dh.canDelete(deleteContext, member)) { + success = dh.delete(deleteContext, member); + } + } + return success; + } + + @Override + public void addDeleteHandler(DeleteHandler deleteHandler) { + if (deleteHandler == null) { + throw new IllegalArgumentException("'null' is not a valid DeleteHandler."); + } + deleteHandlers.add(deleteHandler); + + } + + @Override + public DeleteHandler[] getDeleteHandlers() { + return deleteHandlers.toArray(new DeleteHandler[deleteHandlers.size()]); + } + + public static DeleteManager getDefaultManager() { + if (DEFAULT_MANAGER == null) { + DeleteManager manager = new DeleteManagerImpl(); + manager.addDeleteHandler(new DefaultHandler()); + DEFAULT_MANAGER = manager; + } + return DEFAULT_MANAGER; + } + +} diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java index 1493c2c..0bf7b71 100644 --- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java @@ -20,6 +20,8 @@ import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.server.io.AbstractExportContext; import org.apache.jackrabbit.server.io.CopyMoveContextImpl; import org.apache.jackrabbit.server.io.DefaultIOListener; +import org.apache.jackrabbit.server.io.DeleteContextImpl; +import org.apache.jackrabbit.server.io.DeleteManager; import org.apache.jackrabbit.server.io.ExportContext; import org.apache.jackrabbit.server.io.ExportContextImpl; import org.apache.jackrabbit.server.io.IOListener; @@ -557,31 +559,20 @@ public class DavResourceImpl implements DavResource, BindableResource, JcrConsta throw new DavException(DavServletResponse.SC_FORBIDDEN); } + DeleteManager dm = config.getDeleteManager(); + dm.delete(new DeleteContextImpl(getJcrSession()), member); + // make sure, non-jcr locks are removed, once the removal is completed try { - String itemPath = member.getLocator().getRepositoryPath(); - Item memItem = getJcrSession().getItem(itemPath); - if (memItem instanceof Node) { - ((Node)memItem).removeShare(); - } else { - memItem.remove(); - } - getJcrSession().save(); - - // make sure, non-jcr locks are removed, once the removal is completed - try { - if (!isJcrLockable()) { - ActiveLock lock = getLock(Type.WRITE, Scope.EXCLUSIVE); - if (lock != null) { - lockManager.releaseLock(lock.getToken(), member); - } + if (!isJcrLockable()) { + ActiveLock lock = getLock(Type.WRITE, Scope.EXCLUSIVE); + if (lock != null) { + lockManager.releaseLock(lock.getToken(), member); } - } catch (DavException e) { - // since check for 'locked' exception has been performed before - // ignore any error here } - } catch (RepositoryException e) { - throw new JcrDavException(e); + } catch (DavException e) { + // since check for 'locked' exception has been performed before + // ignore any error here } } diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java index 660df46..769ffe4 100644 --- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java +++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java @@ -35,6 +35,8 @@ 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.DeleteManager; +import org.apache.jackrabbit.server.io.DeleteManagerImpl; import org.apache.jackrabbit.server.io.IOHandler; import org.apache.jackrabbit.server.io.IOManager; import org.apache.jackrabbit.server.io.PropertyHandler; @@ -80,6 +82,7 @@ public class ResourceConfig { private IOManager ioManager; private CopyMoveManager cmManager; private PropertyManager propManager; + private DeleteManager deleteManager; private String[] nodetypeNames = new String[0]; private boolean collectionNames = false; @@ -472,6 +475,14 @@ public class ResourceConfig { return cmManager; } + public DeleteManager getDeleteManager() { + if (deleteManager == null) { + log.debug("Missing delete-manager > building default."); + deleteManager = DeleteManagerImpl.getDefaultManager(); + } + return deleteManager; + } + /** * Returns true, if the given item represents a {@link Node node} that is * either any of the nodetypes specified to represent a collection or