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