001package com.ganteater.ae.desktop;
002
003import java.awt.BorderLayout;
004import java.awt.Color;
005import java.awt.FileDialog;
006import java.awt.Font;
007import java.awt.event.ActionEvent;
008import java.awt.event.ActionListener;
009import java.awt.event.WindowAdapter;
010import java.awt.event.WindowEvent;
011import java.io.File;
012import java.util.Map;
013import java.util.Vector;
014
015import javax.swing.BorderFactory;
016import javax.swing.JButton;
017import javax.swing.JDialog;
018import javax.swing.JEditorPane;
019import javax.swing.JLabel;
020import javax.swing.JOptionPane;
021import javax.swing.JPanel;
022import javax.swing.JScrollPane;
023import javax.swing.JTextField;
024import javax.swing.JToolBar;
025import javax.swing.JTree;
026
027import org.apache.commons.lang.ArrayUtils;
028import org.apache.commons.lang.StringUtils;
029import org.apache.commons.lang.exception.ExceptionUtils;
030
031import com.ganteater.ae.AEWorkspace;
032import com.ganteater.ae.CommandException;
033import com.ganteater.ae.ILogger;
034import com.ganteater.ae.RecipeRunner;
035import com.ganteater.ae.TaskThread;
036import com.ganteater.ae.desktop.ui.HyperlinkAdapter;
037import com.ganteater.ae.desktop.ui.JParsedown;
038import com.ganteater.ae.desktop.ui.OptionPane;
039import com.ganteater.ae.desktop.ui.AEFrame;
040import com.ganteater.ae.desktop.ui.AttachButton;
041import com.ganteater.ae.desktop.util.UIUtils;
042import com.ganteater.ae.processor.BaseProcessor;
043import com.ganteater.ae.processor.Processor;
044import com.ganteater.ae.util.xml.easyparser.Node;
045
046public class WorkPlace extends RecipeRunner {
047
048        private static final Font ABOUT_FONT = new Font("SansSerif", Font.PLAIN, 12);
049        private static final String MAIL_ATTR_NAME = "email";
050
051        protected JToolBar aboutButtonPanel = new JToolBar();
052
053        protected String recipeFilePath;
054
055        protected FileDialog theAttacFileDialog;
056        protected JLabel fTitleTest = new JLabel();
057        protected JTextField theConfigName = new JTextField();
058        private AEFrame aeFrame = null;
059        private JDialog aboutDialog;
060
061        public WorkPlace(AEFrame aeFrame, Node aConfigNode, Map<String, Object> aSystemVariables) {
062                super(aeFrame.getWorkspace(), aConfigNode, aSystemVariables);
063                aConfigNode.getVector(true);
064                this.aeFrame = aeFrame;
065                theConfigName.setEditable(false);
066
067                theConfigName.setFont(new Font("Dialog", Font.PLAIN, 9));
068                theConfigName.setBackground(Color.lightGray);
069
070                theAttacFileDialog = new FileDialog(JOptionPane.getRootFrame(), "Storing attach in file", FileDialog.SAVE);
071                theAttacFileDialog.setDirectory(System.getProperty("user.home"));
072
073                fTitleTest.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
074
075                JPanel thePanelLogo = new JPanel(new BorderLayout());
076
077                thePanelLogo.add(theConfigName, BorderLayout.SOUTH);
078
079                JPanel theComp = new JPanel(new BorderLayout());
080                JPanel theCompTitle = new JPanel(new BorderLayout());
081                theComp.add(theCompTitle, BorderLayout.NORTH);
082        }
083
084        protected void setActiveTest(String theActiveTest) {
085                if (theActiveTest != null) {
086                        recipeFilePath = getManager().getTestPath(theActiveTest);
087                }
088
089                runTest(recipeFilePath, createLog(theActiveTest, true));
090        }
091
092        @Override
093        public void startTask(String aNameTask) {
094                setTestName(aNameTask);
095        }
096
097        @Override
098        public void setTestName(String aNameTask) {
099                fTitleTest.setText(aNameTask);
100        }
101
102        @Override
103        public void endTask(boolean aErrorState) {
104                super.endTask(aErrorState);
105
106                if (!aErrorState) {
107                        fTitleTest.setText(" Recipe done.");
108                } else {
109                        fTitleTest.setText(" Recipe failed.");
110                }
111
112                manager.progressValue(0, 0, !aErrorState);
113        }
114
115        public void runTest(String aTestFile, ILogger aLog) {
116                if (aTestFile == null) {
117                        return;
118                }
119                recipeFilePath = aTestFile;
120
121                TaskThread theThread = new TaskThread(this, aTestFile);
122                theThread.start();
123        }
124
125        public String getTestFile() {
126                return recipeFilePath;
127        }
128
129        public void setTestsFile(String aTestsFile) {
130                recipeFilePath = aTestsFile;
131        }
132
133        @Override
134        public String inputFile(File defaultFile, Processor taskProcessor) {
135                String theResult = null;
136
137                String preferedFile = AEWorkspace.getInstance().getDefaultUserConfiguration(".inputFile",
138                                defaultFile == null ? null : defaultFile.getAbsolutePath());
139
140                if (preferedFile != null) {
141                        defaultFile = new File(preferedFile);
142                }
143
144                theResult = preferedFile;
145
146                if (preferedFile == null || !getManager().isConsoleDefaultInput("inputFile", null)) {
147                        FileDialog fileDialog = new FileDialog(JOptionPane.getRootFrame(), "Loading file in property ",
148                                        FileDialog.LOAD);
149
150                        if (defaultFile != null) {
151                                if (defaultFile.isDirectory()) {
152                                        fileDialog.setDirectory(defaultFile.getParent());
153                                } else {
154                                        fileDialog.setFile(defaultFile.getName());
155                                }
156                        }
157
158                        fileDialog.setVisible(true);
159
160                        theResult = fileDialog.getDirectory() + fileDialog.getFile();
161                        AEWorkspace.getInstance().setDefaultUserConfiguration(".inputFile", theResult);
162                }
163
164                return theResult;
165        }
166
167        @Override
168        public void aboutTest(String theTaskName, Node aCurrentAction) {
169                if (theTaskName == null)
170                        return;
171                setAbout(theTaskName, aCurrentAction);
172        }
173
174        protected void setAbout(String theTaskName, Node aCurrentAction) {
175                JPanel aboutPanel = new JPanel();
176                aboutPanel.setLayout(new BorderLayout());
177                aboutPanel.setBorder(BorderFactory.createBevelBorder(10));
178
179                aboutDialog = new JDialog(JOptionPane.getRootFrame(), "About", false);
180                aboutDialog.addWindowListener(new WindowAdapter() {
181                        @Override
182                        public void windowClosing(WindowEvent e) {
183                                UIUtils.saveDialogPreferedView(aboutDialog, "Task:" + theTaskName);
184                        }
185
186                        @Override
187                        public void windowDeactivated(WindowEvent e) {
188                                UIUtils.saveDialogPreferedView(aboutDialog, "Task:" + theTaskName);
189                        }
190                });
191                aboutDialog.getContentPane().add(aboutPanel);
192                UIUtils.applyPreferedView(aboutDialog, "Task:" + theTaskName, 400, 600);
193
194                StringBuilder theBuffer = new StringBuilder();
195
196                Node[] theAuthorNodes = aCurrentAction.getNodes("author");
197
198                theBuffer.append("<html><body>");
199                Node[] descriptions = aCurrentAction.getNodes("description");
200                for (Node description : descriptions) {
201                        String innerXMLText = description.getInnerXMLText();
202                        JParsedown pd = new JParsedown();
203                        innerXMLText = pd.text(innerXMLText);
204                        theBuffer.append(innerXMLText);
205                }
206                if (!ArrayUtils.isEmpty(descriptions) && ArrayUtils.isNotEmpty(theAuthorNodes)) {
207                        theBuffer.append("<hr/>");
208                }
209
210                if (theAuthorNodes != null) {
211                        for (int i = 0; i < theAuthorNodes.length; i++) {
212                                if (theAuthorNodes[i].getAttribute("name") != null)
213                                        theBuffer.append(
214                                                        "Authore: <font color=\"red\">" + theAuthorNodes[i].getAttribute("name") + "</font><br>");
215                                if (theAuthorNodes[i].getAttribute(MAIL_ATTR_NAME) != null)
216                                        theBuffer.append("E-mail: <a href='mailto:" + theAuthorNodes[i].getAttribute(MAIL_ATTR_NAME) + "'>"
217                                                        + theAuthorNodes[i].getAttribute(MAIL_ATTR_NAME) + "</a><br>");
218                                if (theAuthorNodes[i].getAttribute("messager") != null)
219                                        theBuffer.append("Messager: " + theAuthorNodes[i].getAttribute("messager") + "<br>");
220                                if (theAuthorNodes[i].getAttribute("phone") != null)
221                                        theBuffer.append("Phone: " + theAuthorNodes[i].getAttribute("phone") + "<br>");
222                                if (theAuthorNodes.length > 1)
223                                        theBuffer.append("<hr>");
224                        }
225                }
226
227                theBuffer.append("</body></html>");
228
229                JEditorPane aboutPane = new JEditorPane();
230                aboutPane.setContentType("text/html");
231                aboutPane.setText(theBuffer.toString());
232                aboutPane.addHyperlinkListener(new HyperlinkAdapter(manager));
233
234                aboutPane.setEditable(false);
235                aboutPane.setFont(ABOUT_FONT);
236
237                aboutPanel.add(new JScrollPane(aboutPane), BorderLayout.CENTER);
238                aboutButtonPanel.removeAll();
239
240                if (ArrayUtils.isNotEmpty(descriptions) || ArrayUtils.isNotEmpty(theAuthorNodes)) {
241                        JButton aboutButton = new JButton(AEFrame.getIcon("about.png"));
242                        aboutButton.addActionListener(x -> showAboutPanel());
243                        aboutButtonPanel.add(aboutButton);
244                }
245
246                Node[] theDocNodes = aCurrentAction.getNodes("attach/file");
247
248                if (theDocNodes != null && theDocNodes.length > 0) {
249                        for (int i = 0; i < theDocNodes.length; i++) {
250                                JLabel theButton = new AttachButton(this, theDocNodes[i], theTaskName);
251                                aboutButtonPanel.add(theButton);
252                        }
253
254                }
255
256        }
257
258        private void showAboutPanel() {
259                aboutDialog.setVisible(true);
260        }
261
262        @Override
263        public void criticalError(CommandException aThrowable, Processor processor) {
264                if (!aThrowable.isReviewed()) {
265                        String message = ExceptionUtils.getMessage(aThrowable);
266                        if (StringUtils.isBlank(message)) {
267                                message = "Message is absent. Please see stack trace.";
268                        }
269                        OptionPane.showMessageDialog(aeFrame, message, "Critical exception", JOptionPane.ERROR_MESSAGE);
270                }
271                super.criticalError(aThrowable, processor);
272        }
273
274        @Override
275        public void checkFailure(CommandException e, Processor processor) {
276                String message = e.getMessage();
277                if (StringUtils.startsWith(message, "com.ganteater.ae.desktop.util.AssertionFailedError")) {
278                        message = StringUtils.substringAfter(message, "com.ganteater.ae.desktop.util.");
279                }
280                if (message.length() > 1000) {
281                        message = "Check Failure. See log messages.";
282                }
283
284                String formatMessage = formatMessage(message);
285
286                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), formatMessage, "Exception",
287                                JOptionPane.ERROR_MESSAGE);
288
289                super.checkFailure(e, processor);
290        }
291
292        private String formatMessage(String message) {
293                if (message == null) {
294                        return "Something went wrong. The error message is empty.";
295                }
296
297                StringBuilder result = new StringBuilder();
298                int length = 0;
299                for (int i = 0; i < message.length(); i++) {
300                        char c = message.charAt(i);
301                        result.append(c);
302                        length++;
303                        if (c == '\n') {
304                                length = 0;
305                        }
306                        if (c == ' ' && length > 80) {
307                                result.append('\n');
308                                length = 0;
309                        }
310                }
311
312                return result.toString();
313        }
314
315        class PanelTree extends JPanel implements ActionListener {
316                private static final long serialVersionUID = 1L;
317
318                JTree jTree = null;
319
320                boolean fExpandRow = true;
321
322                JButton theButton = new JButton("Collapse");
323
324                public PanelTree(Vector<Vector<String>> theVector) {
325                        super(new BorderLayout());
326                        jTree = new JTree(theVector);
327
328                        jTree.setEditable(true);
329
330                        for (int i = 0; i < jTree.getRowCount(); i++) {
331                                jTree.expandRow(i);
332                        }
333
334                        JScrollPane scroll = new JScrollPane(jTree);
335                        add(scroll, BorderLayout.CENTER);
336                }
337
338                public void actionPerformed(ActionEvent e) {
339                        fExpandRow = !fExpandRow;
340                        if (fExpandRow) {
341                                theButton.setText("Collapse");
342                                for (int i = 0; i < jTree.getRowCount(); i++) {
343                                        jTree.expandRow(i);
344                                }
345                        } else {
346                                theButton.setText("Expand");
347                                for (int i = jTree.getRowCount(); i >= 0; i--) {
348                                        jTree.collapseRow(i);
349                                }
350                        }
351                }
352        }
353
354        @Override
355        public Processor getTaskProcessor() {
356                Processor processor = super.getTaskProcessor();
357                if (processor == null) {
358                        String testFile = getTestFile();
359                        if (testFile == null) {
360                                testFile = getManager().getStartDir().getAbsolutePath();
361                        }
362                        processor = new BaseProcessor(getManager(), getLogger(), new File(testFile).getParentFile());
363                        processor.setTestListener(this);
364                }
365                return processor;
366        }
367
368        public AEFrame getAeFrame() {
369                return aeFrame;
370        }
371
372}