1 19 20 package org.netbeans.bluej; 21 22 import java.awt.Dialog ; 23 import java.awt.event.MouseEvent ; 24 import java.io.IOException ; 25 import java.text.MessageFormat ; 26 import java.util.HashMap ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.Properties ; 30 import java.util.regex.Pattern ; 31 import javax.swing.JButton ; 32 import javax.swing.event.ChangeEvent ; 33 import javax.swing.event.ChangeListener ; 34 import org.apache.tools.ant.module.api.support.ActionUtils; 35 import org.netbeans.api.fileinfo.NonRecursiveFolder; 36 import org.netbeans.api.java.project.JavaProjectConstants; 37 import org.netbeans.api.java.source.SourceUtils; 38 import org.netbeans.api.project.ProjectManager; 39 import org.netbeans.api.project.ProjectUtils; 40 import org.netbeans.spi.project.ActionProvider; 41 import org.netbeans.spi.project.support.ant.AntProjectHelper; 42 import org.netbeans.spi.project.support.ant.EditableProperties; 43 import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; 44 import org.openide.DialogDescriptor; 45 import org.openide.DialogDisplayer; 46 import org.openide.ErrorManager; 47 import org.openide.NotifyDescriptor; 48 import org.openide.awt.MouseUtils; 49 import org.openide.execution.ExecutorTask; 50 import org.openide.filesystems.FileObject; 51 import org.openide.filesystems.FileUtil; 52 import org.openide.util.Lookup; 53 import org.openide.util.NbBundle; 54 55 58 class BluejActionProvider implements ActionProvider { 59 60 private static final String [] supportedActions = { 62 COMMAND_BUILD, 63 COMMAND_CLEAN, 64 COMMAND_REBUILD, 65 COMMAND_COMPILE_SINGLE, 66 COMMAND_RUN, 67 COMMAND_RUN_SINGLE, 68 COMMAND_DEBUG, 69 COMMAND_DEBUG_SINGLE, 70 JavaProjectConstants.COMMAND_JAVADOC, 71 COMMAND_TEST, 72 COMMAND_TEST_SINGLE, 73 COMMAND_DEBUG_TEST_SINGLE, 74 JavaProjectConstants.COMMAND_DEBUG_FIX, 75 COMMAND_DEBUG_STEP_INTO, 76 }; 77 78 79 BluejProject project; 81 82 private UpdateHelper updateHelper; 84 85 86 87 Map commands; 88 89 public BluejActionProvider(BluejProject project, UpdateHelper updateHelper) { 90 91 commands = new HashMap (); 92 commands.put(COMMAND_BUILD, new String [] {"jar"}); commands.put(COMMAND_CLEAN, new String [] {"clean"}); commands.put(COMMAND_REBUILD, new String [] {"clean", "jar"}); commands.put(COMMAND_COMPILE_SINGLE, new String [] {"compile-single"}); commands.put(COMMAND_RUN, new String [] {"run"}); commands.put(COMMAND_RUN_SINGLE, new String [] {"run-single"}); commands.put(COMMAND_DEBUG, new String [] {"debug"}); commands.put(COMMAND_DEBUG_SINGLE, new String [] {"debug-single"}); commands.put(JavaProjectConstants.COMMAND_JAVADOC, new String [] {"javadoc"}); commands.put(COMMAND_TEST, new String [] {"test"}); commands.put(COMMAND_TEST_SINGLE, new String [] {"test-single"}); commands.put(COMMAND_DEBUG_TEST_SINGLE, new String [] {"debug-test"}); commands.put(JavaProjectConstants.COMMAND_DEBUG_FIX, new String [] {"debug-fix"}); commands.put(COMMAND_DEBUG_STEP_INTO, new String [] {"debug-stepinto"}); 108 this.updateHelper = updateHelper; 109 this.project = project; 110 } 111 112 private FileObject findBuildXml() { 113 return project.getProjectDirectory().getFileObject(GeneratedFilesHelper.BUILD_XML_PATH); 114 } 115 116 public String [] getSupportedActions() { 117 return supportedActions; 118 } 119 120 public void invokeAction( final String command, final Lookup context ) throws IllegalArgumentException { 121 Runnable action = new Runnable () { 122 public void run() { 123 Properties p = new Properties (); 124 String [] targetNames; 125 126 targetNames = getTargetNames(command, context, p); 127 if (targetNames == null) { 128 return; 129 } 130 if (targetNames.length == 0) { 131 targetNames = null; 132 } 133 if (p.keySet().size() == 0) { 134 p = null; 135 } 136 try { 137 FileObject buildFo = findBuildXml(); 138 if (buildFo == null || !buildFo.isValid()) { 139 NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle.getMessage(BluejActionProvider.class, 141 "LBL_No_Build_XML_Found"), NotifyDescriptor.WARNING_MESSAGE); 142 DialogDisplayer.getDefault().notify(nd); 143 } else { 144 ExecutorTask task = ActionUtils.runTarget(buildFo, targetNames, p); 145 } 146 } catch (IOException e) { 147 ErrorManager.getDefault().notify(e); 148 } 149 } 150 }; 151 152 action.run(); 153 } 154 155 158 String [] getTargetNames(String command, Lookup context, Properties p) throws IllegalArgumentException { 159 String [] targetNames = new String [0]; 160 if ( command.equals( COMMAND_COMPILE_SINGLE ) ) { 161 FileObject[] sourceRoots = new FileObject[] { project.getProjectDirectory() }; 162 FileObject[] files = findSourcesAndPackages( context, sourceRoots); 163 boolean recursive = (context.lookup(NonRecursiveFolder.class) == null); 164 if (files != null) { 165 p.setProperty("javac.includes", ActionUtils.antIncludesList(files, getRoot(sourceRoots,files[0]), recursive)); targetNames = new String [] {"compile-single"}; } 168 } else if ( command.equals( COMMAND_TEST_SINGLE ) ) { 176 FileObject[] files = findTestSourcesForSources(context); 177 targetNames = setupTestSingle(p, files); 178 } else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) { 179 FileObject[] files = findTestSourcesForSources(context); 180 targetNames = setupDebugTestSingle(p, files); 181 } 182 else if (command.equals(COMMAND_RUN) || command.equals(COMMAND_DEBUG) || command.equals(COMMAND_DEBUG_STEP_INTO)) { 202 EditableProperties ep = updateHelper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH); 203 EditableProperties eprivate = updateHelper.getProperties (AntProjectHelper.PRIVATE_PROPERTIES_PATH); 204 if (eprivate == null) { 205 eprivate = new EditableProperties(); 206 updateHelper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, eprivate); 207 } 208 String mainClass = (String )ep.get ("main.class"); 211 if (mainClass == null) { 221 if (showMainClassWarning(mainClass, ProjectUtils.getInformation(project).getDisplayName(), ep, eprivate, -1)) { 223 return null; 224 } 225 mainClass = (String )ep.get("main.class"); } 227 try { 229 if (updateHelper.requestSave()) { 230 updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep); 231 updateHelper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, eprivate); 232 ProjectManager.getDefault().saveProject(project); 233 } 234 } catch (IOException ioe) { 235 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Error while saving project: " + ioe); 236 } 237 if (!command.equals(COMMAND_RUN)) { 238 p.setProperty("debug.class", mainClass); } 240 241 targetNames = (String [])commands.get(command); 242 if (targetNames == null) { 243 throw new IllegalArgumentException (command); 244 } 245 } else if (command.equals(COMMAND_RUN_SINGLE) || command.equals(COMMAND_DEBUG_SINGLE)) { 246 FileObject[] files = findTestSources(context, false); 247 if (files != null) { 248 if (command.equals(COMMAND_RUN_SINGLE)) { 249 targetNames = setupTestSingle(p, files); 250 } else { 251 targetNames = setupDebugTestSingle(p, files); 252 } 253 } else { 254 FileObject file = findSources(context)[0]; 255 String clazz = FileUtil.getRelativePath(project.getProjectDirectory(), file); 256 p.setProperty("javac.includes", clazz); if (clazz.endsWith(".java")) { clazz = clazz.substring(0, clazz.length() - 5); 260 } 261 clazz = clazz.replace('/','.'); 262 263 if (!hasMainMethod(file)) { 264 NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle.getMessage(BluejActionProvider.class, "LBL_No_Main_Classs_Found", clazz), NotifyDescriptor.INFORMATION_MESSAGE); 265 DialogDisplayer.getDefault().notify(nd); 266 return null; 267 } else { 268 if (command.equals(COMMAND_RUN_SINGLE)) { 269 p.setProperty("run.class", clazz); targetNames = (String [])commands.get(COMMAND_RUN_SINGLE); 271 } else { 272 p.setProperty("debug.class", clazz); targetNames = (String [])commands.get(COMMAND_DEBUG_SINGLE); 274 } 275 } 276 } 277 } else { 278 targetNames = (String [])commands.get(command); 279 if (targetNames == null) { 280 throw new IllegalArgumentException (command); 281 } 282 } 283 return targetNames; 284 } 285 286 private String [] setupTestSingle(Properties p, FileObject[] files) { 287 FileObject[] testSrcPath = new FileObject[] {project.getProjectDirectory()}; 288 FileObject root = getRoot(testSrcPath, files[0]); 289 p.setProperty("test.includes", ActionUtils.antIncludesList(files, root)); p.setProperty("javac.includes", ActionUtils.antIncludesList(files, root)); return new String [] {"test-single"}; } 293 294 private String [] setupDebugTestSingle(Properties p, FileObject[] files) { 295 FileObject[] testSrcPath = new FileObject[] {project.getProjectDirectory()}; 296 FileObject root = getRoot(testSrcPath, files[0]); 297 String path = FileUtil.getRelativePath(root, files[0]); 298 p.setProperty("test.class", path.substring(0, path.length() - 5).replace('/', '.')); return new String [] {"debug-test"}; } 302 303 public boolean isActionEnabled( String command, Lookup context ) { 304 FileObject buildXml = findBuildXml(); 305 if ( buildXml == null || !buildXml.isValid()) { 306 return false; 307 } 308 if ( command.equals( COMMAND_COMPILE_SINGLE ) ) { 309 return findSourcesAndPackages( context, project.getProjectDirectory()) != null 310 || findSourcesAndPackages( context, project.getProjectDirectory()) != null; 311 } else if ( command.equals( COMMAND_TEST_SINGLE ) ) { 312 return findTestSourcesForSources(context) != null; 313 } else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) { 314 FileObject[] files = findTestSourcesForSources(context); 315 return files != null && files.length == 1; 316 } else if (command.equals(COMMAND_RUN_SINGLE) || 317 command.equals(COMMAND_DEBUG_SINGLE) || 318 command.equals(JavaProjectConstants.COMMAND_DEBUG_FIX)) { 319 FileObject fos[] = findSources(context); 320 if (fos != null && fos.length == 1) { 321 return true; 322 } 323 fos = findTestSources(context, false); 324 return fos != null && fos.length == 1; 325 } else { 326 return true; 328 } 329 } 330 331 332 333 335 336 private static final Pattern SRCDIRJAVA = Pattern.compile("\\.java$"); private static final String SUBST = "Test.java"; 339 342 private FileObject[] findSources(Lookup context) { 343 FileObject[] srcPath = new FileObject[] {project.getProjectDirectory()}; 344 for (int i=0; i< srcPath.length; i++) { 345 FileObject[] files = ActionUtils.findSelectedFiles(context, srcPath[i], ".java", true); if (files != null) { 347 return files; 348 } 349 } 350 return null; 351 } 352 353 private FileObject[] findSourcesAndPackages(Lookup context, FileObject srcDir) { 354 if (srcDir != null) { 355 FileObject[] files = ActionUtils.findSelectedFiles(context, srcDir, null, true); if (files != null) { 358 for (int i = 0; i < files.length; i++) { 359 if (!files[i].isFolder() && !"java".equals(files[i].getExt())) { return null; 361 } 362 } 363 } 364 return files; 365 } else { 366 return null; 367 } 368 } 369 370 private FileObject[] findSourcesAndPackages(Lookup context, FileObject[] srcRoots) { 371 for (int i=0; i<srcRoots.length; i++) { 372 FileObject[] result = findSourcesAndPackages(context, srcRoots[i]); 373 if (result != null) { 374 return result; 375 } 376 } 377 return null; 378 } 379 380 382 private FileObject[] findTestSources(Lookup context, boolean checkInSrcDir) { 383 FileObject[] files = ActionUtils.findSelectedFiles(context, project.getProjectDirectory(), "Test.java", true); if (files != null) { 386 return files; 387 } 388 if (checkInSrcDir) { 389 files = findSources(context); 390 if (files != null) { 391 FileObject[] files2 = ActionUtils.regexpMapFiles(files, project.getProjectDirectory(), SRCDIRJAVA, project.getProjectDirectory(), SUBST, true); 393 if (files2 != null) { 394 return files2; 395 } 396 } 397 } 398 return null; 399 } 400 401 402 404 private FileObject[] findTestSourcesForSources(Lookup context) { 405 FileObject[] sourceFiles = findSources(context); 406 if (sourceFiles == null) { 407 return null; 408 } 409 FileObject srcDir = project.getProjectDirectory(); 410 FileObject[] files2 = ActionUtils.regexpMapFiles(sourceFiles, srcDir, SRCDIRJAVA, project.getProjectDirectory(), SUBST, true); 411 if (files2 != null) { 412 return files2; 413 } 414 return null; 415 } 416 417 private FileObject getRoot(FileObject[] roots, FileObject file) { 418 assert file != null : "File can't be null"; FileObject srcDir = null; 420 for (int i=0; i< roots.length; i++) { 421 assert roots[i] != null : "Source Path Root can't be null"; if (FileUtil.isParentOf(roots[i],file) || roots[i].equals(file)) { 423 srcDir = roots[i]; 424 break; 425 } 426 } 427 return srcDir; 428 } 429 430 431 457 489 490 491 512 520 private boolean showMainClassWarning (String mainClass, String projectName, EditableProperties ep, EditableProperties eprivate, int messageType) { 521 boolean canceled; 522 final JButton okButton = new JButton ("OK"); 525 String message; 527 switch (messageType) { 528 case -1: 529 message = MessageFormat.format (NbBundle.getMessage(BluejActionProvider.class, "LBL_MainClassNotFound"), new Object [] { 530 projectName 531 }); 532 break; 533 case -2: 534 message = MessageFormat.format (NbBundle.getMessage(BluejActionProvider.class, "LBL_MainClassWrong"), new Object [] { 535 mainClass, 536 projectName 537 }); 538 break; 539 default: 540 throw new IllegalArgumentException (); 541 } 542 final MainClassWarning panel = new MainClassWarning (message, new FileObject[] { project.getProjectDirectory() } ); 543 panel.setArguments(eprivate.getProperty("application.args")); panel.setSelectedMainClass(ep.getProperty("main.class")); Object [] options = new Object [] { 546 okButton, 547 DialogDescriptor.CANCEL_OPTION 548 }; 549 550 panel.addChangeListener (new ChangeListener () { 551 public void stateChanged (ChangeEvent e) { 552 if (e.getSource () instanceof MouseEvent && MouseUtils.isDoubleClick (((MouseEvent )e.getSource ()))) { 553 okButton.doClick (); 555 } else { 556 okButton.setEnabled (panel.getSelectedMainClass () != null); 557 } 558 } 559 }); 560 561 okButton.setEnabled (false); 562 DialogDescriptor desc = new DialogDescriptor (panel, "Run Project", true, options, options[0], DialogDescriptor.BOTTOM_ALIGN, null, null); 564 desc.setMessageType (DialogDescriptor.INFORMATION_MESSAGE); 565 Dialog dlg = DialogDisplayer.getDefault ().createDialog (desc); 566 dlg.setVisible (true); 567 if (desc.getValue() != options[0]) { 568 canceled = true; 569 } else { 570 mainClass = panel.getSelectedMainClass (); 571 canceled = false; 572 ep.put ("main.class", mainClass == null ? "" : mainClass); eprivate.put("application.args", panel.getArguments()); } 575 dlg.dispose(); 576 577 return canceled; 578 } 579 580 581 586 public static boolean hasMainMethod(FileObject fo) { 587 if (fo == null) { 588 return false; 590 } 591 return !SourceUtils.getMainClasses(fo).isEmpty(); 592 } 593 594 } 595 | Popular Tags |