KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > j2seproject > J2SEActionProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java.j2seproject;
21
22 import java.awt.Dialog JavaDoc;
23 import java.awt.event.MouseEvent JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.text.MessageFormat JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.Set JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38 import java.util.regex.Pattern JavaDoc;
39 import javax.swing.JButton JavaDoc;
40 import javax.swing.event.ChangeEvent JavaDoc;
41 import javax.swing.event.ChangeListener JavaDoc;
42 import org.apache.tools.ant.module.api.support.ActionUtils;
43 import org.netbeans.api.fileinfo.NonRecursiveFolder;
44 import org.netbeans.api.java.classpath.ClassPath;
45 import org.netbeans.api.java.project.JavaProjectConstants;
46 import org.netbeans.api.project.ProjectInformation;
47 import org.netbeans.api.project.ProjectManager;
48 import org.netbeans.api.project.ProjectUtils;
49 import org.netbeans.modules.java.j2seproject.applet.AppletSupport;
50 import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
51 import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
52 import org.netbeans.modules.java.j2seproject.ui.customizer.MainClassChooser;
53 import org.netbeans.modules.java.j2seproject.ui.customizer.MainClassWarning;
54 import org.netbeans.spi.project.ActionProvider;
55 import org.netbeans.spi.project.support.ant.AntProjectHelper;
56 import org.netbeans.spi.project.support.ant.EditableProperties;
57 import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
58 import org.netbeans.spi.project.ui.support.DefaultProjectOperations;
59 import org.openide.DialogDescriptor;
60 import org.openide.DialogDisplayer;
61 import org.openide.ErrorManager;
62 import org.openide.NotifyDescriptor;
63 import org.openide.awt.MouseUtils;
64 import org.openide.filesystems.FileObject;
65 import org.openide.filesystems.FileStateInvalidException;
66 import org.openide.filesystems.FileUtil;
67 import org.openide.util.Lookup;
68 import org.openide.util.NbBundle;
69
70 /** Action provider of the J2SE project. This is the place where to do
71  * strange things to J2SE actions. E.g. compile-single.
72  */

73 class J2SEActionProvider implements ActionProvider {
74     
75     // Commands available from J2SE project
76
private static final String JavaDoc[] supportedActions = {
77         COMMAND_BUILD,
78         COMMAND_CLEAN,
79         COMMAND_REBUILD,
80         COMMAND_COMPILE_SINGLE,
81         COMMAND_RUN,
82         COMMAND_RUN_SINGLE,
83         COMMAND_DEBUG,
84         COMMAND_DEBUG_SINGLE,
85         JavaProjectConstants.COMMAND_JAVADOC,
86         COMMAND_TEST,
87         COMMAND_TEST_SINGLE,
88         COMMAND_DEBUG_TEST_SINGLE,
89         JavaProjectConstants.COMMAND_DEBUG_FIX,
90         COMMAND_DEBUG_STEP_INTO,
91         COMMAND_DELETE,
92         COMMAND_COPY,
93         COMMAND_MOVE,
94         COMMAND_RENAME,
95     };
96     
97     
98     private static final String JavaDoc[] platformSensitiveActions = {
99         COMMAND_BUILD,
100         COMMAND_REBUILD,
101         COMMAND_COMPILE_SINGLE,
102         COMMAND_RUN,
103         COMMAND_RUN_SINGLE,
104         COMMAND_DEBUG,
105         COMMAND_DEBUG_SINGLE,
106         JavaProjectConstants.COMMAND_JAVADOC,
107         COMMAND_TEST,
108         COMMAND_TEST_SINGLE,
109         COMMAND_DEBUG_TEST_SINGLE,
110         JavaProjectConstants.COMMAND_DEBUG_FIX,
111         COMMAND_DEBUG_STEP_INTO,
112     };
113     
114     // Project
115
J2SEProject project;
116     
117     // Ant project helper of the project
118
private UpdateHelper updateHelper;
119     
120         
121     /** Map from commands to ant targets */
122     Map JavaDoc<String JavaDoc,String JavaDoc[]> commands;
123     
124     /**Set of commands which are affected by background scanning*/
125     final Set JavaDoc<String JavaDoc> bkgScanSensitiveActions;
126     
127     public J2SEActionProvider( J2SEProject project, UpdateHelper updateHelper ) {
128         
129         commands = new HashMap JavaDoc<String JavaDoc,String JavaDoc[]>();
130         commands.put(COMMAND_BUILD, new String JavaDoc[] {"jar"}); // NOI18N
131
commands.put(COMMAND_CLEAN, new String JavaDoc[] {"clean"}); // NOI18N
132
commands.put(COMMAND_REBUILD, new String JavaDoc[] {"clean", "jar"}); // NOI18N
133
commands.put(COMMAND_COMPILE_SINGLE, new String JavaDoc[] {"compile-single"}); // NOI18N
134
// commands.put(COMMAND_COMPILE_TEST_SINGLE, new String[] {"compile-test-single"}); // NOI18N
135
commands.put(COMMAND_RUN, new String JavaDoc[] {"run"}); // NOI18N
136
commands.put(COMMAND_RUN_SINGLE, new String JavaDoc[] {"run-single"}); // NOI18N
137
commands.put(COMMAND_DEBUG, new String JavaDoc[] {"debug"}); // NOI18N
138
commands.put(COMMAND_DEBUG_SINGLE, new String JavaDoc[] {"debug-single"}); // NOI18N
139
commands.put(JavaProjectConstants.COMMAND_JAVADOC, new String JavaDoc[] {"javadoc"}); // NOI18N
140
commands.put(COMMAND_TEST, new String JavaDoc[] {"test"}); // NOI18N
141
commands.put(COMMAND_TEST_SINGLE, new String JavaDoc[] {"test-single"}); // NOI18N
142
commands.put(COMMAND_DEBUG_TEST_SINGLE, new String JavaDoc[] {"debug-test"}); // NOI18N
143
commands.put(JavaProjectConstants.COMMAND_DEBUG_FIX, new String JavaDoc[] {"debug-fix"}); // NOI18N
144
commands.put(COMMAND_DEBUG_STEP_INTO, new String JavaDoc[] {"debug-stepinto"}); // NOI18N
145

146         this.bkgScanSensitiveActions = new HashSet JavaDoc<String JavaDoc>(Arrays.asList(new String JavaDoc[] {
147             COMMAND_RUN,
148             COMMAND_RUN_SINGLE,
149             COMMAND_DEBUG,
150             COMMAND_DEBUG_SINGLE,
151             COMMAND_DEBUG_STEP_INTO
152         }));
153             
154         this.updateHelper = updateHelper;
155         this.project = project;
156     }
157     
158     private FileObject findBuildXml() {
159         return project.getProjectDirectory().getFileObject(GeneratedFilesHelper.BUILD_XML_PATH);
160     }
161     
162     public String JavaDoc[] getSupportedActions() {
163         return supportedActions;
164     }
165     
166     public void invokeAction( final String JavaDoc command, final Lookup context ) throws IllegalArgumentException JavaDoc {
167         if (COMMAND_DELETE.equals(command)) {
168             DefaultProjectOperations.performDefaultDeleteOperation(project);
169             return ;
170         }
171         
172         if (COMMAND_COPY.equals(command)) {
173             DefaultProjectOperations.performDefaultCopyOperation(project);
174             return ;
175         }
176         
177         if (COMMAND_MOVE.equals(command)) {
178             DefaultProjectOperations.performDefaultMoveOperation(project);
179             return ;
180         }
181         
182         if (COMMAND_RENAME.equals(command)) {
183             DefaultProjectOperations.performDefaultRenameOperation(project, null);
184             return ;
185         }
186         
187         Runnable JavaDoc action = new Runnable JavaDoc () {
188             public void run () {
189                 Properties JavaDoc p = new Properties JavaDoc();
190                 String JavaDoc[] targetNames;
191         
192                 targetNames = getTargetNames(command, context, p);
193                 if (targetNames == null) {
194                     return;
195                 }
196                 if (targetNames.length == 0) {
197                     targetNames = null;
198                 }
199                 if (p.keySet().size() == 0) {
200                     p = null;
201                 }
202                 try {
203                     FileObject buildFo = findBuildXml();
204                     if (buildFo == null || !buildFo.isValid()) {
205                         //The build.xml was deleted after the isActionEnabled was called
206
NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle.getMessage(J2SEActionProvider.class,
207                                 "LBL_No_Build_XML_Found"), NotifyDescriptor.WARNING_MESSAGE);
208                         DialogDisplayer.getDefault().notify(nd);
209                     }
210                     else {
211                         ActionUtils.runTarget(buildFo, targetNames, p);
212                     }
213                 }
214                 catch (IOException JavaDoc e) {
215                     ErrorManager.getDefault().notify(e);
216                 }
217             }
218         };
219         
220 // if (this.bkgScanSensitiveActions.contains(command)) {
221
// JMManager.getManager().invokeAfterScanFinished(action, NbBundle.getMessage (J2SEActionProvider.class,"ACTION_"+command)); //NOI18N
222
// }
223
// else {
224
action.run();
225 // }
226
}
227
228     /**
229      * @return array of targets or null to stop execution; can return empty array
230      */

231     /*private*/ String JavaDoc[] getTargetNames(String JavaDoc command, Lookup context, Properties JavaDoc p) throws IllegalArgumentException JavaDoc {
232         if (Arrays.asList(platformSensitiveActions).contains(command)) {
233             final String JavaDoc activePlatformId = this.project.evaluator().getProperty("platform.active"); //NOI18N
234
if (J2SEProjectUtil.getActivePlatform (activePlatformId) == null) {
235                 showPlatformWarning ();
236                 return null;
237             }
238         }
239         String JavaDoc[] targetNames = new String JavaDoc[0];
240         Map JavaDoc<String JavaDoc,String JavaDoc[]> targetsFromConfig = loadTargetsFromConfig();
241         if ( command.equals( COMMAND_COMPILE_SINGLE ) ) {
242             FileObject[] sourceRoots = project.getSourceRoots().getRoots();
243             FileObject[] files = findSourcesAndPackages( context, sourceRoots);
244             boolean recursive = (context.lookup(NonRecursiveFolder.class) == null);
245             if (files != null) {
246                 p.setProperty("javac.includes", ActionUtils.antIncludesList(files, getRoot(sourceRoots,files[0]), recursive)); // NOI18N
247
String JavaDoc[] targets = targetsFromConfig.get(command);
248                 targetNames = (targets != null) ? targets : commands.get(command);
249             }
250             else {
251                 FileObject[] testRoots = project.getTestSourceRoots().getRoots();
252                 files = findSourcesAndPackages(context, testRoots);
253                 p.setProperty("javac.includes", ActionUtils.antIncludesList(files, getRoot(testRoots,files[0]), recursive)); // NOI18N
254
targetNames = new String JavaDoc[] {"compile-test-single"}; // NOI18N
255
}
256         }
257         else if ( command.equals( COMMAND_TEST_SINGLE ) ) {
258             FileObject[] files = findTestSourcesForSources(context);
259             targetNames = setupTestSingle(p, files);
260         }
261         else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) {
262             FileObject[] files = findTestSourcesForSources(context);
263             targetNames = setupDebugTestSingle(p, files);
264         }
265         else if ( command.equals( JavaProjectConstants.COMMAND_DEBUG_FIX ) ) {
266             FileObject[] files = findSources( context );
267             String JavaDoc path = null;
268             if (files != null) {
269                 path = FileUtil.getRelativePath(getRoot(project.getSourceRoots().getRoots(),files[0]), files[0]);
270                 targetNames = new String JavaDoc[] {"debug-fix"}; // NOI18N
271
} else {
272                 files = findTestSources(context, false);
273                 path = FileUtil.getRelativePath(getRoot(project.getTestSourceRoots().getRoots(),files[0]), files[0]);
274                 targetNames = new String JavaDoc[] {"debug-fix-test"}; // NOI18N
275
}
276             // Convert foo/FooTest.java -> foo/FooTest
277
if (path.endsWith(".java")) { // NOI18N
278
path = path.substring(0, path.length() - 5);
279             }
280             p.setProperty("fix.includes", path); // NOI18N
281
}
282         else if (command.equals (COMMAND_RUN) || command.equals(COMMAND_DEBUG) || command.equals(COMMAND_DEBUG_STEP_INTO)) {
283             String JavaDoc config = project.evaluator().getProperty(J2SEConfigurationProvider.PROP_CONFIG);
284             String JavaDoc path;
285             if (config == null || config.length() == 0) {
286                 path = AntProjectHelper.PROJECT_PROPERTIES_PATH;
287             } else {
288                 // Set main class for a particular config only.
289
path = "nbproject/configs/" + config + ".properties"; // NOI18N
290
}
291             EditableProperties ep = updateHelper.getProperties(path);
292
293             // check project's main class
294
// Check whether main class is defined in this config. Note that we use the evaluator,
295
// not ep.getProperty(MAIN_CLASS), since it is permissible for the default pseudoconfig
296
// to define a main class - in this case an active config need not override it.
297
String JavaDoc mainClass = project.evaluator().getProperty(J2SEProjectProperties.MAIN_CLASS);
298             MainClassStatus result = isSetMainClass (project.getSourceRoots().getRoots(), mainClass);
299             if (context.lookup(J2SEConfigurationProvider.Config.class) != null) {
300                 // If a specific config was selected, just skip this check for now.
301
// XXX would ideally check that that config in fact had a main class.
302
// But then evaluator.getProperty(MAIN_CLASS) would be inaccurate.
303
// Solvable but punt on it for now.
304
result = MainClassStatus.SET_AND_VALID;
305             }
306             if (result != MainClassStatus.SET_AND_VALID) {
307                 do {
308                     // show warning, if cancel then return
309
if (showMainClassWarning (mainClass, ProjectUtils.getInformation(project).getDisplayName(), ep,result)) {
310                         return null;
311                     }
312                     // No longer use the evaluator: have not called putProperties yet so it would not work.
313
mainClass = ep.get(J2SEProjectProperties.MAIN_CLASS);
314                     result=isSetMainClass (project.getSourceRoots().getRoots(), mainClass);
315                 } while (result != MainClassStatus.SET_AND_VALID);
316                 try {
317                     if (updateHelper.requestSave()) {
318                         updateHelper.putProperties(path, ep);
319                         ProjectManager.getDefault().saveProject(project);
320                     }
321                     else {
322                         return null;
323                     }
324                 } catch (IOException JavaDoc ioe) {
325                     ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Error while saving project: " + ioe);
326                 }
327             }
328             if (!command.equals(COMMAND_RUN) && /* XXX should ideally look up proper mainClass in evaluator x config */ mainClass != null) {
329                 p.setProperty("debug.class", mainClass); // NOI18N
330
}
331             String JavaDoc[] targets = targetsFromConfig.get(command);
332             targetNames = (targets != null) ? targets : commands.get(command);
333             if (targetNames == null) {
334                 throw new IllegalArgumentException JavaDoc(command);
335             }
336         } else if (command.equals (COMMAND_RUN_SINGLE) || command.equals (COMMAND_DEBUG_SINGLE)) {
337             FileObject[] files = findTestSources(context, false);
338             if (files != null) {
339                 if (command.equals(COMMAND_RUN_SINGLE)) {
340                     targetNames = setupTestSingle(p, files);
341                 } else {
342                     targetNames = setupDebugTestSingle(p, files);
343                 }
344             } else {
345                 FileObject file = findSources(context)[0];
346                 String JavaDoc clazz = FileUtil.getRelativePath(getRoot(project.getSourceRoots().getRoots(),file), file);
347                 p.setProperty("javac.includes", clazz); // NOI18N
348
// Convert foo/FooTest.java -> foo.FooTest
349
if (clazz.endsWith(".java")) { // NOI18N
350
clazz = clazz.substring(0, clazz.length() - 5);
351                 }
352                 clazz = clazz.replace('/','.');
353
354                 if (!J2SEProjectUtil.hasMainMethod (file)) {
355                     if (AppletSupport.isApplet(file)) {
356                         
357                         EditableProperties ep = updateHelper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
358                         String JavaDoc jvmargs = ep.getProperty("run.jvmargs");
359                         
360                         URL JavaDoc url = null;
361
362                         // do this only when security policy is not set manually
363
if ((jvmargs == null) || !(jvmargs.indexOf("java.security.policy") > 0)) { //NOI18N
364
AppletSupport.generateSecurityPolicy(project.getProjectDirectory());
365                             if ((jvmargs == null) || (jvmargs.length() == 0)) {
366                                 ep.setProperty("run.jvmargs", "-Djava.security.policy=applet.policy"); //NOI18N
367
} else {
368                                 ep.setProperty("run.jvmargs", jvmargs + " -Djava.security.policy=applet.policy"); //NOI18N
369
}
370                             updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
371                             try {
372                                 ProjectManager.getDefault().saveProject(project);
373                             } catch (Exception JavaDoc e) {
374                                 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Error while saving project: " + e);
375                             }
376                         }
377                         
378                         if (file.existsExt("html") || file.existsExt("HTML")) { //NOI18N
379
url = copyAppletHTML(file, "html"); //NOI18N
380
} else {
381                             url = generateAppletHTML(file);
382                         }
383                         if (url == null) {
384                             return null;
385                         }
386                         p.setProperty("applet.url", url.toString()); // NOI18N
387
if (command.equals (COMMAND_RUN_SINGLE)) {
388                             targetNames = new String JavaDoc[] {"run-applet"}; // NOI18N
389
} else {
390                             p.setProperty("debug.class", clazz); // NOI18N
391
targetNames = new String JavaDoc[] {"debug-applet"}; // NOI18N
392
}
393                     } else {
394                         NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle.getMessage(J2SEActionProvider.class, "LBL_No_Main_Classs_Found", clazz), NotifyDescriptor.INFORMATION_MESSAGE);
395                         DialogDisplayer.getDefault().notify(nd);
396                         return null;
397                     }
398                 } else {
399                     if (command.equals (COMMAND_RUN_SINGLE)) {
400                         p.setProperty("run.class", clazz); // NOI18N
401
String JavaDoc[] targets = targetsFromConfig.get(command);
402                         targetNames = (targets != null) ? targets : commands.get(COMMAND_RUN_SINGLE);
403                     } else {
404                         p.setProperty("debug.class", clazz); // NOI18N
405
String JavaDoc[] targets = targetsFromConfig.get(command);
406                         targetNames = (targets != null) ? targets : commands.get(COMMAND_DEBUG_SINGLE);
407                     }
408                 }
409             }
410         } else {
411             String JavaDoc[] targets = targetsFromConfig.get(command);
412             targetNames = (targets != null) ? targets : commands.get(command);
413             if (targetNames == null) {
414                 throw new IllegalArgumentException JavaDoc(command);
415             }
416         }
417         J2SEConfigurationProvider.Config c = context.lookup(J2SEConfigurationProvider.Config.class);
418         if (c != null) {
419             String JavaDoc config;
420             if (c.name != null) {
421                 config = c.name;
422             } else {
423                 // Invalid but overrides any valid setting in config.properties.
424
config = "";
425             }
426             p.setProperty(J2SEConfigurationProvider.PROP_CONFIG, config);
427         }
428         return targetNames;
429     }
430     
431     // loads targets for specific commands from shared config property file
432
// returns map; key=command name; value=array of targets for given command
433
private HashMap JavaDoc<String JavaDoc,String JavaDoc[]> loadTargetsFromConfig() {
434         HashMap JavaDoc<String JavaDoc,String JavaDoc[]> targets = new HashMap JavaDoc<String JavaDoc,String JavaDoc[]>(6);
435         String JavaDoc config = project.evaluator().getProperty(J2SEConfigurationProvider.PROP_CONFIG);
436         // load targets from shared config
437
FileObject propFO = project.getProjectDirectory().getFileObject("nbproject/configs/" + config + ".properties");
438         if (propFO == null) {
439             return targets;
440         }
441         Properties JavaDoc props = new Properties JavaDoc();
442         try {
443             InputStream JavaDoc is = propFO.getInputStream();
444             try {
445                 props.load(is);
446             } finally {
447                 is.close();
448             }
449         } catch (IOException JavaDoc ex) {
450             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
451             return targets;
452         }
453         Enumeration JavaDoc propNames = props.propertyNames();
454         while (propNames.hasMoreElements()) {
455             String JavaDoc propName = (String JavaDoc) propNames.nextElement();
456             if (propName.startsWith("$target.")) {
457                 String JavaDoc tNameVal = props.getProperty(propName);
458                 String JavaDoc cmdNameKey = null;
459                 if (tNameVal != null && !tNameVal.equals("")) {
460                     cmdNameKey = propName.substring("$target.".length());
461                     StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(tNameVal.trim(), " ");
462                     List JavaDoc<String JavaDoc> targetNames = new ArrayList JavaDoc<String JavaDoc>(3);
463                     while (stok.hasMoreTokens()) {
464                         targetNames.add(stok.nextToken());
465                     }
466                     targets.put(cmdNameKey, targetNames.toArray(new String JavaDoc[targetNames.size()]));
467                 }
468             }
469         }
470         return targets;
471     }
472     
473     private String JavaDoc[] setupTestSingle(Properties JavaDoc p, FileObject[] files) {
474         FileObject[] testSrcPath = project.getTestSourceRoots().getRoots();
475         FileObject root = getRoot(testSrcPath, files[0]);
476         p.setProperty("test.includes", ActionUtils.antIncludesList(files, root)); // NOI18N
477
p.setProperty("javac.includes", ActionUtils.antIncludesList(files, root)); // NOI18N
478
return new String JavaDoc[] {"test-single"}; // NOI18N
479
}
480
481     private String JavaDoc[] setupDebugTestSingle(Properties JavaDoc p, FileObject[] files) {
482         FileObject[] testSrcPath = project.getTestSourceRoots().getRoots();
483         FileObject root = getRoot(testSrcPath, files[0]);
484         String JavaDoc path = FileUtil.getRelativePath(root, files[0]);
485         // Convert foo/FooTest.java -> foo.FooTest
486
p.setProperty("test.class", path.substring(0, path.length() - 5).replace('/', '.')); // NOI18N
487
return new String JavaDoc[] {"debug-test"}; // NOI18N
488
}
489
490     public boolean isActionEnabled( String JavaDoc command, Lookup context ) {
491         FileObject buildXml = findBuildXml();
492         if ( buildXml == null || !buildXml.isValid()) {
493             return false;
494         }
495         if ( command.equals( COMMAND_COMPILE_SINGLE ) ) {
496             return findSourcesAndPackages( context, project.getSourceRoots().getRoots()) != null
497                     || findSourcesAndPackages( context, project.getTestSourceRoots().getRoots()) != null;
498         }
499         else if ( command.equals( COMMAND_TEST_SINGLE ) ) {
500             return findTestSourcesForSources(context) != null;
501         }
502         else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) {
503             FileObject[] files = findTestSourcesForSources(context);
504             return files != null && files.length == 1;
505         } else if (command.equals(COMMAND_RUN_SINGLE) ||
506                         command.equals(COMMAND_DEBUG_SINGLE) ||
507                         command.equals(JavaProjectConstants.COMMAND_DEBUG_FIX)) {
508             FileObject fos[] = findSources(context);
509             if (fos != null && fos.length == 1) {
510                 return true;
511             }
512             fos = findTestSources(context, false);
513             return fos != null && fos.length == 1;
514         } else {
515             // other actions are global
516
return true;
517         }
518     }
519     
520     
521    
522     // Private methods -----------------------------------------------------
523

524     
525     private static final Pattern JavaDoc SRCDIRJAVA = Pattern.compile("\\.java$"); // NOI18N
526
private static final String JavaDoc SUBST = "Test.java"; // NOI18N
527

528     /** Find selected sources, the sources has to be under single source root,
529      * @param context the lookup in which files should be found
530      */

531     private FileObject[] findSources(Lookup context) {
532         FileObject[] srcPath = project.getSourceRoots().getRoots();
533         for (int i=0; i< srcPath.length; i++) {
534             FileObject[] files = ActionUtils.findSelectedFiles(context, srcPath[i], ".java", true); // NOI18N
535
if (files != null) {
536                 return files;
537             }
538         }
539         return null;
540     }
541
542     private FileObject[] findSourcesAndPackages (Lookup context, FileObject srcDir) {
543         if (srcDir != null) {
544             FileObject[] files = ActionUtils.findSelectedFiles(context, srcDir, null, true); // NOI18N
545
//Check if files are either packages of java files
546
if (files != null) {
547                 for (int i = 0; i < files.length; i++) {
548                     if (!files[i].isFolder() && !"java".equals(files[i].getExt())) {
549                         return null;
550                     }
551                 }
552             }
553             return files;
554         } else {
555             return null;
556         }
557     }
558     
559     private FileObject[] findSourcesAndPackages (Lookup context, FileObject[] srcRoots) {
560         for (int i=0; i<srcRoots.length; i++) {
561             FileObject[] result = findSourcesAndPackages(context, srcRoots[i]);
562             if (result != null) {
563                 return result;
564             }
565         }
566         return null;
567     }
568     
569     /** Find either selected tests or tests which belong to selected source files
570      */

571     private FileObject[] findTestSources(Lookup context, boolean checkInSrcDir) {
572         //XXX: Ugly, should be rewritten
573
FileObject[] testSrcPath = project.getTestSourceRoots().getRoots();
574         for (int i=0; i< testSrcPath.length; i++) {
575             FileObject[] files = ActionUtils.findSelectedFiles(context, testSrcPath[i], ".java", true); // NOI18N
576
if (files != null) {
577                 return files;
578             }
579         }
580         if (checkInSrcDir && testSrcPath.length>0) {
581             FileObject[] files = findSources (context);
582             if (files != null) {
583                 //Try to find the test under the test roots
584
FileObject srcRoot = getRoot(project.getSourceRoots().getRoots(),files[0]);
585                 for (int i=0; i<testSrcPath.length; i++) {
586                     FileObject[] files2 = ActionUtils.regexpMapFiles(files,srcRoot, SRCDIRJAVA, testSrcPath[i], SUBST, true);
587                     if (files2 != null) {
588                         return files2;
589                     }
590                 }
591             }
592         }
593         return null;
594     }
595    
596
597     /** Find tests corresponding to selected sources.
598      */

599     private FileObject[] findTestSourcesForSources(Lookup context) {
600         FileObject[] sourceFiles = findSources(context);
601         if (sourceFiles == null) {
602             return null;
603         }
604         FileObject[] testSrcPath = project.getTestSourceRoots().getRoots();
605         if (testSrcPath.length == 0) {
606             return null;
607         }
608         FileObject[] srcPath = project.getSourceRoots().getRoots();
609         FileObject srcDir = getRoot(srcPath, sourceFiles[0]);
610         for (int i=0; i<testSrcPath.length; i++) {
611             FileObject[] files2 = ActionUtils.regexpMapFiles(sourceFiles, srcDir, SRCDIRJAVA, testSrcPath[i], SUBST, true);
612             if (files2 != null) {
613                 return files2;
614             }
615         }
616         return null;
617     }
618     
619     private FileObject getRoot (FileObject[] roots, FileObject file) {
620         assert file != null : "File can't be null"; //NOI18N
621
FileObject srcDir = null;
622         for (int i=0; i< roots.length; i++) {
623             assert roots[i] != null : "Source Path Root can't be null"; //NOI18N
624
if (FileUtil.isParentOf(roots[i],file) || roots[i].equals(file)) {
625                 srcDir = roots[i];
626                 break;
627             }
628         }
629         return srcDir;
630     }
631     
632     private static enum MainClassStatus {
633         SET_AND_VALID,
634         SET_BUT_INVALID,
635         UNSET
636     }
637
638     /**
639      * Tests if the main class is set
640      * @param sourcesRoots source roots
641      * @param mainClass main class name
642      * @return status code
643      */

644     private MainClassStatus isSetMainClass(FileObject[] sourcesRoots, String JavaDoc mainClass) {
645
646         // support for unit testing
647
if (MainClassChooser.unitTestingSupport_hasMainMethodResult != null) {
648             return MainClassChooser.unitTestingSupport_hasMainMethodResult ? MainClassStatus.SET_AND_VALID : MainClassStatus.SET_BUT_INVALID;
649         }
650
651         if (mainClass == null || mainClass.length () == 0) {
652             return MainClassStatus.UNSET;
653         }
654         if (sourcesRoots.length > 0) {
655             ClassPath bootPath = ClassPath.getClassPath (sourcesRoots[0], ClassPath.BOOT); //Single compilation unit
656
ClassPath compilePath = ClassPath.getClassPath (sourcesRoots[0], ClassPath.COMPILE);
657             ClassPath sourcePath = ClassPath.getClassPath(sourcesRoots[0], ClassPath.SOURCE);
658             if (J2SEProjectUtil.isMainClass (mainClass, bootPath, compilePath, sourcePath)) {
659                 return MainClassStatus.SET_AND_VALID;
660             }
661         }
662         else {
663             ClassPathProviderImpl cpProvider = project.getLookup().lookup(ClassPathProviderImpl.class);
664             if (cpProvider != null) {
665                 ClassPath bootPath = cpProvider.getProjectSourcesClassPath(ClassPath.BOOT);
666                 ClassPath compilePath = cpProvider.getProjectSourcesClassPath(ClassPath.COMPILE);
667                 ClassPath sourcePath = cpProvider.getProjectSourcesClassPath(ClassPath.SOURCE); //Empty ClassPath
668
if (J2SEProjectUtil.isMainClass (mainClass, bootPath, compilePath, sourcePath)) {
669                     return MainClassStatus.SET_AND_VALID;
670                 }
671             }
672         }
673         return MainClassStatus.SET_BUT_INVALID;
674     }
675     
676     /**
677      * Asks user for name of main class
678      * @param mainClass current main class
679      * @param projectName the name of project
680      * @param ep project.properties to possibly edit
681      * @param messgeType type of dialog
682      * @return true if user selected main class
683      */

684     private boolean showMainClassWarning(String JavaDoc mainClass, String JavaDoc projectName, EditableProperties ep, MainClassStatus messageType) {
685         boolean canceled;
686         final JButton JavaDoc okButton = new JButton JavaDoc (NbBundle.getMessage (MainClassWarning.class, "LBL_MainClassWarning_ChooseMainClass_OK")); // NOI18N
687
okButton.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (MainClassWarning.class, "AD_MainClassWarning_ChooseMainClass_OK"));
688         
689         // main class goes wrong => warning
690
String JavaDoc message;
691         switch (messageType) {
692             case UNSET:
693                 message = MessageFormat.format (NbBundle.getMessage(MainClassWarning.class,"LBL_MainClassNotFound"), new Object JavaDoc[] {
694                     projectName
695                 });
696                 break;
697             case SET_BUT_INVALID:
698                 message = MessageFormat.format (NbBundle.getMessage(MainClassWarning.class,"LBL_MainClassWrong"), new Object JavaDoc[] {
699                     mainClass,
700                     projectName
701                 });
702                 break;
703             default:
704                 throw new IllegalArgumentException JavaDoc ();
705         }
706         final MainClassWarning panel = new MainClassWarning (message,project.getSourceRoots().getRoots());
707         Object JavaDoc[] options = new Object JavaDoc[] {
708             okButton,
709             DialogDescriptor.CANCEL_OPTION
710         };
711         
712         panel.addChangeListener (new ChangeListener JavaDoc () {
713            public void stateChanged (ChangeEvent JavaDoc e) {
714                if (e.getSource () instanceof MouseEvent JavaDoc && MouseUtils.isDoubleClick (((MouseEvent JavaDoc)e.getSource ()))) {
715                    // click button and the finish dialog with selected class
716
okButton.doClick ();
717                } else {
718                    okButton.setEnabled (panel.getSelectedMainClass () != null);
719                }
720            }
721         });
722         
723         okButton.setEnabled (false);
724         DialogDescriptor desc = new DialogDescriptor (panel,
725             NbBundle.getMessage (MainClassWarning.class, "CTL_MainClassWarning_Title", ProjectUtils.getInformation(project).getDisplayName()), // NOI18N
726
true, options, options[0], DialogDescriptor.BOTTOM_ALIGN, null, null);
727         desc.setMessageType (DialogDescriptor.INFORMATION_MESSAGE);
728         Dialog JavaDoc dlg = DialogDisplayer.getDefault ().createDialog (desc);
729         dlg.setVisible (true);
730         if (desc.getValue() != options[0]) {
731             canceled = true;
732         } else {
733             mainClass = panel.getSelectedMainClass ();
734             canceled = false;
735             ep.put(J2SEProjectProperties.MAIN_CLASS, mainClass == null ? "" : mainClass);
736         }
737         dlg.dispose();
738
739         return canceled;
740     }
741     
742     private void showPlatformWarning () {
743         final JButton JavaDoc closeOption = new JButton JavaDoc (NbBundle.getMessage(J2SEActionProvider.class, "CTL_BrokenPlatform_Close"));
744         closeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEActionProvider.class, "AD_BrokenPlatform_Close"));
745         final ProjectInformation pi = (ProjectInformation) this.project.getLookup().lookup (ProjectInformation.class);
746         final String JavaDoc projectDisplayName = pi == null ?
747             NbBundle.getMessage (J2SEActionProvider.class,"TEXT_BrokenPlatform_UnknownProjectName")
748             : pi.getDisplayName();
749         final DialogDescriptor dd = new DialogDescriptor(
750             NbBundle.getMessage(J2SEActionProvider.class, "TEXT_BrokenPlatform", projectDisplayName),
751             NbBundle.getMessage(J2SEActionProvider.class, "MSG_BrokenPlatform_Title"),
752             true,
753             new Object JavaDoc[] {closeOption},
754             closeOption,
755             DialogDescriptor.DEFAULT_ALIGN,
756             null,
757             null);
758         dd.setMessageType(DialogDescriptor.WARNING_MESSAGE);
759         final Dialog JavaDoc dlg = DialogDisplayer.getDefault().createDialog(dd);
760         dlg.setVisible(true);
761     }
762
763     private URL JavaDoc generateAppletHTML(FileObject file) {
764         URL JavaDoc url = null;
765         try {
766             String JavaDoc buildDirProp = project.evaluator().getProperty("build.dir"); //NOI18N
767
String JavaDoc classesDirProp = project.evaluator().getProperty("build.classes.dir"); //NOI18N
768
FileObject buildDir = this.updateHelper.getAntProjectHelper().resolveFileObject(buildDirProp);
769             FileObject classesDir = this.updateHelper.getAntProjectHelper().resolveFileObject(classesDirProp);
770
771             if (buildDir == null) {
772                 buildDir = FileUtil.createFolder(project.getProjectDirectory(), buildDirProp);
773             }
774
775             if (classesDir == null) {
776                 classesDir = FileUtil.createFolder(project.getProjectDirectory(), classesDirProp);
777             }
778             String JavaDoc activePlatformName = project.evaluator().getProperty("platform.active"); //NOI18N
779
url = AppletSupport.generateHtmlFileURL(file, buildDir, classesDir, activePlatformName);
780         } catch (FileStateInvalidException fe) {
781             //ingore
782
} catch (IOException JavaDoc ioe) {
783             ErrorManager.getDefault().notify(ioe);
784             return null;
785         }
786         return url;
787     }
788
789     private URL JavaDoc copyAppletHTML(FileObject file, String JavaDoc ext) {
790         URL JavaDoc url = null;
791         try {
792             String JavaDoc buildDirProp = project.evaluator().getProperty("build.dir"); //NOI18N
793
FileObject buildDir = updateHelper.getAntProjectHelper().resolveFileObject(buildDirProp);
794
795             if (buildDir == null) {
796                 buildDir = FileUtil.createFolder(project.getProjectDirectory(), buildDirProp);
797             }
798             
799             FileObject htmlFile = null;
800             htmlFile = file.getParent().getFileObject(file.getName(), "html"); //NOI18N
801
if (htmlFile == null) {
802                 htmlFile = file.getParent().getFileObject(file.getName(), "HTML"); //NOI18N
803
}
804             if (htmlFile == null) {
805                 return null;
806             }
807             
808             FileObject existingFile = buildDir.getFileObject(htmlFile.getName(), htmlFile.getExt());
809             if (existingFile != null) {
810                 existingFile.delete();
811             }
812             
813             FileObject targetHtml = htmlFile.copy(buildDir, file.getName(), ext);
814             
815             if (targetHtml != null) {
816                 String JavaDoc activePlatformName = project.evaluator().getProperty("platform.active"); //NOI18N
817
url = AppletSupport.getHTMLPageURL(targetHtml, activePlatformName);
818             }
819         } catch (FileStateInvalidException fe) {
820             //ingore
821
} catch (IOException JavaDoc ioe) {
822             ErrorManager.getDefault().notify(ioe);
823             return null;
824         }
825         return url;
826     }
827     
828 }
829
Popular Tags