You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by js...@apache.org on 2015/09/04 16:06:50 UTC

svn commit: r1701271 - /sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java

Author: jsedding
Date: Fri Sep  4 14:06:50 2015
New Revision: 1701271

URL: http://svn.apache.org/r1701271
Log:
SLING-5001 - Logic in WhiteboardHandler is hard to follow

- refactored and cleaned up WhiteboardHandler

Modified:
    sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java

Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java?rev=1701271&r1=1701270&r2=1701271&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java (original)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java Fri Sep  4 14:06:50 2015
@@ -25,6 +25,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.sling.commons.scheduler.Job;
+import org.apache.sling.commons.scheduler.ScheduleOptions;
 import org.apache.sling.commons.scheduler.Scheduler;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -42,6 +43,10 @@ import org.slf4j.LoggerFactory;
 @Component(immediate=true)
 public class WhiteboardHandler {
 
+    private static final String SCHEDULED_JOB_FILTER =
+            "(|(" + Constants.OBJECTCLASS + "=" + Runnable.class.getName() + ")" +
+            "(" + Constants.OBJECTCLASS + "=" + Job.class.getName() + "))";
+
     /** Default logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -59,17 +64,16 @@ public class WhiteboardHandler {
     @Activate
     protected void activate(final BundleContext btx) throws InvalidSyntaxException {
         this.serviceTracker = new ServiceTracker(btx,
-                btx.createFilter("(|(" + Constants.OBJECTCLASS + "=" + Runnable.class.getName() + ")" +
-                 "(" + Constants.OBJECTCLASS + "=" + Job.class.getName() + "))"),
+                btx.createFilter(SCHEDULED_JOB_FILTER),
                 new ServiceTrackerCustomizer() {
 
             public void  removedService(final ServiceReference reference, final Object service) {
-                unregister(reference, service);
+                unregister(reference);
                 btx.ungetService(reference);
             }
 
             public void modifiedService(final ServiceReference reference, final Object service) {
-                unregister(reference, service);
+                unregister(reference);
                 register(reference, service);
             }
 
@@ -87,7 +91,6 @@ public class WhiteboardHandler {
     /**
      * Deactivate this component.
      * Stop the scheduler.
-     * @param ctx The component context.
      */
     @Deactivate
     protected void deactivate() {
@@ -119,6 +122,14 @@ public class WhiteboardHandler {
         throw new IllegalArgumentException("Property " + name + " is not of type Boolean");
     }
 
+    private boolean getBooleanOrDefault(final ServiceReference ref, final String name, final boolean defaultValue) {
+        final Boolean value = getBooleanProperty(ref, name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return value;
+    }
+
     private Long getLongProperty(final ServiceReference ref, final String name) {
         final Object obj = ref.getProperty(name);
         if ( obj == null ) {
@@ -141,10 +152,19 @@ public class WhiteboardHandler {
         throw new IllegalArgumentException("Property " + name + " is not of type Integer");
     }
 
+    private String[] getStringArray(final ServiceReference ref, final String name) {
+        final Object value = ref.getProperty(name);
+        if ( value instanceof String[] ) {
+            return (String[])value;
+        } else if ( value != null ) {
+            return new String[] {value.toString()};
+        }
+        return null;
+    }
+
     /**
      * Create unique identifier
-     * @param type
-     * @param ref
+     * @param ref The service reference
      * @throws IllegalArgumentException
      */
     private String getServiceIdentifier(final ServiceReference ref) {
@@ -156,68 +176,22 @@ public class WhiteboardHandler {
             }
         }
         // now append service id to create a unique identifier
-        name = name + "." + ref.getProperty(Constants.SERVICE_ID);
+        name = name + "." + getLongProperty(ref, Constants.SERVICE_ID);
         return name;
     }
 
     /**
      * Register a job or task
-     * @param type The type (job or task)
      * @param ref The service reference
+     * @param job The job object
      * @throws IllegalArgumentException
      */
     private void register(final ServiceReference ref, final Object job) {
         try {
-            final String name = getServiceIdentifier(ref);
-            final Boolean concurrent = getBooleanProperty(ref, Scheduler.PROPERTY_SCHEDULER_CONCURRENT);
-            final Object runOn = ref.getProperty(Scheduler.PROPERTY_SCHEDULER_RUN_ON);
-            String[] runOnOpts = null;
-            if ( runOn instanceof String ) {
-                runOnOpts = new String[] {runOn.toString()};
-            } else if ( runOn instanceof String[] ) {
-                runOnOpts = (String[])runOn;
-            } else if ( runOn != null ) {
-                this.logger.warn("Property {} ignored for scheduler {}", Scheduler.PROPERTY_SCHEDULER_RUN_ON, ref);
-            }
-            final String expression = getStringProperty(ref, Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
-            if ( expression != null ) {
-                this.scheduler.schedule(ref.getBundle().getBundleId(), (Long)ref.getProperty(Constants.SERVICE_ID),
-                        job, this.scheduler.EXPR(expression)
-                        .name(name)
-                        .canRunConcurrently((concurrent != null ? concurrent : true))
-                        .onInstancesOnly(runOnOpts));
-                this.idToNameMap.put((Long)ref.getProperty(Constants.SERVICE_ID), name);
-            } else {
-                final Long period = getLongProperty(ref, Scheduler.PROPERTY_SCHEDULER_PERIOD);
-                if ( period != null ) {
-                    if ( period < 1 ) {
-                        this.logger.debug("Ignoring service {} : scheduler period is less than 1.", ref);
-                    } else {
-                        boolean immediate = false;
-                        if ( ref.getProperty(Scheduler.PROPERTY_SCHEDULER_IMMEDIATE) != null ) {
-                            immediate = getBooleanProperty(ref, Scheduler.PROPERTY_SCHEDULER_IMMEDIATE);
-                        }
-                        final Date date = new Date();
-                        if ( !immediate ) {
-                            date.setTime(System.currentTimeMillis() + period * 1000);
-                        }
-                        final Integer times = getIntegerProperty(ref, Scheduler.PROPERTY_SCHEDULER_TIMES);
-                        if ( times != null && times < 1 ) {
-                            this.logger.debug("Ignoring service {} : scheduler times is less than 1.", ref);
-                        } else {
-                            final int t = (times != null ? times : -1);
-                            this.scheduler.schedule(ref.getBundle().getBundleId(), (Long)ref.getProperty(Constants.SERVICE_ID),
-                                    job, this.scheduler.AT(date, t, period)
-                                    .name(name)
-                                    .canRunConcurrently((concurrent != null ? concurrent : true))
-                                    .onInstancesOnly(runOnOpts));
-                            this.idToNameMap.put((Long)ref.getProperty(Constants.SERVICE_ID), name);
-                        }
-                    }
-                } else {
-                    this.logger.debug("Ignoring servce {} : no scheduling property found.", ref);
-                }
+            if (!tryScheduleExpression(ref, job) && !trySchedulePeriod(ref, job)) {
+                this.logger.debug("Ignoring service {} : no scheduling property found.", ref);
             }
+
         } catch ( final IllegalArgumentException iae) {
             this.logger.warn("Ignoring service {} : {}", ref, iae.getMessage());
         }
@@ -225,12 +199,67 @@ public class WhiteboardHandler {
 
     /**
      * Unregister a service.
-     * @param ref The service reference.
+     * @param reference The service reference.
      */
-    private void unregister(final ServiceReference reference, final Object service) {
-        final String name = idToNameMap.remove(reference.getProperty(Constants.SERVICE_ID));
+    private void unregister(final ServiceReference reference) {
+        final String name = idToNameMap.remove(getLongProperty(reference, Constants.SERVICE_ID));
         if ( name != null ) {
             this.scheduler.unschedule(reference.getBundle().getBundleId(), name);
         }
     }
+
+    private boolean trySchedulePeriod(final ServiceReference ref, final Object job) {
+        final Long period = getLongProperty(ref, Scheduler.PROPERTY_SCHEDULER_PERIOD);
+        if ( period == null ) {
+            return false;
+        }
+
+        if ( period < 1 ) {
+            this.logger.debug("Ignoring service {} : scheduler period is less than 1.", ref);
+        } else {
+            final Date date = new Date();
+            boolean immediate = getBooleanOrDefault(ref, Scheduler.PROPERTY_SCHEDULER_IMMEDIATE, false);
+            if ( !immediate ) {
+                date.setTime(System.currentTimeMillis() + period * 1000);
+            }
+            final Integer times = getIntegerProperty(ref, Scheduler.PROPERTY_SCHEDULER_TIMES);
+            if ( times != null && times < 1 ) {
+                this.logger.debug("Ignoring service {} : scheduler times is less than 1.", ref);
+            } else {
+                final int t = (times != null ? times : -1);
+                scheduleJob(ref, job, this.scheduler.AT(date, t, period));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean tryScheduleExpression(final ServiceReference ref, final Object job) {
+        final String expression = getStringProperty(ref, Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
+        if ( expression != null ) {
+            scheduleJob(ref, job, this.scheduler.EXPR(expression));
+            return true;
+        }
+        return false;
+    }
+
+    private String[] getRunOpts(final ServiceReference ref) {
+        return getStringArray(ref, Scheduler.PROPERTY_SCHEDULER_RUN_ON);
+    }
+
+    private void scheduleJob(final ServiceReference ref, final Object job, final ScheduleOptions scheduleOptions) {
+        final String name = getServiceIdentifier(ref);
+        final Boolean concurrent = getBooleanProperty(ref, Scheduler.PROPERTY_SCHEDULER_CONCURRENT);
+        final String[] runOnOpts = getRunOpts(ref);
+
+        final ScheduleOptions options = scheduleOptions
+                .name(name)
+                .canRunConcurrently((concurrent != null ? concurrent : true))
+                .onInstancesOnly(runOnOpts);
+
+        final long bundleId = ref.getBundle().getBundleId();
+        final Long serviceId = getLongProperty(ref, Constants.SERVICE_ID);
+        this.scheduler.schedule(bundleId, serviceId, job, options);
+        this.idToNameMap.put(serviceId, name);
+    }
 }