commit 37ae75e821ba43ea636f1e65a38e86bcb0e78c10
Author: Alfusainey <alf.jallow@gmail.com>
Date:   Mon Apr 27 12:09:34 2015 +0200

    add XML configuration support for handlers that remove protected items in the JCR Server

diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
index 308b69e..57d152b 100644
--- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
+++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.server.remoting.davex;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -236,7 +237,8 @@ public abstract class JcrRemotingServlet extends JCRWebdavServerServlet {
     public static final String INIT_PARAM_BATCHREAD_CONFIG = "batchread-config";
 
     /**
-     * the 'protectedhandlers-config' init paramter.
+     * the 'protectedhandlers-config' init paramter. this parameter contains the XML
+     * configuration file for protected item remove handlers. 
      */
     public static final String INIT_PARAM_PROTECTED_HANDLERS_CONFIG = "protectedhandlers-config";
     
@@ -271,10 +273,11 @@ public abstract class JcrRemotingServlet extends JCRWebdavServerServlet {
         }
 
         String protectedHandlerConfig = getServletConfig().getInitParameter(INIT_PARAM_PROTECTED_HANDLERS_CONFIG);
-        try {
+        
+        try {        	
             protectedRemoveManager = new ProtectedRemoveManager(protectedHandlerConfig);
         } catch (IOException e) {
-            log.debug("Unable to create ProtectedRemoveManager from " + protectedHandlerConfig + ".");
+            log.debug("Unable to create ProtectedRemoveManager from " + protectedHandlerConfig + ".\n "+e.getMessage());
         }
 
         // Determine the configured location for temporary files used when
diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveConfig.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveConfig.java
new file mode 100644
index 0000000..e44cb1e
--- /dev/null
+++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveConfig.java
@@ -0,0 +1,83 @@
+/*
+ * 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.remoting.davex;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * A configuration of ProtectedItemRemoveHandler(s).
+ * 
+ * <code>ProtectedRemoveConfig</code>
+ */
+class ProtectedRemoveConfig {
+
+	private static final Logger log = LoggerFactory.getLogger(ProtectedRemoveConfig.class);
+
+	private static final String ELEMENT_HANDLER = "protecteditemremovehandler";
+	private static final String ELEMENT_CLASS = "class";
+	private static final String ATTRIBUTE_NAME = "name";
+
+	private final ProtectedRemoveManager manager;
+
+	ProtectedRemoveConfig(ProtectedRemoveManager manager) throws IOException {
+		this.manager = manager;
+	}
+
+	void parse(InputStream inputStream) throws IOException {
+		Element config;
+		ProtectedItemRemoveHandler instance = null;
+		try {
+			config = DomUtil.parseDocument(inputStream).getDocumentElement();
+			if (config == null) {
+				log.warn("Missing mandatory config element");
+				return;
+			}
+			ElementIterator handlers = DomUtil.getChildren(config, ELEMENT_HANDLER, null);
+			while (handlers.hasNext()) {
+				Element handler = handlers.nextElement();
+				instance = createHandler(handler);
+				manager.addHandler(instance);
+			}
+		} catch (ParserConfigurationException e) {
+			log.error(e.getMessage(), e);
+		} catch (SAXException e) {
+			log.error(e.getMessage(), e);
+		}
+	}
+
+	private ProtectedItemRemoveHandler createHandler(Element parent) {
+		ProtectedItemRemoveHandler instance = null;
+		Element classElem = DomUtil.getChildElement(parent, ELEMENT_CLASS, null);
+		if (classElem != null) {
+			String className = DomUtil.getAttribute(classElem, ATTRIBUTE_NAME, null);
+			if (className != null) {
+				instance = manager.createHandler(className);
+			}
+		}
+		return instance;
+	}
+}
diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveManager.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveManager.java
index 92052ce..9dcb197 100644
--- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveManager.java
+++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/ProtectedRemoveManager.java
@@ -18,12 +18,11 @@ package org.apache.jackrabbit.server.remoting.davex;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.List;
-import java.util.Properties;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -31,13 +30,13 @@ import javax.jcr.Session;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ProtectedRemoveManager {
+class ProtectedRemoveManager {
 
     private static final Logger log = LoggerFactory.getLogger(ProtectedRemoveManager.class);
 
     private List<ProtectedItemRemoveHandler> handlers = new ArrayList<ProtectedItemRemoveHandler>();
 
-    public ProtectedRemoveManager(String config) throws IOException {
+    ProtectedRemoveManager(String config) throws IOException {
 
     	 if (config == null) {
              log.warn("protectedhandlers-config is missing -> DIFF processing can fail for the Remove operation if the content to" +
@@ -45,25 +44,18 @@ public class ProtectedRemoveManager {
          } else {
         	 File file = new File(config);
         	 if (file.exists()) {         
-        		 InputStream inStream = new FileInputStream(file);
-                 Properties props = new Properties();
-        		 props.load(inStream);             
-        		 for (Enumeration<?> en = props.propertyNames(); en.hasMoreElements();) {             
-        			 String key = en.nextElement().toString();                 
-        			 String className = props.getProperty(key);                 
-        			 if (!className.isEmpty()) {                 
-        				 ProtectedItemRemoveHandler irHandler = createHandler(className);                     
-        				 if (irHandler != null) {                     
-        					 handlers.add(irHandler);                        
-        				 }                    
-        			 }                
-        		 }            
+        		 InputStream fis = null;
+ 				try {
+ 					fis = new FileInputStream(file);
+ 					ProtectedRemoveConfig prConfig = new ProtectedRemoveConfig(this);
+ 					prConfig.parse(fis);
+ 				} catch (FileNotFoundException e) {
+ 					throw new IOException(e.getMessage(), e);
+ 				}            
         	 } else { // config is an Impl class
         		 if (!config.isEmpty()) {        	    	
-        			 ProtectedItemRemoveHandler irHandler = createHandler(config);        	         
-        			 if (irHandler != null) {        	         
-        				 handlers.add(irHandler);        	            
-        			 }        	    	
+        			 ProtectedItemRemoveHandler handler = createHandler(config); 					
+        			 addHandler(handler);        	    	
         		 } else {        	    
         			 log.debug("Fail to locate the protected-item-remove-handler properties file.");        	    	
         		 }
@@ -71,7 +63,7 @@ public class ProtectedRemoveManager {
          }    	 
     }
 
-    public boolean remove(Session session, String itemPath) throws RepositoryException {
+    boolean remove(Session session, String itemPath) throws RepositoryException {
         for (ProtectedItemRemoveHandler handler : handlers) {
             if (handler.remove(session, itemPath)) {
                 return true;
@@ -86,13 +78,15 @@ public class ProtectedRemoveManager {
      * @return
      * @throws RepositoryException
      */
-    private static ProtectedItemRemoveHandler createHandler(String className) {
+    ProtectedItemRemoveHandler createHandler(String className) {
+    	ProtectedItemRemoveHandler irHandler = null;
         try {
-            Class<?> irHandlerClass = Class.forName(className);
-            if (ProtectedItemRemoveHandler.class.isAssignableFrom(irHandlerClass)) {
-                ProtectedItemRemoveHandler irHandler = (ProtectedItemRemoveHandler) irHandlerClass.newInstance();
-                return irHandler;
-            }
+        	if (!className.isEmpty()) {
+				Class<?> irHandlerClass = Class.forName(className);
+				if (ProtectedItemRemoveHandler.class.isAssignableFrom(irHandlerClass)) {
+					irHandler = (ProtectedItemRemoveHandler) irHandlerClass.newInstance();
+				}
+			}
         } catch (ClassNotFoundException e) {
             log.error(e.getMessage(), e);
         } catch (InstantiationException e) {
@@ -100,6 +94,12 @@ public class ProtectedRemoveManager {
         } catch (IllegalAccessException e) {
             log.error(e.getMessage(), e);
         }
-        return null;
+        return irHandler;
     }
+    
+    void addHandler(ProtectedItemRemoveHandler instance) {
+		if (instance != null) {
+			handlers.add(instance);
+		}
+	}
 }
diff --git a/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
index bb6bc32..05db010 100644
--- a/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
+++ b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
@@ -33,6 +33,7 @@ public class TestAll extends TestCase {
         TestSuite suite = new TestSuite("org.apache.jackrabbit.server.remoting.davex tests");
 
         suite.addTestSuite(DiffParserTest.class);
+        suite.addTestSuite(JsonDiffHandlerImportTest.class);
         suite.addTestSuite(JsonDiffHandlerTest.class);
         suite.addTestSuite(BatchReadConfigTest.class);
 
diff --git a/jackrabbit-jcr-server/src/test/resources/protectedHandlersConfig.xml b/jackrabbit-jcr-server/src/test/resources/protectedHandlersConfig.xml
new file mode 100644
index 0000000..7491f63
--- /dev/null
+++ b/jackrabbit-jcr-server/src/test/resources/protectedHandlersConfig.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<config>
+    <!--
+     Defines the ProtectedItemRemoveHandler implementation(s) responsible for removing
+     protected items using the JCR server.
+    -->
+       <protecteditemremovehandler>
+            <class name="org.apache.jackrabbit.server.remoting.davex.AclRemoveHandler" />
+       </protecteditemremovehandler>
+</config>
\ No newline at end of file
diff --git a/jackrabbit-jcr2dav/src/test/resources/protectedHandlersConfig.xml b/jackrabbit-jcr2dav/src/test/resources/protectedHandlersConfig.xml
new file mode 100644
index 0000000..7491f63
--- /dev/null
+++ b/jackrabbit-jcr2dav/src/test/resources/protectedHandlersConfig.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<config>
+    <!--
+     Defines the ProtectedItemRemoveHandler implementation(s) responsible for removing
+     protected items using the JCR server.
+    -->
+       <protecteditemremovehandler>
+            <class name="org.apache.jackrabbit.server.remoting.davex.AclRemoveHandler" />
+       </protecteditemremovehandler>
+</config>
\ No newline at end of file
diff --git a/jackrabbit-webapp/src/main/webapp/WEB-INF/web.xml b/jackrabbit-webapp/src/main/webapp/WEB-INF/web.xml
index cb1863b..bfcf019 100644
--- a/jackrabbit-webapp/src/main/webapp/WEB-INF/web.xml
+++ b/jackrabbit-webapp/src/main/webapp/WEB-INF/web.xml
@@ -334,7 +334,7 @@
         </init-param>
         <init-param>
           <param-name>protectedhandlers-config</param-name>
-          <param-value>/WEB-INF/protectedHandlers.properties</param-value>
+          <param-value>/WEB-INF/protectedHandlersConfig.xml</param-value>
           <description>JcrRemotingServlet: Handlers for removing protected items.</description>
         </init-param>
         <!-- init-param>
