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}