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