You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2010/04/27 17:28:13 UTC

svn commit: r938519 - in /sling/trunk/bundles/servlets/post: ./ src/main/java/org/apache/sling/servlets/post/ src/main/java/org/apache/sling/servlets/post/impl/ src/main/java/org/apache/sling/servlets/post/impl/helper/ src/main/java/org/apache/sling/se...

Author: justin
Date: Tue Apr 27 15:28:13 2010
New Revision: 938519

URL: http://svn.apache.org/viewvc?rev=938519&view=rev
Log:
SLING-1504 - making NodeNameGenerator pluggable

Added:
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java
      - copied, changed from r938518, sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameGenerator.java
Removed:
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameGenerator.java
Modified:
    sling/trunk/bundles/servlets/post/pom.xml
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java

Modified: sling/trunk/bundles/servlets/post/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/pom.xml?rev=938519&r1=938518&r2=938519&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/pom.xml (original)
+++ sling/trunk/bundles/servlets/post/pom.xml Tue Apr 27 15:28:13 2010
@@ -55,7 +55,7 @@
                 <configuration>
                     <instructions>
                         <Export-Package>
-                            org.apache.sling.servlets.post;version=2.0.4.incubator
+                            org.apache.sling.servlets.post;version=2.0.6
                         </Export-Package>
                         <Private-Package>
                             org.apache.sling.servlets.post.impl.*

Added: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java?rev=938519&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java (added)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java Tue Apr 27 15:28:13 2010
@@ -0,0 +1,37 @@
+/*
+ * 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.sling.servlets.post;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+
+/**
+ * Service interface which allows for custom node name generation for * resources.
+ *
+ */
+public interface NodeNameGenerator {
+
+    /**
+     * Get the to-be-created node name from the request.
+     *
+     * @param req request
+     * @param parentPath the path to the new node's parent
+     * @param requirePrefix if true, ignore parameters which do not being with ./
+     * @param defaultNodeNameGenerator the default node name generator
+     */
+    public String getNodeName(SlingHttpServletRequest request, String parentPath, boolean requirePrefix,
+            NodeNameGenerator defaultNodeNameGenerator);
+}

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java?rev=938519&r1=938518&r2=938519&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java Tue Apr 27 15:28:13 2010
@@ -22,6 +22,7 @@ import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -37,9 +38,10 @@ import org.apache.sling.servlets.post.Sl
 import org.apache.sling.servlets.post.SlingPostOperation;
 import org.apache.sling.servlets.post.SlingPostProcessor;
 import org.apache.sling.servlets.post.impl.helper.DateParser;
+import org.apache.sling.servlets.post.impl.helper.DefaultNodeNameGenerator;
 import org.apache.sling.servlets.post.impl.helper.JSONResponse;
 import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
-import org.apache.sling.servlets.post.impl.helper.NodeNameGenerator;
+import org.apache.sling.servlets.post.NodeNameGenerator;
 import org.apache.sling.servlets.post.impl.operations.CopyOperation;
 import org.apache.sling.servlets.post.impl.operations.DeleteOperation;
 import org.apache.sling.servlets.post.impl.operations.ModifyOperation;
@@ -76,6 +78,10 @@ import org.slf4j.LoggerFactory;
  * 					interface="org.apache.sling.servlets.post.SlingPostOperation"
  * 					cardinality="0..n"
  * 					policy="dynamic"
+ * @scr.reference name="nodeNameGenerator"
+ *                  interface="org.apache.sling.servlets.post.NodeNameGenerator"
+ *                  cardinality="0..n"
+ *                  policy="dynamic"
  */
 public class SlingPostServlet extends SlingAllMethodsServlet {
 
@@ -108,16 +114,11 @@ public class SlingPostServlet extends Sl
     private static final String PROP_NODE_NAME_MAX_LENGTH = "servlet.post.nodeNameMaxLength";
 
     /**
-     * utility class for generating node names
-     */
-    private NodeNameGenerator nodeNameGenerator;
-
-    /**
      * utility class for parsing date strings
      */
     private DateParser dateParser;
 
-    private SlingPostOperation modifyOperation;
+    private ModifyOperation modifyOperation;
 
     private final List<ServiceReference> delayedPostOperations = new ArrayList<ServiceReference>();
 
@@ -129,13 +130,22 @@ public class SlingPostServlet extends Sl
 
     private SlingPostProcessor[] cachedPostProcessors = new SlingPostProcessor[0];
 
+    private final List<ServiceReference> delayedNodeNameGenerators = new ArrayList<ServiceReference>();
+
+    private final List<ServiceReference> nodeNameGenerators = new ArrayList<ServiceReference>();
+
+    private NodeNameGenerator[] cachedNodeNameGenerators = new NodeNameGenerator[0];
+
     private ComponentContext componentContext;
 
+    private NodeNameGenerator defaultNodeNameGenerator;
+
     @Override
     public void init() {
         // default operation: create/modify
-        modifyOperation = new ModifyOperation(nodeNameGenerator, dateParser,
+        modifyOperation = new ModifyOperation(defaultNodeNameGenerator, dateParser,
             getServletContext());
+        modifyOperation.setExtraNodeNameGenerators(cachedNodeNameGenerators);
 
         // other predefined operations
         postOperations.put(SlingPostConstants.OPERATION_COPY,
@@ -329,7 +339,7 @@ public class SlingPostServlet extends Sl
         String[] nameHints = OsgiUtil.toStringArray(props.get(PROP_NODE_NAME_HINT_PROPERTIES));
         int nameMax = (int) OsgiUtil.toLong(
             props.get(PROP_NODE_NAME_MAX_LENGTH), -1);
-        nodeNameGenerator = new NodeNameGenerator(nameHints, nameMax);
+        defaultNodeNameGenerator = new DefaultNodeNameGenerator(nameHints, nameMax);
 
         dateParser = new DateParser();
         String[] dateFormats = OsgiUtil.toStringArray(props.get(PROP_DATE_FORMAT));
@@ -342,10 +352,16 @@ public class SlingPostServlet extends Sl
                     dateFormat, t);
             }
         }
+
+        synchronized ( this.delayedNodeNameGenerators ) {
+            for(final ServiceReference ref : this.delayedNodeNameGenerators) {
+                this.registerNodeNameGenerator(ref);
+            }
+            this.delayedNodeNameGenerators.clear();
+        }
     }
 
     protected void deactivate(ComponentContext context) {
-        nodeNameGenerator = null;
         dateParser = null;
         this.componentContext = null;
     }
@@ -425,4 +441,54 @@ public class SlingPostServlet extends Sl
             }
         }
     }
+
+    protected void bindNodeNameGenerator(ServiceReference ref) {
+        synchronized ( this.delayedNodeNameGenerators ) {
+            if ( this.componentContext == null ) {
+                this.delayedNodeNameGenerators.add(ref);
+            } else {
+                this.registerNodeNameGenerator(ref);
+            }
+        }
+    }
+
+    protected void unbindNodeNameGenerator(ServiceReference ref) {
+        synchronized ( this.delayedNodeNameGenerators ) {
+            this.delayedNodeNameGenerators.remove(ref);
+            this.nodeNameGenerators.remove(ref);
+        }
+    }
+
+    protected void registerNodeNameGenerator(ServiceReference ref) {
+        final int ranking = OsgiUtil.toInteger(ref.getProperty(Constants.SERVICE_RANKING), 0);
+        int index = 0;
+        while ( index < this.nodeNameGenerators.size() &&
+                ranking < OsgiUtil.toInteger(this.nodeNameGenerators.get(index).getProperty(Constants.SERVICE_RANKING), 0)) {
+            index++;
+        }
+        if ( index == this.nodeNameGenerators.size() ) {
+            this.nodeNameGenerators.add(ref);
+        } else {
+            this.nodeNameGenerators.add(index, ref);
+        }
+        this.cachedNodeNameGenerators = new NodeNameGenerator[this.nodeNameGenerators.size()];
+        index = 0;
+        for(final ServiceReference current : this.nodeNameGenerators) {
+            final NodeNameGenerator generator = (NodeNameGenerator) this.componentContext.locateService("nodeNameGenerator", current);
+            if ( generator != null ) {
+                this.cachedNodeNameGenerators[index] = generator;
+                index++;
+            }
+        }
+        if ( index < this.cachedNodeNameGenerators.length ) {
+            NodeNameGenerator[] oldArray = this.cachedNodeNameGenerators;
+            this.cachedNodeNameGenerators = new NodeNameGenerator[index];
+            for(int i=0;i<index;i++) {
+                this.cachedNodeNameGenerators[i] = oldArray[i];
+            }
+        }
+        if(this.modifyOperation != null) {
+            this.modifyOperation.setExtraNodeNameGenerators(this.cachedNodeNameGenerators);
+        }
+    }
 }

Copied: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java (from r938518, sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameGenerator.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java?p2=sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java&p1=sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameGenerator.java&r1=938518&r2=938519&rev=938519&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameGenerator.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java Tue Apr 27 15:28:13 2010
@@ -16,8 +16,10 @@
  */
 package org.apache.sling.servlets.post.impl.helper;
 
+import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.request.RequestParameter;
 import org.apache.sling.api.request.RequestParameterMap;
+import org.apache.sling.servlets.post.NodeNameGenerator;
 import org.apache.sling.servlets.post.SlingPostConstants;
 
 /**
@@ -25,7 +27,7 @@ import org.apache.sling.servlets.post.Sl
  * like title, description, etc.
  * See SLING-128.
  */
-public class NodeNameGenerator {
+public class DefaultNodeNameGenerator implements NodeNameGenerator {
 
     private final String[] parameterNames;
     private final NodeNameFilter filter = new NodeNameFilter();
@@ -35,7 +37,7 @@ public class NodeNameGenerator {
     private int maxLength = DEFAULT_MAX_NAME_LENGTH;
     private int counter;
 
-    public NodeNameGenerator(String[] parameterNames, int maxNameLength) {
+    public DefaultNodeNameGenerator(String[] parameterNames, int maxNameLength) {
         if (parameterNames == null) {
             this.parameterNames = new String[0];
         } else {
@@ -50,13 +52,16 @@ public class NodeNameGenerator {
     /**
      * Get a "nice" node name, if possible, based on given request
      *
-     * @param parameters the request parameters
+     * @param request the request
+     * @param basePath the base path
      * @param requirePrefix <code>true</code> if the parameter names for
      *      properties requires a prefix
+     * @param defaultNodeNameGenerator a default generator
      * @return a nice node name
      */
-    public String getNodeName(RequestParameterMap parameters,
-            boolean requirePrefix) {
+    public String getNodeName(SlingHttpServletRequest request, String basePath,
+            boolean requirePrefix, NodeNameGenerator defaultNodeNameGenerator) {
+        RequestParameterMap parameters = request.getRequestParameterMap();
         String valueToUse = null;
         boolean doFilter = true;
 

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java?rev=938519&r1=938518&r2=938519&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java Tue Apr 27 15:28:13 2010
@@ -44,7 +44,7 @@ import org.apache.sling.servlets.post.Ab
 import org.apache.sling.servlets.post.Modification;
 import org.apache.sling.servlets.post.SlingPostConstants;
 import org.apache.sling.servlets.post.impl.helper.DateParser;
-import org.apache.sling.servlets.post.impl.helper.NodeNameGenerator;
+import org.apache.sling.servlets.post.NodeNameGenerator;
 import org.apache.sling.servlets.post.impl.helper.ReferenceParser;
 import org.apache.sling.servlets.post.impl.helper.RequestProperty;
 import org.apache.sling.servlets.post.impl.helper.SlingFileUploadHandler;
@@ -58,9 +58,14 @@ import org.apache.sling.servlets.post.im
 public class ModifyOperation extends AbstractSlingPostOperation {
 
     /**
+     * The default node name generator
+     */
+    private final NodeNameGenerator defaultNodeNameGenerator;
+
+    /**
      * utility class for generating node names
      */
-    private final NodeNameGenerator nodeNameGenerator;
+    private NodeNameGenerator[] extraNodeNameGenerators;
 
     private final DateParser dateParser;
 
@@ -69,13 +74,17 @@ public class ModifyOperation extends Abs
      */
     private final SlingFileUploadHandler uploadHandler;
 
-    public ModifyOperation(NodeNameGenerator nodeNameGenerator,
+    public ModifyOperation(NodeNameGenerator defaultNodeNameGenerator,
             DateParser dateParser, ServletContext servletContext) {
-        this.nodeNameGenerator = nodeNameGenerator;
+        this.defaultNodeNameGenerator = defaultNodeNameGenerator;
         this.dateParser = dateParser;
         this.uploadHandler = new SlingFileUploadHandler(servletContext);
     }
 
+    public void setExtraNodeNameGenerators(NodeNameGenerator[] extraNodeNameGenerators) {
+        this.extraNodeNameGenerators = extraNodeNameGenerators;
+    }
+
     @Override
     protected void doRun(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes)
             throws RepositoryException {
@@ -170,12 +179,24 @@ public class ModifyOperation extends Abs
 
     private String generateName(SlingHttpServletRequest request, String basePath)
             throws RepositoryException {
+        boolean requirePrefix = requireItemPathPrefix(request);
+
+        String generatedName = null;
+        if (extraNodeNameGenerators != null) {
+            for (NodeNameGenerator generator : extraNodeNameGenerators) {
+                generatedName = generator.getNodeName(request, basePath, requirePrefix, defaultNodeNameGenerator);
+                if (generatedName != null) {
+                    break;
+                }
+            }
+        }
+        if (generatedName == null) {
+            generatedName = defaultNodeNameGenerator.getNodeName(request, basePath, requirePrefix, defaultNodeNameGenerator);
+        }
 
         // If the path ends with a *, create a node under its parent, with
         // a generated node name
-        basePath += "/"
-            + nodeNameGenerator.getNodeName(request.getRequestParameterMap(),
-                requireItemPathPrefix(request));
+        basePath += "/" + generatedName;
 
         // if resulting path exists, add a suffix until it's not the case
         // anymore