Author: cziegeler
Date: Fri May  5 09:22:56 2017
New Revision: 1793991

URL: http://svn.apache.org/viewvc?rev=1793991&view=rev
Log:
SLING-6782 : Sling Job implementation should avoid unnecessary writes to the 
repository. Apply patch from Jörg Hoh. Modified the patch to be able to remove 
duplicate code from ResourceUtil

Modified:
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java
    
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java
 Fri May  5 09:22:56 2017
@@ -26,6 +26,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 /**
  * Environment component. This component provides "global settings"
@@ -45,11 +46,11 @@ public class EnvironmentComponent {
     /**
      * Our thread pool.
      */
-    @Reference(service=EventingThreadPool.class)
+    @Reference(service=EventingThreadPool.class, 
policyOption=ReferencePolicyOption.GREEDY)
     private ThreadPool threadPool;
 
     /** Sling settings service. */
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private SlingSettingsService settingsService;
 
     /**

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java
 Fri May  5 09:22:56 2017
@@ -29,6 +29,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -57,7 +58,7 @@ public class EventingThreadPool implemen
         int minPoolSize() default 35;
     }
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private ThreadPoolManager threadPoolManager;
 
     /** The real thread pool used. */

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
 Fri May  5 09:22:56 2017
@@ -124,7 +124,7 @@ public class JobHandler {
                     if ( keepJobInHistory ) {
                         final ValueMap vm = 
ResourceHelper.getValueMap(jobResource);
                         newPath = 
this.configuration.getStoragePath(job.getTopic(), job.getId(), isSuccess);
-                        final Map<String, Object> props = new HashMap<String, 
Object>(vm);
+                        final Map<String, Object> props = new HashMap<>(vm);
                         props.put(JobImpl.PROPERTY_FINISHED_STATE, 
state.name());
                         if ( isSuccess ) {
                             // we set the finish date to start date + duration
@@ -181,7 +181,7 @@ public class JobHandler {
                     final ValueMap vm = 
ResourceHelper.getValueMap(jobResource);
                     final String newPath = 
this.configuration.getUniquePath(targetId, job.getTopic(), job.getId(), 
job.getProperties());
 
-                    final Map<String, Object> props = new HashMap<String, 
Object>(vm);
+                    final Map<String, Object> props = new HashMap<>(vm);
                     props.remove(Job.PROPERTY_JOB_QUEUE_NAME);
                     if ( targetId == null ) {
                         props.remove(Job.PROPERTY_JOB_TARGET_INSTANCE);

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
 Fri May  5 09:22:56 2017
@@ -66,6 +66,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
@@ -92,10 +93,10 @@ public class JobManagerImpl
     /** Default logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private EventAdmin eventAdmin;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private Scheduler scheduler;
 
     @Reference
@@ -104,7 +105,7 @@ public class JobManagerImpl
     @Reference
     private QueuesMBean queuesMBean;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private ThreadPoolManager threadPoolManager;
 
     /** The job manager configuration. */
@@ -637,7 +638,7 @@ public class JobManagerImpl
         if ( logger.isDebugEnabled() ) {
             logger.debug("Storing new job {} at {}", 
Utility.toString(jobTopic, properties), path);
         }
-        ResourceHelper.getOrCreateResource(resolver,
+        ResourceHelper.createAndCommitResource(resolver,
                 path,
                 properties);
 

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
 Fri May  5 09:22:56 2017
@@ -52,6 +52,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -156,16 +157,16 @@ public class JobManagerConfiguration {
     @Reference
     private EnvironmentComponent environment;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private ResourceResolverFactory resourceResolverFactory;
 
     @Reference
     private QueueConfigurationManager queueConfigManager;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private Scheduler scheduler;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private ServiceUserMapped serviceUserMapped;
 
     /** Is this still active? */

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java
 Fri May  5 09:22:56 2017
@@ -36,6 +36,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 import org.slf4j.Logger;
@@ -56,7 +57,7 @@ public class NewJobSender implements Res
     private JobManagerConfiguration configuration;
 
     /** The event admin. */
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private EventAdmin eventAdmin;
 
     /** Service registration for the event handler. */

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
 Fri May  5 09:22:56 2017
@@ -56,6 +56,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
@@ -81,7 +82,7 @@ public class QueueManager
     /** Default logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private EventAdmin eventAdmin;
 
     @Reference
@@ -90,7 +91,7 @@ public class QueueManager
     @Reference
     private QueuesMBean queuesMBean;
 
-    @Reference
+    @Reference(policyOption=ReferencePolicyOption.GREEDY)
     private ThreadPoolManager threadPoolManager;
 
     /**

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java
 Fri May  5 09:22:56 2017
@@ -277,7 +277,7 @@ public class ScheduledJobHandler impleme
             } else {
                 logger.debug("Storing new scheduled job {} at {}", properties, 
path);
             }
-            ResourceHelper.getOrCreateResource(resolver,
+            ResourceHelper.createAndCommitResource(resolver,
                     path,
                     properties);
             // put back real schedule infos

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
 Fri May  5 09:22:56 2017
@@ -140,7 +140,7 @@ public class CheckTopologyTask {
                                             final ValueMap vm = 
ResourceHelper.getValueMap(rsrc);
                                             final String targetId = 
caps.detectTarget(topicName, vm, info);
 
-                                            final Map<String, Object> props = 
new HashMap<String, Object>(vm);
+                                            final Map<String, Object> props = 
new HashMap<>(vm);
                                             
props.remove(Job.PROPERTY_JOB_STARTED_TIME);
 
                                             final String newPath;
@@ -251,7 +251,7 @@ public class CheckTopologyTask {
 
                             if ( targetId != null ) {
                                 final String newPath = 
configuration.getAssginedJobsPath() + '/' + targetId + '/' + 
topicResource.getName() + 
rsrc.getPath().substring(topicResource.getPath().length());
-                                final Map<String, Object> props = new 
HashMap<String, Object>(vm);
+                                final Map<String, Object> props = new 
HashMap<>(vm);
                                 props.put(Job.PROPERTY_JOB_QUEUE_NAME, 
info.queueName);
                                 props.put(Job.PROPERTY_JOB_TARGET_INSTANCE, 
targetId);
                                 props.remove(Job.PROPERTY_JOB_STARTED_TIME);
@@ -287,7 +287,7 @@ public class CheckTopologyTask {
                         try {
                             final ValueMap vm = 
ResourceHelper.getValueMap(rsrc);
                             final String newPath = 
configuration.getUnassignedJobsPath() + '/' + topicResource.getName() + 
rsrc.getPath().substring(topicResource.getPath().length());
-                            final Map<String, Object> props = new 
HashMap<String, Object>(vm);
+                            final Map<String, Object> props = new 
HashMap<>(vm);
                             props.remove(Job.PROPERTY_JOB_QUEUE_NAME);
                             props.remove(Job.PROPERTY_JOB_TARGET_INSTANCE);
                             props.remove(Job.PROPERTY_JOB_STARTED_TIME);

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java
 Fri May  5 09:22:56 2017
@@ -120,7 +120,7 @@ public class UpgradeTask {
                     final ValueMap vm = ResourceHelper.getValueMap(rsrc);
                     final String targetId = caps.detectTarget(topicName, vm, 
info);
 
-                    final Map<String, Object> props = new HashMap<String, 
Object>(vm);
+                    final Map<String, Object> props = new HashMap<>(vm);
                     final String newPath;
                     if ( targetId != null ) {
                         newPath = configuration.getAssginedJobsPath() + '/' + 
targetId + '/' + topicResource.getName() + 
rsrc.getPath().substring(topicResource.getPath().length());
@@ -198,7 +198,7 @@ public class UpgradeTask {
         try {
             final ValueMap vm = ResourceHelper.getValueMap(jobResource);
             // check for binary properties
-            Map<String, Object> binaryProperties = new HashMap<String, 
Object>();
+            Map<String, Object> binaryProperties = new HashMap<>();
             final ObjectInputStream ois = vm.get("slingevent:properties", 
ObjectInputStream.class);
             if ( ois != null ) {
                 try {

Modified: 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java?rev=1793991&r1=1793990&r2=1793991&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java
 (original)
+++ 
sling/trunk/bundles/extensions/event/resource/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java
 Fri May  5 09:22:56 2017
@@ -25,7 +25,6 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -173,17 +172,17 @@ public abstract class ResourceHelper {
     public static Map<String, Object> cloneValueMap(final ValueMap vm) throws 
InstantiationException {
         List<Exception> hasReadError = null;
         try {
-            final Map<String, Object> result = new HashMap<String, Object>(vm);
+            final Map<String, Object> result = new HashMap<>(vm);
             for(final Map.Entry<String, Object> entry : result.entrySet()) {
                 if ( entry.getKey().equals(PROPERTY_SCHEDULE_INFO) ) {
                     final String[] infoArray = vm.get(entry.getKey(), 
String[].class);
                     if ( infoArray == null || infoArray.length == 0 ) {
                         if ( hasReadError == null ) {
-                            hasReadError = new ArrayList<Exception>();
+                            hasReadError = new ArrayList<>();
                         }
                         hasReadError.add(new Exception("Unable to deserialize 
property '" + entry.getKey() + "' : " + entry.getValue()));
                     } else {
-                        final List<ScheduleInfo> infos = new 
ArrayList<ScheduleInfo>();
+                        final List<ScheduleInfo> infos = new ArrayList<>();
                         for(final String i : infoArray) {
                             final ScheduleInfoImpl info = 
ScheduleInfoImpl.deserialize(i);
                             if ( info != null ) {
@@ -192,7 +191,7 @@ public abstract class ResourceHelper {
                         }
                         if ( infos.size() < infoArray.length ) {
                             if ( hasReadError == null ) {
-                                hasReadError = new ArrayList<Exception>();
+                                hasReadError = new ArrayList<>();
                             }
                             hasReadError.add(new Exception("Unable to 
deserialize property '" + entry.getKey() + "' : " + 
Arrays.toString(infoArray)));
                         } else {
@@ -206,7 +205,7 @@ public abstract class ResourceHelper {
                         entry.setValue(value);
                     } else {
                         if ( hasReadError == null ) {
-                            hasReadError = new ArrayList<Exception>();
+                            hasReadError = new ArrayList<>();
                         }
                         // let's find out which class might be missing
                         ObjectInputStream ois = null;
@@ -256,171 +255,61 @@ public abstract class ResourceHelper {
     public static void getOrCreateBasePath(final ResourceResolver resolver,
             final String path)
     throws PersistenceException {
-       getOrCreateResource(resolver,
+        ResourceUtil.getOrCreateResource(resolver,
                         path,
                         ResourceHelper.RESOURCE_TYPE_FOLDER,
                         ResourceHelper.RESOURCE_TYPE_FOLDER,
                         true);
     }
 
-    public static Resource getOrCreateResource(final ResourceResolver resolver,
-            final String path, final Map<String, Object> props)
+    /**
+     * Create the resource and commit it
+     * @param resolver The resource resolver
+     * @param path The path of the resource
+     * @param props The properties
+     * @return The created resource
+     * @throws PersistenceException If something goes wrong
+     */
+    public static Resource createAndCommitResource(final ResourceResolver 
resolver,
+            final String path,
+            final Map<String, Object> props)
     throws PersistenceException {
-       return getOrCreateResource(resolver,
+       return ResourceUtil.getOrCreateResource(resolver,
                         path,
                         props,
                         ResourceHelper.RESOURCE_TYPE_FOLDER,
                         true);
     }
 
-    /**
-     * Creates or gets the resource at the given path.
-     * This is a copy of Sling's API ResourceUtil method to avoid a dependency 
on the latest
-     * Sling API version! We can remove this once we update to Sling API > 2.8
-     * @param resolver The resource resolver to use for creation
-     * @param path     The full path to be created
-     * @param resourceType The optional resource type of the final resource to 
create
-     * @param intermediateResourceType THe optional resource type of all 
intermediate resources
-     * @param autoCommit If set to true, a commit is performed after each 
resource creation.
-     */
-    private static Resource getOrCreateResource(
-                            final ResourceResolver resolver,
-                            final String path,
-                            final String resourceType,
-                            final String intermediateResourceType,
-                            final boolean autoCommit)
-    throws PersistenceException {
-        final Map<String, Object> props;
-        if ( resourceType == null ) {
-            props = null;
-        } else {
-            props = 
Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, 
(Object)resourceType);
-        }
-        return getOrCreateResource(resolver, path, props, 
intermediateResourceType, autoCommit);
-    }
 
     /**
      * Creates or gets the resource at the given path.
-     * If an exception occurs, it retries the operation up to five times if 
autoCommit is enabled.
-     * In this case, {@link ResourceResolver#revert()} is called on the 
resolver before the
-     * creation is retried.
-     * This is a copy of Sling's API ResourceUtil method to avoid a dependency 
on the latest
-     * Sling API version! We can remove this once we update to Sling API > 2.8
+     * If any resource along the parent path needs to be created,
+     * this is committed immediately. The resource itself is not committed.
+     * This is the task of the caller.
      *
      * @param resolver The resource resolver to use for creation
      * @param path     The full path to be created
-     * @param resourceProperties The optional resource properties of the final 
resource to create
-     * @param intermediateResourceType THe optional resource type of all 
intermediate resources
-     * @param autoCommit If set to true, a commit is performed after each 
resource creation.
+     * @param props    The properties of the new resource.
+     * @return The resource for the path.
+     * @throws PersistenceException If something goes wrong
      */
-    private static Resource getOrCreateResource(
-            final ResourceResolver resolver,
+    public static Resource getOrCreateResource(final ResourceResolver resolver,
             final String path,
-            final Map<String, Object> resourceProperties,
-            final String intermediateResourceType,
-            final boolean autoCommit)
+            final Map<String, Object> props)
     throws PersistenceException {
-        PersistenceException mostRecentPE = null;
-        for(int i=0;i<5;i++) {
-            try {
-                return getOrCreateResourceInternal(resolver,
+        // create parent path with auto commit set to true
+        final String parentPath = ResourceUtil.getParent(path);
+        ResourceUtil.getOrCreateResource(resolver,
+                parentPath,
+                ResourceHelper.RESOURCE_TYPE_FOLDER,
+                ResourceHelper.RESOURCE_TYPE_FOLDER,
+                true);
+        // now create resource itself
+        return ResourceUtil.getOrCreateResource(resolver,
                         path,
-                        resourceProperties,
-                        intermediateResourceType,
-                        autoCommit);
-            } catch ( final PersistenceException pe ) {
-                if ( autoCommit ) {
-                    // in case of exception, revert to last clean state and 
retry
-                    resolver.revert();
-                    resolver.refresh();
-                    mostRecentPE = pe;
-                } else {
-                    throw pe;
-                }
-            }
-        }
-        throw mostRecentPE;
-    }
-
-    /**
-     * Creates or gets the resource at the given path.
-     * This is a copy of Sling's API ResourceUtil method to avoid a dependency 
on the latest
-     * Sling API version! We can remove this once we update to Sling API > 2.8
-     *
-     * @param resolver The resource resolver to use for creation
-     * @param path     The full path to be created
-     * @param resourceProperties The optional resource properties of the final 
resource to create
-     * @param intermediateResourceType THe optional resource type of all 
intermediate resources
-     * @param autoCommit If set to true, a commit is performed after each 
resource creation.
-     */
-    private static Resource getOrCreateResourceInternal(
-            final ResourceResolver resolver,
-            final String path,
-            final Map<String, Object> resourceProperties,
-            final String intermediateResourceType,
-            final boolean autoCommit)
-    throws PersistenceException {
-        Resource rsrc = resolver.getResource(path);
-        if ( rsrc == null ) {
-            final int lastPos = path.lastIndexOf('/');
-            final String name = path.substring(lastPos + 1);
-
-            final Resource parentResource;
-            if ( lastPos == 0 ) {
-                parentResource = resolver.getResource("/");
-            } else {
-                final String parentPath = path.substring(0, lastPos);
-                parentResource = getOrCreateResource(resolver,
-                        parentPath,
-                        intermediateResourceType,
-                        intermediateResourceType,
-                        autoCommit);
-            }
-            if ( autoCommit ) {
-                resolver.refresh();
-            }
-            try {
-                int retry = 5;
-                while ( retry > 0 && rsrc == null ) {
-                    rsrc = resolver.create(parentResource, name, 
resourceProperties);
-                    // check for SNS
-                    if ( !name.equals(rsrc.getName()) ) {
-                        resolver.refresh();
-                        resolver.delete(rsrc);
-                        rsrc = resolver.getResource(parentResource, name);
-                    }
-                    retry--;
-                }
-                if ( rsrc == null ) {
-                    throw new PersistenceException("Unable to create 
resource.");
-                }
-            } catch ( final PersistenceException pe ) {
-                // this could be thrown because someone else tried to create 
this
-                // node concurrently
-                resolver.refresh();
-                rsrc = resolver.getResource(parentResource, name);
-                if ( rsrc == null ) {
-                    throw pe;
-                }
-            }
-            if ( autoCommit ) {
-                try {
-                    resolver.commit();
-                    resolver.refresh();
-                    rsrc = resolver.getResource(parentResource, name);
-                } catch ( final PersistenceException pe ) {
-                    // try again - maybe someone else did create the resource 
in the meantime
-                    // or we ran into Jackrabbit's stale item exception in a 
clustered environment
-                    resolver.revert();
-                    resolver.refresh();
-                    rsrc = resolver.getResource(parentResource, name);
-                    if ( rsrc == null ) {
-                        rsrc = resolver.create(parentResource, name, 
resourceProperties);
-                        resolver.commit();
-                    }
-                }
-            }
-        }
-        return rsrc;
+                        props,
+                        ResourceHelper.RESOURCE_TYPE_FOLDER,
+                        false);
     }
 }
\ No newline at end of file


Reply via email to