/*
 * 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.event.impl.jobs.config;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Services;
import org.apache.sling.event.impl.jobs.JobEvent;
import org.apache.sling.event.jobs.JobUtil;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;


/**
 * An event handler for special job events.
 *
 * We schedule this event handler to run in the background and clean up
 * obsolete events.
 */
@Component
@Services({
    @Service(value=QueueConfigurationManager.class)
})
public class QueueConfigurationManager {

    /** Configurations - ordered by service ranking. */
    private volatile InternalQueueConfiguration[] orderedConfigs = new InternalQueueConfiguration[0];

    /** Service tracker for the configurations. */
    private ServiceTracker configTracker;

    /** Tracker count to detect changes. */
    private volatile int lastTrackerCount = -1;


    /**
     * Activate this component.
     * Create the service tracker and start it.
     */
    @Activate
    protected void activate(final BundleContext bundleContext) {
        this.configTracker = new ServiceTracker(bundleContext,
                InternalQueueConfiguration.class.getName(), null);
        this.configTracker.open();
    }

    /**
     * Deactivate this component.
     * Stop the service tracker.
     */
    @Deactivate
    protected void deactivate() {
        if ( this.configTracker != null ) {
            this.configTracker.close();
            this.configTracker = null;
        }
    }

    /**
     * Return all configurations.
     */
    public InternalQueueConfiguration[] getConfigurations() {
        final int count = this.configTracker.getTrackingCount();
        InternalQueueConfiguration[] configurations = this.orderedConfigs;
        if ( this.lastTrackerCount < count ) {
            synchronized ( this ) {
                configurations = this.orderedConfigs;
                if ( this.lastTrackerCount < count ) {
                    final Object[] trackedConfigs = this.configTracker.getServices();
                    if ( trackedConfigs == null || trackedConfigs.length == 0 ) {
                        configurations = new InternalQueueConfiguration[0];
                    } else {
                        configurations = new InternalQueueConfiguration[trackedConfigs.length];
                        int i = 0;
                        for(final Object entry : trackedConfigs) {
                            final InternalQueueConfiguration config = (InternalQueueConfiguration)entry;
                            configurations[i] = config;
                            i++;
                        }
                    }
                    this.orderedConfigs = configurations;
                    this.lastTrackerCount = count;
                }
            }
        }
        return configurations;
    }

    /**
     * Find the queue configuration for the job.
     * This method only returns a configuration if one matches.
     */
    public InternalQueueConfiguration getQueueConfiguration(final JobEvent event) {
        final InternalQueueConfiguration[] configurations = this.getConfigurations();
        // check for queue name first
        final String queueName = (String)event.event.getProperty(JobUtil.PROPERTY_JOB_QUEUE_NAME);
        for(final InternalQueueConfiguration config : configurations) {
            if ( config.isValid() ) {
                if ( queueName != null ) {
                    if ( queueName.equals(config.getName()) ) {
                        event.queueName = queueName;
                        return config;
                    }
                } else {
                    if ( config.match(event) ) {
                        return config;
                    }
                }
            }
        }
        return null;
    }
}

@@ -4168,46 +4168,8 @@
 ();%0A
-        // check for queue name first%0A
     
@@ -4393,34 +4393,37 @@
     
-if (
+// check for
  queue
-N
+ n
 ame 
-!= null ) %7B
+first
 %0A   
@@ -4435,24 +4435,41 @@
         
-    
 if (
+ queueName != null &&
  queueNa
@@ -4520,20 +4520,16 @@
         
-    
 event.qu
@@ -4561,36 +4561,32 @@
                 
-   
- 
 return config;%0A 
@@ -4604,43 +4604,10 @@
     
-    %7D%0A                %7D else %7B%0A    
+%7D%0A
     
@@ -4659,36 +4659,32 @@
                 
-    
 return config;%0A 
@@ -4682,38 +4682,16 @@
 config;%0A
-                    %7D%0A
         

Fix queue configuration detection if queue name is provided in the job event.