KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > junit > wizards > Utils


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 2004-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.junit.wizards;
21
22 import java.io.IOException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Map JavaDoc;
29 import org.netbeans.api.java.project.JavaProjectConstants;
30 import org.netbeans.api.java.queries.UnitTestForSourceQuery;
31 import org.netbeans.api.project.FileOwnerQuery;
32 import org.netbeans.api.project.Project;
33 import org.netbeans.api.project.ProjectUtils;
34 import org.netbeans.api.project.SourceGroup;
35 import org.netbeans.modules.junit.TestUtil;
36 import org.openide.ErrorManager;
37 import org.openide.cookies.EditorCookie;
38 import org.openide.filesystems.FileObject;
39 import org.openide.filesystems.FileUtil;
40 import org.openide.filesystems.URLMapper;
41 import org.openide.loaders.DataObject;
42 import org.openide.loaders.DataObjectNotFoundException;
43 import org.openide.text.Line;
44 import org.openide.util.Utilities;
45
46 /**
47  *
48  * @author Marian Petras
49  */

50 public final class Utils {
51
52     /** */
53     private final Project project;
54     /** <!-- PENDING --> */
55     private boolean sourceGroupsOnly = true;
56     /** <!-- PENDING --> */
57     private SourceGroup[] javaSourceGroups;
58     /** <!-- PENDING --> */
59     private Map JavaDoc<SourceGroup,Object JavaDoc[]> sourcesToTestsMap;
60     /** <!-- PENDING --> */
61     private Map JavaDoc<FileObject,Object JavaDoc> foldersToSourceGroupsMap;
62     
63     /**
64      * <!-- PENDING -->
65      */

66     public Utils(Project project) {
67         this.project = project;
68     }
69     
70     /** <!-- PENDING --> */
71     static FileObject findTestsRoot(Project project) {
72         final SourceGroup[] sourceGroups
73                 = new Utils(project).getJavaSourceGroups();
74         for (int i = 0; i < sourceGroups.length; i++) {
75             FileObject root = sourceGroups[i].getRootFolder();
76             if (root.getName().equals(EmptyTestCaseWizard.TESTS_ROOT_NAME)) {
77                 return root;
78             }
79         }
80         return null;
81     }
82     
83     /** */
84     static FileObject getPackageFolder(
85             FileObject root,
86             String JavaDoc pkgName) throws IOException JavaDoc {
87         String JavaDoc relativePathName = pkgName.replace('.', '/');
88         FileObject folder = root.getFileObject(relativePathName);
89         if (folder == null) {
90             folder = FileUtil.createFolder(root, relativePathName);
91         }
92         return folder;
93     }
94     
95     /**
96      * Identifies and collects <code>SourceGroup</code>s and folders
97      * of a given project which may serve as target folders for newly created
98      * test classes.
99      *
100      * @param project project whose folders are to be checked
101      * @param sourceGroupsOnly return only <code>SourceGroup</code>s
102      * - ignore target folders not having
103      * a corresponding <code>SourceGroup</code>
104      * @return collection which may contain <code>FileObject</code>s
105      * or <code>SourceGroup</code>s (or both);
106      * it may be empty but not <code>null</code>
107      * @author Marian Petras
108      */

109     static Collection JavaDoc getTestTargets(Project project,
110                                      final boolean sourceGroupsOnly) {
111         final Utils utils = new Utils(project);
112         return utils.getTestTargets(sourceGroupsOnly);
113     }
114     
115     /**
116      * Builds a map that containing relation between <code>SourceGroup</code>s
117      * and their respective test <code>SourceGroup</code>s.
118      * Each entry of the map contains a <code>SourceGroup</code> as a key
119      * and an array of test <code>SourceGroup</code>s returned by
120      * <code>UnitTestForSourceQuery</code> for that <code>SourceGroup</code>
121      * as a value. <code>SourceGroup</code>s that have no test
122      * <code>SourceGroup</code>s assigned are omitted, i.e. the resulting
123      * map does not contain entries that would have empty arrays as their
124      * values.
125      *
126      * @param project project whose <code>SourceGroup</code>s are to be
127      * checked
128      * @param sourceGroupsOnly return only <code>SourceGroup</code>s
129      * - ignore test folders not having
130      * a corresponding <code>SourceGroup</code>
131      * @return created map - may be empty, may be unmodifiable
132      * never <code>null</code>
133      */

134     static Map JavaDoc getSourcesToTestsMap(Project project,
135                                     final boolean sourceGroupsOnly) {
136         final Utils utils = new Utils(project);
137         return utils.getSourcesToTestsMap(sourceGroupsOnly);
138     }
139     
140     /**
141      * <!-- PENDING -->
142      */

143     Project getProject() {
144         return project;
145     }
146
147     /**
148      * Identifies and collects <code>SourceGroup</code>s and folders
149      * which may serve as target folders for newly created test classes.
150      *
151      * @param sourceGroupsOnly return only <code>SourceGroup</code>s
152      * (skip target folders without matching
153      * <code>SourceGroup</code>)
154      * @return collection which may contain <code>FileObject</code>s
155      * or <code>SourceGroup</code>s (or both);
156      * it may be empty but not <code>null</code>
157      * @see #getTestTargets(Project, boolean)
158      * @author Marian Petras
159      */

160     private Collection JavaDoc<Object JavaDoc> getTestTargets(final boolean sourceGroupsOnly) {
161
162         /*
163          * Idea:
164          * 1) Get all SourceGroups
165          * 2) For each SourceGroup, ask UnitTestForSourceQuery for its related
166          * test SourceGroups
167          *
168          * Union of all SourceGroups returned by UnitTestForSourceQuery
169          * are the test SourceGroups.
170          */

171
172         /* .) get all SourceGroups: */
173         final SourceGroup[] sourceGroups = getJavaSourceGroups();
174         if (sourceGroups.length == 0) {
175             return Collections.<Object JavaDoc>emptyList();
176         }
177
178         /* .) */
179         createFoldersToSourceGroupsMap(sourceGroups);
180         Object JavaDoc testTargetsUnion[] = new Object JavaDoc[sourceGroups.length];
181         int size = 0;
182         for (int i = 0; i < sourceGroups.length; i++) {
183             Object JavaDoc[] testTargets = getTestTargets(sourceGroups[i],
184                                                   sourceGroupsOnly);
185             size = merge(testTargets, testTargetsUnion, size);
186         }
187
188         if (size != testTargetsUnion.length) {
189             testTargetsUnion = TestUtil.skipNulls(testTargetsUnion, new Object JavaDoc[0]);
190         }
191
192         return Collections.unmodifiableCollection(
193                       Arrays.asList(testTargetsUnion));
194     }
195     
196     /**
197      * <!-- PENDING -->
198      */

199     Map JavaDoc<SourceGroup,Object JavaDoc[]> getSourcesToTestsMap() {
200         if (sourcesToTestsMap == null) {
201             sourcesToTestsMap = createSourcesToTestsMap(sourceGroupsOnly);
202         }
203         return sourcesToTestsMap;
204     }
205     
206     /**
207      * <!-- PENDING -->
208      */

209     Map JavaDoc<SourceGroup,Object JavaDoc[]> getSourcesToTestsMap(final boolean sourceGroupsOnly) {
210         if (sourceGroupsOnly != this.sourceGroupsOnly) {
211             sourcesToTestsMap = null;
212             this.sourceGroupsOnly = sourceGroupsOnly;
213         }
214         return getSourcesToTestsMap();
215     }
216
217     /**
218      * Builds a map that containing relation between <code>SourceGroup</code>s
219      * and their respective test <code>SourceGroup</code>s.
220      * Each entry of the map contains a <code>SourceGroup</code> as a key
221      * and an array of test <code>SourceGroup</code>s returned by
222      * <code>UnitTestForSourceQuery</code> for that <code>SourceGroup</code>
223      * as a value. <code>SourceGroup</code>s that have no test
224      * <code>SourceGroup</code>s assigned are omitted, i.e. the resulting
225      * map does not contain entries that would have empty arrays as their
226      * values.
227      *
228      * @param sourceGroupsOnly return only <code>SourceGroup</code>s
229      * - ignore test folders not having
230      * a corresponding <code>SourceGroup</code>
231      * @return created map - may be empty, may be unmodifiable,
232      * cannot be <code>null</code>
233      */

234     private Map JavaDoc<SourceGroup,Object JavaDoc[]> createSourcesToTestsMap(final boolean sourceGroupsOnly) {
235         
236         /*
237          * Idea:
238          * 1) Get all SourceGroups
239          * 2) For each SourceGroup, ask UnitTestForSourceQuery for its related
240          * test SourceGroups
241          */

242
243         /* .) get all SourceGroups: */
244         final SourceGroup[] sourceGroups = getJavaSourceGroups();
245         if (sourceGroups.length == 0) {
246             return Collections.<SourceGroup,Object JavaDoc[]>emptyMap();
247         }
248
249         /* .) get test SourceGroups for each SourceGroup: */
250         createFoldersToSourceGroupsMap(sourceGroups);
251         Object JavaDoc testTargetsUnion[] = new Object JavaDoc[sourceGroups.length];
252         Map JavaDoc<SourceGroup,Object JavaDoc[]> map;
253         map = new HashMap JavaDoc<SourceGroup,Object JavaDoc[]>(
254                             (int) ((float) sourceGroups.length * 1.33f + 0.5f),
255                             .75f);
256         for (int i = 0; i < sourceGroups.length; i++) {
257             Object JavaDoc[] testTargets = getTestTargets(sourceGroups[i],
258                                                   sourceGroupsOnly);
259             if (testTargets.length != 0) {
260                 map.put(sourceGroups[i], testTargets);
261             }
262         }
263         if (map.isEmpty()) {
264             return Collections.<SourceGroup,Object JavaDoc[]>emptyMap();
265         }
266         if (map.size() == 1) {
267             Map.Entry JavaDoc<SourceGroup,Object JavaDoc[]> entry
268                     = map.entrySet().iterator().next();
269             return Collections.singletonMap(entry.getKey(), entry.getValue());
270         }
271
272         final int finalMapSize = map.size();
273         if (finalMapSize >= (sourceGroups.length - 5)) {
274             return map;
275         }
276         
277         final Map JavaDoc<SourceGroup,Object JavaDoc[]> targetMap;
278         targetMap = new HashMap JavaDoc<SourceGroup,Object JavaDoc[]>(
279                                     (int) ((float) finalMapSize * 1.25f + .5f),
280                                     .8f);
281         targetMap.putAll(map);
282         return targetMap;
283     }
284
285     /**
286      * Merges a given set of <code>FileObject</code>s and
287      * <code>SourceGroup</code>s to the given target set (which may contain
288      * same types of elements).
289      * The source set (array) is not modified during merge. The target
290      * set (array) is not modified otherwise than by adding (overwriting
291      * <code>null</code>s) elements from the source set or by replacing elements
292      * with equivalent elements (i.e. pointing to the same folder). Elements are
293      * always added after the last non-<code>null</code> element of the target
294      * set. After the merge, it is guaranteed that all <code>null</code>
295      * elements of the target array are located at the end. The above
296      * constraints can only be fulfilled if parameter
297      * <code>currTargetSetSize</code> is correct and if all <code>null</code>
298      * elements of the target set are placed at the end of the array at the
299      * moment this method is called. The target array must contain enough
300      * <code>null</code> elements so that all elements to be added to the set
301      * can fit.
302      *
303      * @param setToAdd elements to be added to the target set
304      * - must not contain <code>null</code> elements
305      * @param targetSet array to add elements to
306      * @param currTargetSetSize current count of non-null elements in the
307      * target set (<code>null</code> elements are
308      * always at the end of the array)
309      * @return new size of the target set
310      * (number of non-<code>null</code> elements)
311      */

312     private static int merge(final Object JavaDoc[] setToAdd,
313                              final Object JavaDoc[] targetSet,
314                              final int currTargetSetSize) {
315         if (setToAdd.length == 0) {
316             return currTargetSetSize;
317         }
318         if (currTargetSetSize == 0) {
319             System.arraycopy(setToAdd, 0, targetSet, 0, setToAdd.length);
320             return setToAdd.length;
321         }
322         int targetSetSize = currTargetSetSize;
323         toAdd:
324         for (int i = 0; i < setToAdd.length; i++) {
325             final Object JavaDoc objToAdd = setToAdd[i];
326             for (int j = 0; j < targetSetSize; j++) {
327                 final Object JavaDoc chosen = chooseTarget(targetSet[j], objToAdd);
328                 if (chosen != null) { //both point to the same folder
329
targetSet[j] = chosen;
330                     continue toAdd;
331                 }
332             }
333             targetSet[targetSetSize++] = objToAdd;
334         }
335         return targetSetSize;
336     }
337
338     /**
339      * Finds whether the given two objects defining a target folder are equal
340      * or not and if so, suggests which one is preferred.
341      * Each of the folder targets may be either a <code>SourceGroup<code>
342      * object or a <code>FileObject</code> folder. If both targets point
343      * to the same folder, one of them which is preferred is returned.
344      * Otherwise <code>null</code> is returned.
345      * <p>
346      * If both targets are <code>SourceGroup</code>s, the first target is used.
347      * If none of the targets is a <code>SourceGroup</code>, the first target is
348      * used.
349      * Otherwise (i.e. one target is a <code>SourceGroup</code>,
350      * the other is not), the <code>SourceGroup</code> target is returned.
351      *
352      * @param target1 one target
353      * @param target2 second target
354      * @return <code>null</code> if the two targets define different folders;
355      * or the preferred one (of the passed targets) if the two
356      * are equal
357      */

358     private static Object JavaDoc chooseTarget(Object JavaDoc target1, Object JavaDoc target2) {
359         final boolean isGroup1 = target1 instanceof SourceGroup;
360         final boolean isGroup2 = target2 instanceof SourceGroup;
361
362         assert isGroup1 || (target1 instanceof FileObject);
363         assert isGroup2 || (target2 instanceof FileObject);
364         
365         if (isGroup1 && isGroup2 && target1.equals(target2)) {
366             return target1;
367         }
368
369         final FileObject folder1 = isGroup1
370                                    ? ((SourceGroup) target1).getRootFolder()
371                                    : ((FileObject) target1);
372         final FileObject folder2 = isGroup2
373                                    ? ((SourceGroup) target2).getRootFolder()
374                                    : ((FileObject) target2);
375         if (!(folder1.isFolder())) {
376             throw new IllegalArgumentException JavaDoc("target1: not a folder");//NOI18N
377
}
378         if (!(folder2.isFolder())) {
379             throw new IllegalArgumentException JavaDoc("target2: not a folder");//NOI18N
380
}
381         if (folder1.equals(folder2)) {
382             return (isGroup1 == isGroup2) ? target1
383                                           : (isGroup1 ? target1 : target2);
384         }
385         return null;
386     }
387
388     /**
389      * Returns test targets for the given <code>SourceGroup</code>.
390      * The test targets are folders which are searched when tests for a class
391      * from the <code>SourceGroup</code> are to be found. Each of the returned
392      * test targets may be either <code>SourceGroup</code> (representing
393      * a folder plus additional information such as display name) or simply
394      * a <code>FileObject</code> representing a folder.
395      * If parameter <code>includeSourceGroups</code> is <code>false</code>,
396      * only <code>SourceGroup<code>s are returned (target folders without
397      * corresponding <code>SourceGroup</code>s are ignored).
398      *
399      * @param src source group to find test targets for
400      * @param sourceGroupsOnly skip target folders without matching
401      * <code>SourceGroup</code>
402      * @return array which may contain <code>FileObject</code>s
403      * or <code>SourceGroup</code>s (or both);
404      * it may be empty but not <code>null</code>
405      * @see TestUtil#getFileObject2SourceGroupMap
406      */

407     public Object JavaDoc[] getTestTargets(SourceGroup sourceGroup,
408                                    final boolean sourceGroupsOnly) {
409         
410         /* .) find test root folders: */
411         final FileObject[] testFolders
412                     = getTestFoldersRaw(sourceGroup.getRootFolder());
413         
414         if (testFolders.length == 0) {
415             return new Object JavaDoc[0];
416         }
417         
418         /* .) find SourceGroups corresponding to the FileObjects: */
419         final Object JavaDoc[] targets = new Object JavaDoc[testFolders.length];
420         for (int i = 0; i < targets.length; i++) {
421             final FileObject testFolder = testFolders[i];
422             if (testFolder == null) {
423                 continue;
424             }
425             Object JavaDoc srcGroup = foldersToSourceGroupsMap.get(testFolder);
426             targets[i] = (srcGroup != null)
427                          ? srcGroup
428                          : sourceGroupsOnly ? null : testFolder;
429         }
430         return TestUtil.skipNulls(targets, new Object JavaDoc[0]);
431     }
432     
433     /**
434      * Returns an array of test folders corresponding to the given source
435      * folder - may contain <code>null</code>s.
436      *
437      * @param srcFolder <code>FileObject</code> representing source code root,
438      * for which test root folders should be found
439      * @return array of <code>FileObject</code>s representing test root
440      * folders, possibly with superfluous <code>null</code> elements
441      * @see #getSourceFoldersRaw
442      */

443     public FileObject[] getTestFoldersRaw(FileObject srcFolder) {
444         return getFileObjects(UnitTestForSourceQuery.findUnitTests(srcFolder),
445                               true);
446     }
447     
448     /**
449      * Returns an array of source folders corresponding to the given test
450      * folder - may contain <code>null</code>s.
451      *
452      * @param srcFolder <code>FileObject</code> representing source code root,
453      * for which source root folders should be found
454      * @return array of <code>FileObject</code>s representing source root
455      * folders, possibly with superfluous <code>null</code> elements
456      * @see #getTestFoldersRaw
457      */

458     public FileObject[] getSourceFoldersRaw(FileObject testFolder) {
459         return getFileObjects(UnitTestForSourceQuery.findSources(testFolder),
460                               false);
461     }
462     
463     /**
464      * Returns <code>FileObject</code>s represented by the given URLs.
465      *
466      * @param rootURLs URLs representing <code>FileObject</code>s
467      * @param srcToTest <code>true</code> if we are searching for test
468      * folders, <code>false</code> if we are searching
469      * for source folders - affects only text of warning
470      * log messages
471      * @return array of <code>FileObject</code>s representing source root
472      * folders, possibly with superfluous <code>null</code> elements
473      */

474     private FileObject[] getFileObjects(final URL JavaDoc[] rootURLs,
475                                         final boolean srcToTest) {
476         if (rootURLs.length == 0) {
477             return new FileObject[0];
478         }
479         
480         FileObject[] sourceRoots = new FileObject[rootURLs.length];
481         for (int i = 0; i < rootURLs.length; i++) {
482             if ((sourceRoots[i] = URLMapper.findFileObject(rootURLs[i]))
483                     == null) {
484                 final int severity = ErrorManager.INFORMATIONAL;
485                 if (ErrorManager.getDefault().isLoggable(severity)) {
486                     ErrorManager.getDefault().log(
487                             severity,
488                             (srcToTest ? "Test" : "Source") //NOI18N
489
+ " directory " + rootURLs[i] //NOI18N
490
+ " declared by project " //NOI18N
491
+ ProjectUtils.getInformation(project).getName()
492                             + " does not exist."); //NOI18N
493
}
494                 continue;
495             }
496             Project sourceRootOwner = FileOwnerQuery.getOwner(sourceRoots[i]);
497             if (!project.equals(sourceRootOwner)) {
498                 sourceRoots[i] = null;
499                 
500                 int severity = ErrorManager.INFORMATIONAL;
501                 if (ErrorManager.getDefault().isNotifiable(severity)) {
502                     ErrorManager.getDefault().notify(
503                         severity,
504                         new IllegalStateException JavaDoc(
505                             "Malformed project: Found test root (" + //NOI18N
506
rootURLs[i] + ')' + ' ' +
507                                 (sourceRootOwner == null
508                                         ? "does not belong to any" //NOI18N
509
: "belongs to a different") + //NOI18N
510
" project.")); //NOI18N
511
}
512                 continue;
513             }
514         }
515         return sourceRoots;
516     }
517
518     /**
519      */

520     public static FileObject[] skipNulls(final FileObject[] fileObjs) {
521         if (fileObjs.length == 0) {
522             return fileObjs;
523         }
524         
525         int nullsCount = 0;;
526         for (int i = 0; i < fileObjs.length; i++) {
527             if (fileObjs[i] == null) {
528                 nullsCount++;
529             }
530         }
531         
532         if (nullsCount == 0) {
533             return fileObjs;
534         }
535         if (nullsCount == fileObjs.length) {
536             return new FileObject[0];
537         }
538         
539         final FileObject[] fileObjsNew
540                 = new FileObject[fileObjs.length - nullsCount];
541         int index = 0, indexNew = 0;
542         while (indexNew < fileObjsNew.length) {
543             FileObject fileObj = fileObjs[index++];
544             if (fileObj != null) {
545                 fileObjsNew[indexNew++] = fileObj;
546             }
547         }
548         return fileObjsNew;
549     }
550
551     /**
552      * Creates a map mapping folders to source groups.
553      * For a folder as a key, the map returns the source group having that
554      * folder as a root. The created map is stored to variable
555      * {@link #foldersToSourceGroupsMap}.
556      *
557      * @param sourceGroup source group to create a map from
558      * @author Marian Petras
559      */

560     private void createFoldersToSourceGroupsMap(
561             final SourceGroup[] sourceGroups) {
562         Map JavaDoc<FileObject,Object JavaDoc> result;
563
564         if (sourceGroups.length == 0) {
565             result = Collections.<FileObject,Object JavaDoc>emptyMap();
566         } else {
567             result = new HashMap JavaDoc<FileObject,Object JavaDoc>(2 * sourceGroups.length,
568                                                     .5f);
569             for (SourceGroup sourceGroup : sourceGroups) {
570                 result.put(sourceGroup.getRootFolder(), sourceGroup);
571             }
572         }
573
574         foldersToSourceGroupsMap = result;
575     }
576     
577     /**
578      * <!-- PENDING -->
579      */

580     public SourceGroup[] getJavaSourceGroups() {
581         if (javaSourceGroups == null) {
582             javaSourceGroups = ProjectUtils.getSources(project).getSourceGroups(
583                                         JavaProjectConstants.SOURCES_TYPE_JAVA);
584         }
585         return javaSourceGroups;
586     }
587     
588     /**
589      * Finds a <code>SourceGroup</code> having the specified root folder.
590      * If there are more <code>SourceGroup</code>s matching, the first one
591      * (according to the order of elements in the array) is returned.
592      *
593      * @param sourceGroups source groups to test
594      * @param rootFolder root folder of a source group to be found
595      * @return the found <code>SourceGroup</code>;
596      * or <code>null</code> if no matching <code>SourceGroup</code>
597      * was found
598      */

599     private static SourceGroup findSourceGroup(SourceGroup[] sourceGroups,
600                                                FileObject rootFolder) {
601         for (int i = 0; i < sourceGroups.length; i++) {
602             if (sourceGroups[i].getRootFolder().equals(rootFolder)) {
603                 return sourceGroups[i];
604             }
605         }
606         return (SourceGroup) null;
607     }
608     
609     static boolean isValidClassName(String JavaDoc className) {
610         if (className.length() == 0) {
611             return false;
612         }
613         char[] chars = className.toCharArray();
614         int segmentStart = 0;
615         int i;
616         for (i = 0; i < chars.length; i++) {
617             if (chars[i] == '.') {
618                 if (i == segmentStart) {
619                     return false; //empty segment
620
}
621                 if (!Utilities.isJavaIdentifier(
622                         className.substring(segmentStart, i))) {
623                     return false; //illegal name of the segment
624
}
625                 segmentStart = i + 1;
626             }
627         }
628         if (i == segmentStart) {
629             return false; //empty last segment
630
}
631         if (!Utilities.isJavaIdentifier(
632                 className.substring(segmentStart, chars.length))) {
633             return false; //illegal name of the last segment
634
}
635         return true;
636     }
637     
638     /**
639      */

640     public static void openFile(FileObject file, int lineNum) {
641
642         /*
643          * Most of the following code was copied from the Ant module, method
644          * org.apache.tools.ant.module.run.Hyperlink.outputLineAction(...).
645          */

646
647         if (file == null) {
648             java.awt.Toolkit.getDefaultToolkit().beep();
649             return;
650         }
651
652         try {
653             DataObject dob = DataObject.find(file);
654             EditorCookie ed = (EditorCookie)
655                               dob.getCookie(EditorCookie.class);
656             if (ed != null && /* not true e.g. for *_ja.properties */
657                               file == dob.getPrimaryFile()) {
658                 if (lineNum == -1) {
659                     // OK, just open it.
660
ed.open();
661                 } else {
662                     ed.openDocument();//XXX getLineSet doesn't do it for you
663
try {
664                         Line l = ed.getLineSet().getOriginal(lineNum - 1);
665                         if (!l.isDeleted()) {
666                             l.show(Line.SHOW_GOTO);
667                         }
668                     } catch (IndexOutOfBoundsException JavaDoc ioobe) {
669                         // Probably harmless. Bogus line number.
670
ed.open();
671                     }
672                 }
673             } else {
674                 java.awt.Toolkit.getDefaultToolkit().beep();
675             }
676         } catch (DataObjectNotFoundException ex1) {
677             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex1);
678         } catch (IOException JavaDoc ex2) {
679             // XXX see above, should not be necessary to call openDocument
680
// at all
681
ErrorManager.getDefault().notify(ErrorManager.WARNING, ex2);
682         }
683     }
684         
685 }
686
Popular Tags