package org.jenkinsci.plugins.rabbitmqbuildtrigger;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import hudson.Extension;
import hudson.ExtensionPoint;
import net.sf.json.JSONObject;

import org.jenkinsci.plugins.rabbitmqconsumer.listeners.ApplicationMessageListener;

/**
 * The extension listen application message then call triggers.
 * 
 * @author rinrinne a.k.a. rin_ne
 */
@Extension
public class RemoteBuildListener implements ExtensionPoint, ApplicationMessageListener {
    private static final String PLUGIN_NAME = "Remote Builder";
    private static final String PLUGIN_APPID = "remote-build";

    private static final String KEY_PROJECT = "project";
    private static final String KEY_TOKEN = "token";
    private static final String KEY_PARAMETER = "parameter";

    private static final Logger LOGGER = Logger.getLogger(RemoteBuildListener.class.getName());

    private final List<RemoteBuildTrigger> triggers = new ArrayList<RemoteBuildTrigger>();
    private final Object lock = new Object();

    /**
     * @inheritDoc
     * @return the name.
     */
    public String getName() {
        return PLUGIN_NAME;
    }

    /**
     * @inheritDoc
     * @return the application id.
     */
    public String getAppId() {
        return PLUGIN_APPID;
    }

    /**
     * Adds trigger.
     * 
     * @param trigger
     *            the trigger.
     */
    public void addTrigger(RemoteBuildTrigger trigger) {
        synchronized (lock) {
            if (!triggers.contains(trigger)) {
                triggers.add(trigger);
            }
        }
    }

    /**
     * Removes trigger.
     * 
     * @param trigger
     *            the trigger.
     */
    public void removeTrigger(RemoteBuildTrigger trigger) {
        synchronized (lock) {
            triggers.remove(trigger);
        }
    }

    /**
     * @inheritDoc
     * @param queueName
     *            the queue name.
     */
    public void onBind(String queueName) {
        LOGGER.info("Bind to: " + queueName);
    }

    /**
     * @inheritDoc
     * @param queueName
     *            the queue name.
     */
    public void onUnbind(String queueName) {
        LOGGER.info("Unbind from: " + queueName);
    }

    /**
     * Finds matched projects using given project name and token then schedule
     * build.
     * 
     * @inheritDoc
     * @param queueName
     *            the queue name.
     * @param json
     *            the content of message.
     */
    public void onReceive(String queueName, JSONObject json) {
        synchronized (lock) {
            for (RemoteBuildTrigger t : triggers) {

                if (t.getRemoteBuildToken() == null) {
                    LOGGER.log(Level.WARNING, "ignoring AMQP trigger for project {0}: no token set", t.getProjectName());
                    continue;
                }

                if (t.getProjectName().equals(json.getString(KEY_PROJECT))
                        && t.getRemoteBuildToken().equals(json.getString(KEY_TOKEN))) {
                    t.scheduleBuild(queueName, json.getJSONArray(KEY_PARAMETER));
                }
            }
        }
    }
}

@@ -63,24 +63,18 @@
 va.util.
-ArrayLis
+Se
 t;%0Aimpor
@@ -89,44 +89,38 @@
 til.
-List;%0Aimport java.util.logging.Level
+concurrent.CopyOnWriteArraySet
 ;%0Aim
@@ -948,19 +948,18 @@
 e final 
-Lis
+Se
 t%3CRemote
@@ -991,16 +991,26 @@
 new 
+CopyOnWrite
 Array
-Lis
+Se
 t%3CRe
@@ -1033,54 +1033,8 @@
 %3E();
-%0A    private final Object lock = new Object();
 %0A%0A  
@@ -1460,139 +1460,30 @@
     
-synchronized (lock) %7B%0A            if (!triggers.contains(trigger)) %7B%0A                triggers.add(trigger);%0A            %7D%0A        %7D
+triggers.add(trigger);
 %0A   
@@ -1651,42 +1651,8 @@
 ) %7B%0A
-        synchronized (lock) %7B%0A    
     
@@ -1681,26 +1681,16 @@
 igger);%0A
-        %7D%0A
     %7D%0A%0A 
@@ -2394,42 +2394,8 @@
 ) %7B%0A
-        synchronized (lock) %7B%0A    
     
@@ -2443,36 +2443,32 @@
  %7B%0A%0A            
-    
 if (t.getRemoteB
@@ -2502,28 +2502,24 @@
             
-  
-  
 LOGGER.log(L
@@ -2624,20 +2624,16 @@
         
-    
 continue
@@ -2634,20 +2634,16 @@
 ntinue;%0A
-    
         
@@ -2653,36 +2653,32 @@
  %7D%0A%0A            
-    
 if (t.getProject
@@ -2720,20 +2720,16 @@
 OJECT))%0A
-    
         
@@ -2820,20 +2820,16 @@
         
-  
-  
 t.schedu
@@ -2886,26 +2886,8 @@
 ));%0A
-                %7D%0A
     

Improve locking oppotunity