001package systems.dmx.core.service;
002
003import systems.dmx.core.JSONEnabled;
004import systems.dmx.core.util.DMXUtils;
005
006import org.codehaus.jettison.json.JSONArray;
007import org.codehaus.jettison.json.JSONObject;
008
009import java.util.ArrayList;
010import java.util.Iterator;
011import java.util.List;
012import java.util.logging.Logger;
013
014
015
016/**
017 * Note: Directives is not {@link systems.dmx.core.JSONEnabled} as the underlying structure is a list, not an object.
018 * There is a {@link #toJSONArray} method though.
019 */
020public class Directives implements Iterable<Directives.Entry> {
021
022    // ---------------------------------------------------------------------------------------------- Instance Variables
023
024    private List<Entry> directives = new ArrayList();
025
026    // ------------------------------------------------------------------------------------------------- Class Variables
027
028    private static Logger logger = Logger.getLogger("systems.dmx.core.service.Directives");
029
030    private static final ThreadLocal<Directives> threadLocalDirectives = new ThreadLocal() {
031        @Override
032        protected Directives initialValue() {
033            logger.fine("### Creating tread-local directives");
034            return new Directives();
035        }
036    };
037
038    // -------------------------------------------------------------------------------------------------- Public Methods
039
040    public void add(Directive dir, JSONEnabled arg) {
041        directives.add(new Entry(dir, arg));
042    }
043
044    public JSONArray toJSONArray() {
045        return DMXUtils.toJSONArray(directives);
046    }
047
048    // ---
049
050    public static Directives get() {
051        return threadLocalDirectives.get();
052    }
053
054    public static void remove() {
055        logger.fine("### Removing tread-local directives");
056        threadLocalDirectives.remove();
057    }
058
059    // *** Iterable Implementation ***
060
061    @Override
062    public Iterator<Entry> iterator() {
063        return directives.iterator();
064    }
065
066    // -------------------------------------------------------------------------------------------------- Nested Classes
067
068    public class Entry implements JSONEnabled {
069
070        public Directive dir;
071        public JSONEnabled arg;
072
073        private Entry(Directive dir, JSONEnabled arg) {
074            this.dir = dir;
075            this.arg = arg;
076        }
077
078        @Override
079        public JSONObject toJSON() {
080            try {
081                return new JSONObject()
082                    .put("type", dir)
083                    .put("arg", arg.toJSON());
084            } catch (Exception e) {
085                throw new RuntimeException("Serialization failed", e);
086            }
087        }
088
089        @Override
090        public String toString() {
091            return dir + ": " + arg;
092        }
093    }
094}