incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r967128 - in /sling/trunk/contrib/extensions/bgservlets: ./ src/main/java/org/apache/sling/bgservlets/ src/main/java/org/apache/sling/bgservlets/impl/ src/main/java/org/apache/sling/bgservlets/impl/nodestream/ src/main/java/org/apache/sling...
Date Fri, 23 Jul 2010 15:18:23 GMT
Author: bdelacretaz
Date: Fri Jul 23 15:18:22 2010
New Revision: 967128

URL: http://svn.apache.org/viewvc?rev=967128&view=rev
Log:
SLING-550 - refactored job data storage

Added:
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/main/resources/
    sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/
    sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/
    sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
  (with props)
    sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
  (with props)
Modified:
    sling/trunk/contrib/extensions/bgservlets/pom.xml
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
    sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java

Modified: sling/trunk/contrib/extensions/bgservlets/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/pom.xml (original)
+++ sling/trunk/contrib/extensions/bgservlets/pom.xml Fri Jul 23 15:18:22 2010
@@ -57,6 +57,7 @@
             <Private-Package>org.apache.sling.bgservlets.impl.*</Private-Package>
             <DynamicImport-Package>org.apache.felix.webconsole</DynamicImport-Package>
             <Bundle-Activator>org.apache.sling.bgservlets.impl.Activator</Bundle-Activator>
+            <Sling-Nodetypes>SLING-INF/nodetypes/jobdata.cnd</Sling-Nodetypes>
         
           </instructions>
         </configuration>
       </plugin>

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,43 @@
+/*
+ * 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.bgservlets;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/** Wraps a JCR Node to store and retrieve information
+ * 	about a background Job
+ */
+public interface JobData {
+    String JOB_DATA_MIXIN = "sling:bgJobData";
+    
+	/** Return unique path of this data item */
+	String getPath();
+	
+	/** OutputStream used to write the job's output,
+	 * 	stored permanently under the job node. 
+	 */
+	OutputStream getOutputStream();
+	
+	/** Input stream used to replay data stored
+	 * 	in the stream provided by {#link getOutputStream}
+	 *  @return null if no stream stored yet
+	 */
+	InputStream getInputStream();
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
Fri Jul 23 15:18:22 2010
@@ -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.sling.bgservlets;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+/** Store and retrieve job data persistently */
+public interface JobStorage {
+	/** Create a JobData object for a new job */
+	JobData createJobData(Session s);
+	
+	/** Retrieve an existing JobData object */
+	JobData getJobData(Node ns);
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
(original)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
Fri Jul 23 15:18:22 2010
@@ -20,8 +20,6 @@ package org.apache.sling.bgservlets.impl
 
 import java.io.IOException;
 
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -31,8 +29,9 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.bgservlets.BackgroundHttpServletRequest;
 import org.apache.sling.bgservlets.BackgroundHttpServletResponse;
+import org.apache.sling.bgservlets.JobData;
 import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream;
+import org.apache.sling.bgservlets.JobStorage;
 import org.apache.sling.commons.auth.spi.AuthenticationInfo;
 import org.apache.sling.engine.SlingServlet;
 import org.slf4j.Logger;
@@ -52,14 +51,13 @@ class BackgroundRequestExecutionJob impl
     private final String path;
 
     BackgroundRequestExecutionJob(SlingServlet slingServlet,
-            ResourceResolverFactory rrf, HttpServletRequest request,
+            ResourceResolverFactory rrf, JobStorage storage, HttpServletRequest request,
             HttpServletResponse hsr, String[] parametersToRemove)
             throws IOException, LoginException {
         this.request = new BackgroundHttpServletRequest(request,
                 parametersToRemove);
         this.slingServlet = slingServlet;
 
-        // TODO we might
         // In a normal request the ResourceResolver is added to the request
         // attributes
         // by the authentication service, need to do the same here as we can't
@@ -72,31 +70,16 @@ class BackgroundRequestExecutionJob impl
                     "Missing AuthenticationInfo attribute");
         }
         resourceResolver = rrf.getResourceResolver(aa);
-        
-        // Save servlet output to the repository
+
+        // Get JobData, defines path and used to save servlet output to the repository
         final Session s = resourceResolver.adaptTo(Session.class);
         if(s == null) {
             throw new IOException("Unable to get Session from ResourceResolver " + resourceResolver);
         }
-        
-        // TODO configurable path
-        try {
-            final String outputRootPath = "/" + getClass().getSimpleName();
-            Node outputRoot = null;
-            if(s.itemExists(outputRootPath)) {
-                outputRoot = (Node)s.getItem(outputRootPath);
-            } else {
-                outputRoot = s.getRootNode().addNode(outputRootPath.substring(1));
-            }
-            final Node output = outputRoot.addNode("out_" + System.currentTimeMillis());
-            s.save();
-            final NodeOutputStream nos = new NodeOutputStream(output);
-            path = output.getPath();
-            stream = new SuspendableOutputStream(nos);
-            response = new BackgroundHttpServletResponse(hsr, stream);
-        } catch(RepositoryException re) {
-            throw new IOException("RepositoryException in BackgroundRequestExecutionJob",
re); 
-        }
+        final JobData d = storage.createJobData(s);
+        path = d.getPath();
+        stream = new SuspendableOutputStream(d.getOutputStream());
+        response = new BackgroundHttpServletResponse(hsr, stream);
     }
 
     public String toString() {

Modified: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
(original)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
Fri Jul 23 15:18:22 2010
@@ -37,6 +37,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.bgservlets.ExecutionEngine;
+import org.apache.sling.bgservlets.JobStorage;
 import org.apache.sling.engine.SlingServlet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +64,9 @@ public class BackgroundServletStarterFil
 
     @Reference
     private ResourceResolverFactory resourceResolverFactory;
+    
+    @Reference
+    private JobStorage jobStorage;
 
     /**
      * Request runs in the background if this request parameter is present TODO
@@ -91,8 +95,8 @@ public class BackgroundServletStarterFil
         if (Boolean.valueOf(bgParam)) {
             try {
                 final BackgroundRequestExecutionJob job = new BackgroundRequestExecutionJob(
-                        slingServlet, resourceResolverFactory, request,
-                        response, PARAM_TO_REMOVE);
+                        slingServlet, resourceResolverFactory, jobStorage,
+                        request, response, PARAM_TO_REMOVE);
                 log.debug("{} parameter true, running request in the background ({})",
                         BG_PARAM, job);
                 if (slingRequest != null) {

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,76 @@
+/*
+ * 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.bgservlets.impl;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+/**
+ * Deep-creation of nodes: parent nodes are created if needed.
+ * TOO replace with the version of JCR-2687 once that's released.
+ */
+public class DeepNodeCreator {
+    
+    /** Create a node, also creating parent nodes as needed
+     * @param path Path of the node to create
+     * @param session Used to create nodes
+     * @param nodeType Node type of created nodes, can be
+     *  overridden via {@link #getNodeType}
+     * @return The created node
+     * @throws RepositoryException In case of problems
+     */
+    public Node deepCreateNode(String path, Session session, String nodeType) 
+    throws RepositoryException {
+        Node result = null;
+        if (session.itemExists(path)) {
+            final Item it = session.getItem(path);
+            if (it.isNode()) {
+                result = (Node) it;
+            }
+        } else {
+            final int slashPos = path.lastIndexOf("/");
+            String parentPath = path.substring(0, slashPos);
+            if(parentPath.length() == 0) {
+                parentPath = "/";
+            }
+            final String childPath = path.substring(slashPos + 1);
+            final Node parent = deepCreateNode(parentPath, session, nodeType);
+            result = parent.addNode(childPath, getNodeType(parent, childPath, nodeType));
+            nodeCreated(result);
+            session.save();
+        }
+        return result;
+    }
+    
+    /** Can be overridden to return a specific nodetype to use at a given path.
+     *  @param parent the parent of the node that is being created
+     *  @param childPath the path of the child that is being created
+     *  @param suggestedNodeType the nodeType value passed to {@link deepCreateNode}
+     *  @return suggestedNodeType by default
+     */
+    protected String getNodeType(Node parent, String childPath, String suggestedNodeType)

+    throws RepositoryException {
+        return suggestedNodeType;
+    }
+    
+    /** Can be overridden to customize the created nodes, add mixins etc. */
+    protected void nodeCreated(Node n) throws RepositoryException {
+    }
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
(original)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
Fri Jul 23 15:18:22 2010
@@ -19,6 +19,7 @@
 package org.apache.sling.bgservlets.impl;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 
 import javax.jcr.Node;
@@ -28,11 +29,13 @@ import javax.servlet.http.HttpServletRes
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
-import org.apache.sling.bgservlets.impl.nodestream.NodeInputStream;
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobStorage;
 
 /** Servlet that replays the output of servlets executed in
  *  the background.
@@ -46,6 +49,9 @@ import org.apache.sling.bgservlets.impl.
 })
 public class OutputReplayServlet extends SlingSafeMethodsServlet {
 
+    @Reference
+    private JobStorage jobStorage;
+    
     @Override
     protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)

     throws ServletException, IOException {
@@ -55,19 +61,20 @@ public class OutputReplayServlet extends
                     "Resource does not adapt to a Node: " + request.getResource().getPath());
         }
         
-        // TODO content-type, length etc
-        final NodeInputStream nis = new NodeInputStream(n);
+        // TODO content-type, length etc.
+        final JobData d = jobStorage.getJobData(n); 
+        final InputStream is = d.getInputStream();
         try {
             final OutputStream os = response.getOutputStream();
             final byte [] buffer = new byte[32768];
             int count = 0;
-            while((count = nis.read(buffer, 0, buffer.length)) > 0) {
+            while((count = is.read(buffer, 0, buffer.length)) > 0) {
                 os.write(buffer, 0, count);
             }
             os.flush();
         } finally {
-            if(nis != null) {
-                nis.close();
+            if(is != null) {
+                is.close();
             }
         }
     }

Modified: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
(original)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
Fri Jul 23 15:18:22 2010
@@ -54,6 +54,7 @@ public class NodeInputStream extends Inp
     /** Select next property to read from and open its stream */
     private void selectNextStream() throws IOException {
         counter++;
+        // TODO use hierarchy to allow for arbitrary number of flush calls
         final String name = NodeOutputStream.STREAM_PROPERTY_NAME_PREFIX + counter;
         try {
             if(node.hasProperty(name)) {

Modified: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
(original)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
Fri Jul 23 15:18:22 2010
@@ -80,6 +80,7 @@ public class NodeOutputStream extends Ou
     @Override
     public void flush() throws IOException {
         counter++;
+        // TODO use hierarchy to allow for arbitrary number of flush calls
         final String name = NodeOutputStream.STREAM_PROPERTY_NAME_PREFIX + counter;
         try {
             if(!node.getSession().isLive()) {

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.bgservlets.impl.storage;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.impl.nodestream.NodeInputStream;
+import org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream;
+
+class JobDataImpl implements JobData {
+
+	private final Node node;
+	private final String path;
+	
+	public static final String STREAM_PATH = "outputStream";
+	
+	/** Build a JobDataImpl on supplied node, which must exists */
+	JobDataImpl(Node n) throws RepositoryException {
+		node = n;
+		path = n.getPath();
+	}
+	
+	public InputStream getInputStream() {
+        try {
+    		if(node.hasNode(STREAM_PATH)) {
+    		    return new NodeInputStream(node.getNode(STREAM_PATH));
+    		}
+	    } catch(Exception e) {
+	        throw new JobStorageException("Exception in getInputStream()", e);
+	    }
+		return null;
+	}
+
+	public OutputStream getOutputStream() {
+        try {
+            if(node.hasNode(STREAM_PATH)) {
+                throw new IllegalArgumentException("Stream node already exists: " 
+                        + node.getPath() + "/" + STREAM_PATH);
+            }
+            final Node stream = node.addNode(STREAM_PATH);
+            node.save();
+            return new NodeOutputStream(stream);
+        } catch(Exception e) {
+            throw new JobStorageException("Exception in getOutputStream()", e);
+        }
+	}
+
+	public String getPath() {
+		return path;
+	}
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,35 @@
+/*
+ * 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.bgservlets.impl.storage;
+
+import org.apache.sling.api.SlingException;
+
+/** Exception thrown by this package. Unchecked, meant
+ * 	for non-recoverable problems.
+ */
+@SuppressWarnings("serial")
+class JobStorageException extends SlingException {
+	public JobStorageException(String reason) {
+		super(reason);
+	}
+	
+	public JobStorageException(String reason, Throwable cause) {
+		super(reason, cause);
+	}
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,80 @@
+/*
+ * 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.bgservlets.impl.storage;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobStorage;
+import org.apache.sling.bgservlets.impl.DeepNodeCreator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Default JobStorage implementation */
+@Component
+@Service
+public class JobStorageImpl implements JobStorage {
+
+    private Logger log = LoggerFactory.getLogger(getClass());
+    
+    /** TODO configurable */
+    public static final String JOBS_PATH = "/var/bg/jobs"; 
+    public static final String PATH_FORMAT = "/yyyy/MM/dd/HH/mm";
+    public static final String JOB_NODETYPE = "nt:unstructured";
+    
+	private int counter;
+	private static final DateFormat pathFormat = new SimpleDateFormat(PATH_FORMAT);
+	
+	public JobData createJobData(Session s) {
+        try {
+            return getJobData(createNewJobNode(s));
+        } catch(Exception e) {
+            throw new JobStorageException("Unable to create new JobDataImpl", e);
+        }
+	}
+
+	public JobData getJobData(Node n) {
+        try {
+            return new JobDataImpl(n);
+        } catch(Exception e) {
+            throw new JobStorageException("Unable to create JobDataImpl", e);
+        }
+	}
+
+	Node createNewJobNode(Session s) throws RepositoryException {
+	    String path = null;
+	    synchronized (this) {
+	        counter++;
+	        path = JOBS_PATH + pathFormat.format(new Date()) + "/" + counter;
+        }
+	    final Node result = new DeepNodeCreator().deepCreateNode(path, s, JOB_NODETYPE);
+	    result.addMixin(JobData.JOB_DATA_MIXIN);
+	    result.save();
+	    log.debug("Job node {} created", result.getPath());
+	    return result;
+	}
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,25 @@
+//
+//  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.
+//
+
+<sling = 'http://sling.apache.org/jcr/sling/1.0'>
+
+//-----------------------------------------------------------------------------
+// Marker mixin node type for Sling JobData nodes
+[sling:bgJobData]
+    mixin

Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java?rev=967128&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
(added)
+++ sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,161 @@
+/*
+ * 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.bgservlets.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.junit.Test;
+
+/** Test the DeepNodeCreator class 
+ * TOO replace with the version of JCR-2687 once that's released.
+ * */
+public class DeepNodeCreatorTest {
+
+    @Test
+    public void testExistingNode() throws Exception {
+        final Mockery mockery = new Mockery(); 
+        final DeepNodeCreator c = new DeepNodeCreator();
+        final String path = "/foo/bar";
+        final Session s = mockery.mock(Session.class);
+        final Node n = mockery.mock(Node.class);
+        
+        mockery.checking(new Expectations() {{
+            allowing(s).itemExists(path);
+            will(returnValue(true));
+
+            allowing(s).getItem(path);
+            will(returnValue(n));
+            
+            allowing(n).isNode();
+            will(returnValue(true));
+        }});
+
+        final Node result = c.deepCreateNode(path, s, null);
+        assertTrue("Expecting deepCreate to return existing node", result == n);
+    }
+    
+    public void testCreateFromRoot() throws Exception {
+        final Mockery mockery = new Mockery(); 
+        final DeepNodeCreator c = new DeepNodeCreator();
+        final String rootPath = "/";
+        final String fooPath = "/foo";
+        final String barPath = "/foo/bar";
+        final Session s = mockery.mock(Session.class);
+        final Node root = mockery.mock(Node.class, rootPath);
+        final Node foo = mockery.mock(Node.class, fooPath);
+        final Node bar = mockery.mock(Node.class, barPath);
+        final String testNodeType = "NT_TEST";
+        
+        mockery.checking(new Expectations() {{
+            allowing(s).itemExists(barPath);
+            will(returnValue(false));
+
+            allowing(s).itemExists(fooPath);
+            will(returnValue(false));
+
+            allowing(s).itemExists(rootPath);
+            will(returnValue(true));
+
+            allowing(s).getItem(rootPath);
+            will(returnValue(root));
+            
+            allowing(root).isNode();
+            will(returnValue(true));
+            
+            allowing(root).addNode("foo", testNodeType);
+            will(returnValue(foo));
+            
+            allowing(foo).addNode("bar", testNodeType);
+            will(returnValue(bar));
+            
+            allowing(s).save();
+        }});
+        
+        final Node result = c.deepCreateNode(barPath, s, testNodeType);
+        assertTrue("Expecting deepCreate to return create node", result == bar);
+    }
+    
+    public void testCreateWithVariousTypes() throws Exception {
+        final Mockery mockery = new Mockery();
+        
+        final String fooPath = "/foo";
+        final String barPath = "/foo/bar";
+        final String wiiPath = "/foo/bar/wii";
+        final Session s = mockery.mock(Session.class);
+        final Node foo = mockery.mock(Node.class, fooPath);
+        final Node bar = mockery.mock(Node.class, barPath);
+        final Node wii = mockery.mock(Node.class, wiiPath);
+        
+        mockery.checking(new Expectations() {{
+            allowing(s).itemExists(wiiPath);
+            will(returnValue(false));
+
+            allowing(s).itemExists(barPath);
+            will(returnValue(false));
+
+            allowing(s).itemExists(fooPath);
+            will(returnValue(true));
+
+            allowing(s).getItem(fooPath);
+            will(returnValue(foo));
+            
+            allowing(foo).isNode();
+            will(returnValue(true));
+            
+            allowing(foo).getPath();
+            will(returnValue(fooPath));
+            
+            allowing(foo).addNode("bar", "NT_/foo.bar");
+            will(returnValue(bar));
+            
+            allowing(bar).getPath();
+            will(returnValue(barPath));
+            
+            allowing(bar).addNode("wii", "NT_/foo/bar.wii");
+            will(returnValue(wii));
+            
+            allowing(s).save();
+        }});
+        
+        final AtomicInteger counter = new AtomicInteger();
+        final DeepNodeCreator c = new DeepNodeCreator() {
+
+            @Override
+            protected String getNodeType(Node parent, String childPath, String suggestedNodeType)

+            throws RepositoryException {
+                return "NT_" + parent.getPath() + "." + childPath;
+            }
+
+            @Override
+            protected void nodeCreated(Node n) throws RepositoryException {
+                counter.addAndGet(1);
+            }
+        };
+        final Node result = c.deepCreateNode(wiiPath, s, null);
+        assertTrue("Expecting deepCreate to return created node", result == wii);
+        assertEquals("Expecting correct count of nodeCreated calls", 2, counter.get());
+    }
+}

Propchange: sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message