001package org.javasimon.console;
002
003import org.javasimon.Manager;
004import org.javasimon.SimonManager;
005
006import java.io.IOException;
007import java.io.OutputStream;
008import java.io.PrintWriter;
009import java.io.UnsupportedEncodingException;
010import java.net.URLDecoder;
011import java.nio.charset.Charset;
012import java.util.ArrayList;
013import java.util.Collection;
014import java.util.EnumSet;
015
016import javax.servlet.http.HttpServletRequest;
017import javax.servlet.http.HttpServletResponse;
018
019/**
020 * Action context wraps both HTTP request and response to make unit testing easier.
021 *
022 * @author gquintana
023 */
024public class ActionContext {
025
026        /** HTTP Request. */
027        private final HttpServletRequest request;
028        /** HTTP Response. */
029        private final HttpServletResponse response;
030        /** Request Path. */
031        private String path;
032        /** Simon manager to use. */
033        private Manager manager = SimonManager.manager();
034        /** Simon console plugin manager. */
035        private SimonConsolePluginManager pluginManager;
036
037        public ActionContext(HttpServletRequest request, HttpServletResponse response, String path) {
038                this.request = request;
039                this.response = response;
040                this.path = path;
041        }
042
043        public HttpServletRequest getRequest() {
044                return request;
045        }
046
047        public String getCharacterEncoding() {
048                String encoding = getRequest().getCharacterEncoding();
049                return encoding == null ? Charset.defaultCharset().name() : encoding;
050        }
051
052        public HttpServletResponse getResponse() {
053                return response;
054        }
055
056        public String getPath() {
057                return path;
058        }
059
060        public void setPath(String path) {
061                this.path = path;
062        }
063
064        /** Set content type of response. */
065        public void setContentType(String contentType) {
066                getResponse().setContentType(contentType);
067        }
068
069        /** Get response output stream. */
070        public OutputStream getOutputStream() throws IOException {
071                return getResponse().getOutputStream();
072        }
073
074        /** Get response writer. */
075        public PrintWriter getWriter() throws IOException {
076                return getResponse().getWriter();
077        }
078
079        /** Get Simon {@link org.javasimon.Manager}. */
080        public Manager getManager() {
081                return manager;
082        }
083
084        public void setManager(Manager manager) {
085                this.manager = manager;
086        }
087
088        protected String getParameter(String name) {
089                String value = getRequest().getParameter(name);
090                if (value != null) {
091                        try {
092                                value = URLDecoder.decode(value, getCharacterEncoding());
093                        } catch (UnsupportedEncodingException unsupportedEncodingException) {
094                                // Leave value as is
095                        }
096                }
097                return value;
098        }
099
100        protected String[] getParameters(String name) {
101                return getRequest().getParameterValues(name);
102        }
103
104        /**
105         * Transform empty string (only white spaces) into null, handles null.
106         */
107        private static String blankToNull(String value) {
108                if (value != null) {
109                        value = value.trim();
110                        if (value.equals("")) {
111                                value = null;
112                        }
113                }
114                return value;
115        }
116
117        /** Returns default value when value is null. */
118        private static <T> T defaultValue(T value, T defaultValue) {
119                return value == null ? defaultValue : value;
120        }
121
122        /**
123         * Get request parameter as a String.
124         *
125         * @param name Parameter name
126         * @param defaultValue Parameter default value (can be null)
127         * @return Parameter value
128         */
129        public String getParameterAsString(String name, String defaultValue) {
130                return defaultValue(blankToNull(getParameter(name)), defaultValue);
131        }
132
133        /** Transform a string into an boolean. */
134        private static Boolean stringToBoolean(String value) {
135                final String s = blankToNull(value);
136                return s == null ? null : Boolean.valueOf(s);
137        }
138
139        /**
140         * Get request parameter as a Boolean.
141         *
142         * @param name Parameter name
143         * @param defaultValue Parameter default value
144         */
145        public boolean getParameterAsBoolean(String name, Boolean defaultValue) {
146                return defaultValue(stringToBoolean(getParameter(name)), defaultValue);
147        }
148
149        /**
150         * Transform a string into an enum (using its name which is supposed to be
151         * uppercase, handles null values.
152         */
153        private static <T extends Enum<T>> T stringToEnum(String value, Class<T> type) {
154                final String s = blankToNull(value);
155                return value == null ? null : Enum.valueOf(type, s.toUpperCase());
156        }
157
158        /**
159         * Get request parameter as a Enum.
160         *
161         * @param name Parameter name
162         * @param type Enum type
163         * @param defaultValue Parameter default value (can be null)
164         * @return Parameter value
165         */
166        public <T extends Enum<T>> T getParameterAsEnum(String name, Class<T> type, T defaultValue) {
167                return defaultValue(stringToEnum(getParameter(name), type), defaultValue);
168        }
169
170        /**
171         * Get multiple request parameters as Enums.
172         *
173         * @param name Parameter name
174         * @return Parameter values as an Enum Set.
175         */
176        public <T extends Enum<T>> EnumSet<T> getParametersAsEnums(String name, Class<T> type, EnumSet<T> defaultValue) {
177                String[] enumNames = getParameters(name);
178                if (enumNames == null) {
179                        return defaultValue;
180                } else {
181                        Collection<T> enums = new ArrayList<>();
182                        for (String enumName : enumNames) {
183                                T enumValue = stringToEnum(blankToNull(enumName), type);
184                                if (enumValue != null) {
185                                        enums.add(enumValue);
186                                }
187                        }
188                        return enums.isEmpty() ? defaultValue : EnumSet.copyOf(enums);
189                }
190        }
191
192        public SimonConsolePluginManager getPluginManager() {
193                return pluginManager;
194        }
195
196        public void setPluginManager(SimonConsolePluginManager pluginManager) {
197                this.pluginManager = pluginManager;
198        }
199}