001package org.javasimon.console.action;
002
003import org.javasimon.Sample;
004import org.javasimon.Simon;
005import org.javasimon.SimonState;
006import org.javasimon.console.Action;
007import org.javasimon.console.ActionContext;
008import org.javasimon.console.ActionException;
009import org.javasimon.console.SimonType;
010import org.javasimon.console.SimonTypeFactory;
011import org.javasimon.console.TimeFormatType;
012import org.javasimon.console.json.JsonStringifierFactory;
013import org.javasimon.console.json.ObjectJS;
014import org.javasimon.console.json.SimpleJS;
015import org.javasimon.console.text.Stringifier;
016
017import java.io.IOException;
018import java.util.Iterator;
019
020import javax.servlet.ServletException;
021
022/**
023 * Base for actions returning data in JSON format.
024 *
025 * @author gquintana
026 */
027public abstract class AbstractJsonAction extends Action {
028
029        /** Type converter Object → JSON String. */
030        protected final JsonStringifierFactory jsonStringifierFactory = new JsonStringifierFactory();
031
032        protected AbstractJsonAction(ActionContext context) {
033                super(context);
034        }
035
036        @Override
037        public void readParameters() {
038                TimeFormatType timeFormat = getContext().getParameterAsEnum("timeFormat", TimeFormatType.class, TimeFormatType.MILLISECOND);
039                jsonStringifierFactory.init(timeFormat,
040                        JsonStringifierFactory.READABLE_DATE_PATTERN,// Should be ISO
041                        JsonStringifierFactory.INTEGER_NUMBER_PATTERN
042                );
043        }
044
045        private <T> void addAttribute(ObjectJS objectJS, String name, Class<T> type, T value) {
046                objectJS.setAttribute(name, new SimpleJS<>(value, jsonStringifierFactory.getStringifier(type)));
047        }
048
049        /**
050         * Transforms a Simon into a JSON object.
051         *
052         * @param simon Simon
053         * @return JSON object
054         */
055        protected ObjectJS createObjectJS(Simon simon) {
056                Sample sample = simon.sample();
057                SimonType lType = SimonTypeFactory.getValueFromInstance(sample);
058                ObjectJS objectJS = ObjectJS.create(sample, jsonStringifierFactory);
059                addAttribute(objectJS, "type", SimonType.class, lType);
060                addAttribute(objectJS, "enabled", Boolean.class, simon.isEnabled());
061                addAttribute(objectJS, "state", SimonState.class, simon.getState());
062                return objectJS;
063
064        }
065
066        @SuppressWarnings("unchecked")
067        protected final ObjectJS createAttributesObjectJS(Simon simon) {
068                ObjectJS objectJS = new ObjectJS();
069                Iterator<String> attributeNameIter = simon.getAttributeNames();
070                boolean foundAttribute = false;
071                while (attributeNameIter.hasNext()) {
072                        String attributeName = attributeNameIter.next();
073                        Object attributeValue = simon.getAttribute(attributeName);
074                        if (attributeValue != null) {
075                                Stringifier attributeStringifier = jsonStringifierFactory
076                                        .getStringifier(attributeValue.getClass());
077                                if (attributeStringifier != null) {
078                                        objectJS.setSimpleAttribute(attributeName, attributeValue, attributeStringifier);
079                                        foundAttribute = true;
080                                }
081                        }
082
083                }
084                return foundAttribute ? objectJS : null;
085        }
086
087        @Override
088        public void execute() throws ServletException, IOException, ActionException {
089                dontCache();
090                getContext().setContentType("application/json");
091        }
092}