001package com.ganteater.ae.web;
002
003import java.io.File;
004import java.io.FileReader;
005import java.io.IOException;
006import java.io.Reader;
007import java.util.Collection;
008import java.util.Enumeration;
009import java.util.Map;
010
011import javax.servlet.http.HttpServletResponse;
012
013import org.apache.commons.io.IOUtils;
014import org.apache.commons.lang.ObjectUtils;
015import org.apache.commons.lang.StringUtils;
016import org.apache.log4j.FileAppender;
017import org.apache.log4j.Logger;
018import org.springframework.beans.factory.annotation.Value;
019import org.springframework.web.bind.annotation.RequestMapping;
020import org.springframework.web.bind.annotation.RequestParam;
021import org.springframework.web.bind.annotation.RestController;
022import org.springframework.web.servlet.ModelAndView;
023import org.springframework.web.servlet.view.AbstractView;
024import org.springframework.web.servlet.view.RedirectView;
025
026import com.ganteater.ae.CommandException;
027import com.ganteater.ae.ConfigConstants;
028import com.ganteater.ae.RecipeRunner;
029import com.ganteater.ae.util.xml.easyparser.Node;
030
031@RestController
032public class AEApplicationController {
033
034        private WebWorkspace workspace;
035
036        @Value("#{${contentTypesMap}}")
037        private Map<String, String> contentTypesMap;
038
039        public AEApplicationController(WebWorkspace workspace) {
040                super();
041                this.workspace = workspace;
042        }
043
044        @RequestMapping("/dashboard")
045        public ModelAndView dashboard(@RequestParam(required = false) String command) {
046                ModelAndView modelAndView;
047                if (!StringUtils.equals(command, "loadRecipePack") && workspace.getAllConfigNode() != null
048                                && workspace.getConfigNode() == null) {
049                        try {
050                                Thread.sleep(2000);
051                        } catch (InterruptedException e) {
052                                Thread.currentThread().interrupt();
053                        }
054                }
055                Node configNode = workspace.getConfigNode();
056                if (configNode == null || StringUtils.equals(command, "loadRecipePack")) {
057                        workspace.resetConfiguration();
058                        modelAndView = new ModelAndView("set-configuration");
059                        modelAndView.addObject(ConfigConstants.CONFIG_NAME_SYS_PRPERTY_NAME, workspace.getConfigurationName());
060                        WebLogger webLogger = workspace.getLogs().get(WebWorkspace.CONFIG_LOG_NAME);
061                        modelAndView.addObject("configLog", webLogger);
062
063                } else if (StringUtils.equals(command, "changeConfig")) {
064                        workspace.resetConfiguration();
065                        workspace.afterPropertiesSet();
066                        WebLogger webLogger = workspace.getLogs().get(WebWorkspace.CONFIG_LOG_NAME);
067                        while (webLogger.getInput() == null) {
068                                try {
069                                        Thread.sleep(200);
070                                } catch (InterruptedException e) {
071                                        Thread.currentThread().interrupt();
072                                }
073                        }
074                        modelAndView = new ModelAndView("set-configuration");
075                        modelAndView.addObject("configLog", webLogger);
076                        modelAndView.addObject(ConfigConstants.CONFIG_NAME_SYS_PRPERTY_NAME, workspace.getConfigurationName());
077
078                } else {
079                        modelAndView = new ModelAndView("dashboard");
080                        modelAndView.addObject(ConfigConstants.CONFIG_NAME_SYS_PRPERTY_NAME, workspace.getConfigurationName());
081                }
082
083                return modelAndView;
084        }
085
086        @RequestMapping("/input-array")
087        public RedirectView inputArray(@RequestParam String log, @RequestParam(required = false) String value[],
088                        @RequestParam(required = false) String redirectUrl, @RequestParam(required = false) String action) {
089                WebLogger webLogger = workspace.getLogs().get(log);
090                if ("Cancel".equals(action)) {
091                        value = null;
092                        if (webLogger.getInput() instanceof WebChoiceItem) {
093                                WebChoiceItem webChoiceItem = (WebChoiceItem) webLogger.getInput();
094                                Object[] choiceItems = webChoiceItem.getChoiceItems();
095                                for (int i = 0; i < choiceItems.length; i++) {
096                                        WebInputItem webInputItem = (WebInputItem) choiceItems[i];
097                                        webInputItem.setValue("false");
098                                }
099                        }
100                }
101                if ("Select All".equals(action)) {
102                        WebChoiceItem webChoiceItem = (WebChoiceItem) webLogger.getInput();
103                        Object[] choiceItems = webChoiceItem.getChoiceItems();
104                        for (int i = 0; i < choiceItems.length; i++) {
105                                WebInputItem webInputItem = (WebInputItem) choiceItems[i];
106                                webInputItem.setValue("true");
107                        }
108                        return new RedirectView(StringUtils.defaultIfEmpty(redirectUrl, "show?taskName=" + webLogger.getName()));
109                }
110                if (value == null) {
111                        value = new String[0];
112                }
113                webLogger.applyInput(value);
114                return new RedirectView(StringUtils.defaultIfEmpty(redirectUrl, "show?taskName=" + webLogger.getName()));
115        }
116
117        @RequestMapping("/input")
118        public RedirectView input(@RequestParam String log, @RequestParam(required = false) String value,
119                        @RequestParam(required = false) String redirectUrl, @RequestParam(required = false) String action) {
120                WebLogger webLogger = workspace.getLogs().get(log);
121                if ("Cancel".equals(action)) {
122                        value = null;
123                        if (webLogger.getInput() instanceof WebChoiceItem) {
124                                WebChoiceItem webChoiceItem = (WebChoiceItem) webLogger.getInput();
125                                Object[] choiceItems = webChoiceItem.getChoiceItems();
126                                for (int i = 0; i < choiceItems.length; i++) {
127                                        WebInputItem webInputItem = (WebInputItem) choiceItems[i];
128                                        webInputItem.setValue("false");
129                                }
130                        }
131                }
132                webLogger.applyInput(new String[] { value });
133                return new RedirectView(StringUtils.defaultIfEmpty(redirectUrl, "show?taskName=" + webLogger.getName()));
134        }
135
136        @RequestMapping("/run")
137        public RedirectView runTask(@RequestParam String taskName) {
138                WebLogger webLogger = workspace.getLogs().get(taskName);
139                if (webLogger != null) {
140                        webLogger.moveToArchive();
141                }
142                try {
143                        workspace.runTask(taskName, true);
144                } catch (CommandException e) {
145                        // TODO Auto-generated catch block
146                        e.printStackTrace();
147                }
148                return new RedirectView("show?taskName=" + taskName);
149        }
150
151        @RequestMapping("/task")
152        public AbstractView runTask(@RequestParam String taskName, @RequestParam String action) {
153                WebLogger webLogger = workspace.getLogs().get(taskName);
154                if (webLogger != null) {
155                        if ("stop".equals(action)) {
156                                if (!webLogger.getTestRunner().getTaskProcessor().isStoppedTest()) {
157                                        webLogger.getTestRunner().stopTest();
158                                }
159                        }
160                }
161                return new RedirectView("show?taskName=" + taskName);
162        }
163
164        @RequestMapping("/menu")
165        public ModelAndView getMenu(@RequestParam(required = false) Boolean silent,
166                        @RequestParam(required = false) Boolean mode) {
167                ModelAndView mv = new ModelAndView("menu");
168
169                if (mode != null) {
170                        boolean defaultMode = silent != null && silent ? true : false;
171                        workspace.setConsoleDefaultInput(defaultMode);
172
173                        Collection<WebLogger> values = workspace.getLogs().values();
174                        for (WebLogger webLogger : values) {
175                                webLogger.reset();
176                        }
177                }
178
179                mv.addObject("menuEnabled", true);
180                Object[] publicTestsList = workspace.getPublicTestsList();
181
182                for (int i = 0; i < 10 && publicTestsList.length == 0; i++) {
183                        try {
184                                Thread.sleep(100);
185                        } catch (InterruptedException e) {
186                        }
187                        publicTestsList = workspace.getPublicTestsList();
188                }
189
190                mv.addObject("tests", publicTestsList);
191                mv.addObject("logs", workspace.getLogs());
192                mv.addObject("silent", workspace.isConsoleDefaultInput(null, null));
193                return mv;
194        }
195
196        @RequestMapping("/show")
197        public ModelAndView showMessage(@RequestParam(required = false) String taskName) {
198
199                ModelAndView mv = new ModelAndView();
200                if (taskName != null) {
201                        showLog(taskName, mv, 0);
202                        mv.setViewName("show-log");
203
204                } else {
205                        mv.setViewName("settings");
206                        Node configNode = workspace.getConfigNode();
207                        if (configNode != null) {
208                                mv.addObject("configs", workspace.getAllConfigNode().getXMLText());
209                                mv.addObject("config", configNode.getXMLText());
210                                mv.addObject("startDir", workspace.getStartDir());
211                                mv.addObject("systemVariables", workspace.getSystemVariables());
212                                mv.addObject("workingDir", workspace.getWorkingDir());
213                        }
214                }
215
216                return mv;
217        }
218
219        @RequestMapping(value = "/view.*")
220        public ModelAndView viewRecord(@RequestParam String taskName, @RequestParam int id, HttpServletResponse response)
221                        throws IOException {
222                WebLogger log = workspace.getLogs().get(taskName);
223                WebLogRecord record = log.getRecord(id);
224                ModelAndView mv = new ModelAndView();
225                String type = record.getType();
226                String viewName = "view/" + StringUtils.defaultString(type, "txt");
227                mv.setViewName(viewName);
228                mv.addObject("record", record);
229                mv.addObject("taskName", taskName);
230                mv.addObject("id", id);
231
232                String contentType = setContentType(type);
233                response.setContentType(contentType);
234                return mv;
235        }
236
237        private String setContentType(String type) {
238                String contentType;
239                contentType = contentTypesMap.get(type);
240                if (contentType == null) {
241                        contentType = contentTypesMap.get("default");
242                }
243                return contentType;
244        }
245
246        @RequestMapping("/record")
247        public void showRecord(@RequestParam String taskName, @RequestParam int id, HttpServletResponse response)
248                        throws IOException {
249                WebLogger log = workspace.getLogs().get(taskName);
250                WebLogRecord record = log.getRecord(id);
251                response.setHeader("Content-Disposition", "inline; filename=\"record." + record.getType() + "\"");
252                String type = record.getType();
253                String contentType = setContentType(type);
254                response.setContentType(contentType);
255                
256                if ("eml".equals(type)) {
257                        Object text = record.getMessage();
258                        if (text instanceof byte[]) {
259                                IOUtils.write((byte[]) text, response.getWriter());
260                        } else {
261                                response.getWriter().append(ObjectUtils.toString(text));
262                        }
263                        return;
264                } 
265                response.getWriter().append(ObjectUtils.toString(record.getText()));
266        }
267
268        @RequestMapping("/task-log")
269        public ModelAndView taskLog(@RequestParam String taskName,
270                        @RequestParam(required = false, defaultValue = "-1") int id) {
271                ModelAndView mv = new ModelAndView();
272                showLog(taskName, mv, id + 1);
273                mv.setViewName("task-log");
274
275                return mv;
276        }
277
278        private void showLog(String taskName, ModelAndView mv, int id) {
279                WebLogger log = workspace.getLogs().get(taskName);
280
281                if (log != null) {
282                        RecipeRunner testRunner = log.getTestRunner();
283                        if (testRunner != null && testRunner.getTaskProcessor() != null) {
284                                mv.addObject("status", testRunner.getTaskProcessor().isStoppedTest() ? "stopped" : "running");
285                        }
286                        mv.addObject("title", log.getName());
287                        mv.addObject("startId", log.getStartIndex());
288                        mv.addObject("log", log.getLog(id));
289                        mv.addObject("input", log.getInput());
290                }
291        }
292
293        @RequestMapping("/log")
294        public ModelAndView log() {
295                ModelAndView mv = new ModelAndView();
296                File logPath = getLogPath();
297                if (logPath != null) {
298                        try (Reader reader = new FileReader(logPath)) {
299                                String string = IOUtils.toString(reader);
300                                mv.addObject("record", string);
301                        } catch (IOException e) {
302                                e.printStackTrace();
303                        }
304                }
305                mv.setViewName("view/txt");
306                return mv;
307        }
308
309        public static File getLogPath() {
310                Enumeration appenders = Logger.getRootLogger().getAllAppenders();
311                while (appenders.hasMoreElements()) {
312                        Object object = (Object) appenders.nextElement();
313                        if (object instanceof FileAppender) {
314                                FileAppender fileAppender = (FileAppender) object;
315                                return new File(fileAppender.getFile());
316                        }
317                }
318                return null;
319        }
320
321}