001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.java.source.usages;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.net.URL;
047: import java.util.Collection;
048: import java.util.List;
049: import java.util.Map;
050: import java.util.logging.Handler;
051: import java.util.logging.Level;
052: import java.util.logging.LogRecord;
053: import java.util.logging.Logger;
054: import javax.swing.event.ChangeListener;
055: import org.netbeans.api.java.classpath.ClassPath;
056: import org.netbeans.api.java.classpath.GlobalPathRegistry;
057: import org.netbeans.api.java.source.JavaSource;
058: import org.netbeans.api.java.source.JavaSource.Phase;
059: import org.netbeans.api.java.source.SourceUtils;
060: import org.netbeans.api.java.source.SourceUtilsTestUtil;
061: import org.netbeans.api.java.source.SourceUtilsTestUtil.TestSourceLevelQueryImplementation;
062: import org.netbeans.api.java.source.TestUtilities;
063: import org.netbeans.junit.NbTestCase;
064: import org.netbeans.modules.java.source.tasklist.FirstParseCatcher;
065: import org.netbeans.modules.java.source.tasklist.TaskCache;
066: import org.netbeans.modules.java.source.tasklist.TasklistSettings;
067: import org.netbeans.spi.java.classpath.ClassPathProvider;
068: import org.netbeans.spi.java.classpath.support.ClassPathSupport;
069: import org.netbeans.spi.queries.VisibilityQueryImplementation;
070: import org.openide.filesystems.FileObject;
071: import org.openide.filesystems.FileSystem.AtomicAction;
072: import org.openide.filesystems.FileUtil;
073: import org.openide.loaders.DataObject;
074:
075: /**
076: *
077: * @author Jan Lahoda
078: */
079: public class RepositoryUpdaterTest extends NbTestCase {
080:
081: static {
082: Logger.getLogger(RepositoryUpdater.class.getName()).setLevel(
083: Level.ALL);
084: }
085:
086: public RepositoryUpdaterTest(String testName) {
087: super (testName);
088: }
089:
090: protected void setUp() throws Exception {
091: SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
092: RepositoryUpdater.DELAY = 0;
093: handler = new Handler() {
094: public void publish(LogRecord rec) {
095: if (RepositoryUpdater.GOING_TO_RECOMPILE.equals(rec
096: .getMessage())) {
097: recompiled = (Map<URL, Collection<File>>) rec
098: .getParameters()[0];
099: }
100: }
101:
102: public void flush() {
103: }
104:
105: public void close() throws SecurityException {
106: }
107: };
108: Logger.getLogger(RepositoryUpdater.class.getName()).addHandler(
109: handler);
110: super .setUp();
111: }
112:
113: protected void tearDown() throws Exception {
114: Logger.getLogger(RepositoryUpdater.class.getName())
115: .removeHandler(handler);
116: if (sourceCP != null) {
117: GlobalPathRegistry.getDefault().unregister(
118: ClassPath.SOURCE, new ClassPath[] { sourceCP });
119: }
120: super .tearDown();
121: }
122:
123: private File pack;
124: private File a;
125: private File b;
126: private FileObject fileA;
127: private FileObject fileB;
128: private URL rootURL;
129: private Map<URL, Collection<File>> recompiled;
130: private Handler handler;
131: private ClassPath sourceCP;
132:
133: private void prepareTest(String aFileContent, String bFileContent)
134: throws Exception {
135: prepareTest(aFileContent, bFileContent, null);
136: }
137:
138: private void prepareTest(String aFileContent, String bFileContent,
139: String sourceLevel) throws Exception {
140: clearWorkDir();
141:
142: File workDir = getWorkDir();
143: File src = new File(workDir, "src");
144: File cache = new File(workDir, "cache");
145: File userdir = new File(workDir, "userdir");
146: System.setProperty("netbeans.user", userdir.getAbsolutePath());
147: pack = new File(src, "pack");
148:
149: cache.mkdirs();
150: pack.mkdirs();
151:
152: rootURL = src.toURL();
153:
154: Index.setCacheFolder(cache);
155:
156: a = new File(pack, "A.java");
157: b = new File(pack, "B.java");
158:
159: TestUtilities.copyStringToFile(a, aFileContent);
160: TestUtilities.copyStringToFile(b, bFileContent);
161:
162: List<URL> bootClassPath = SourceUtilsTestUtil
163: .getBootClassPath();
164: URL[] bootClassPathRoots = bootClassPath.toArray(new URL[0]);
165:
166: fileA = FileUtil.toFileObject(a);
167: fileB = FileUtil.toFileObject(b);
168:
169: assertNotNull(fileA);
170: assertNotNull(fileB);
171:
172: if (sourceLevel != null) {
173: SourceUtilsTestUtil.setSourceLevel(fileA, sourceLevel);
174: SourceUtilsTestUtil.setSourceLevel(fileB, sourceLevel);
175: }
176:
177: ClassPath bootCP = ClassPathSupport
178: .createClassPath(bootClassPathRoots);
179:
180: sourceCP = ClassPathSupport
181: .createClassPath(new FileObject[] { FileUtil
182: .toFileObject(src) });
183:
184: CPPImpl impl = new CPPImpl(bootCP, sourceCP);
185:
186: SourceUtilsTestUtil
187: .prepareTest(
188: new String[] { "org/netbeans/modules/tasklist/ui/layer.xml" },
189: new Object[] {
190: impl,
191: new VisibilityQueryImplementation() {
192: public boolean isVisible(
193: FileObject file) {
194: try {
195: return !file.getURL()
196: .toString()
197: .contains(".jar");
198: } catch (IOException e) {
199: e.printStackTrace();
200: return true;
201: }
202: }
203:
204: public void addChangeListener(
205: ChangeListener l) {
206: }
207:
208: public void removeChangeListener(
209: ChangeListener l) {
210: }
211: },
212: new TestSourceLevelQueryImplementation() });
213:
214: RepositoryUpdater.getDefault();
215:
216: GlobalPathRegistry.getDefault().register(ClassPath.SOURCE,
217: new ClassPath[] { sourceCP });
218:
219: waitScanFinished();
220: }
221:
222: public void testSimpleReparse() throws Exception {
223: prepareTest(aFileContent, bFileContent);
224: TestUtilities.copyStringToFile(fileB, bFileContentNewContent);
225:
226: waitScanFinished();
227:
228: assertFalse(TaskCache.getDefault().getErrors(fileA).isEmpty());
229:
230: TestUtilities.copyStringToFile(fileB, bFileContent);
231:
232: waitScanFinished();
233:
234: assertTrue(TaskCache.getDefault().getErrors(fileA).isEmpty());
235: }
236:
237: // public void testWarnings() throws Exception {
238: // System.setProperty("org.netbeans.api.java.source.JavaSource.USE_COMPILER_LINT", "true");
239: // prepareTest("package pack; public class A {java.util.List<String> l = new java.util.ArrayList();}", "package pack; public class B{}");
240: //
241: // assertFalse(TaskCache.getDefault().isInError(fileA, true));
242: //
243: // List<Task> tasks = TaskCache.getDefault().getErrors(fileA);
244: //
245: // assertEquals(1, tasks.size());
246: //
247: // Task t = tasks.get(0);
248: //
249: // assertEquals("nb-tasklist-warning", Accessor.DEFAULT.getGroup(t).getName());
250: // }
251:
252: public void testReparseDeprecated() throws Exception {
253: System
254: .setProperty(
255: "org.netbeans.api.java.source.JavaSource.USE_COMPILER_LINT",
256: "true");
257: prepareTest(
258: "package pack; public class A {private int x = B.get();}",
259: "package pack; public class B {public static int get() {return 0;}}");
260:
261: assertTrue(TaskCache.getDefault().getErrors(fileA).toString(),
262: TaskCache.getDefault().getErrors(fileA).isEmpty());
263:
264: TestUtilities
265: .copyStringToFile(
266: fileB,
267: "package pack; public class B {@Deprecated public static int get() {return 0;}}");
268:
269: waitScanFinished();
270:
271: assertEquals(
272: TaskCache.getDefault().getErrors(fileA).toString(), 1,
273: TaskCache.getDefault().getErrors(fileA).size());
274: }
275:
276: public void testDeleteUpdate1() throws Exception {
277: prepareTest("package pack; public class A { error }",
278: "package pack; public class B {}");
279:
280: FileObject parent = fileA.getParent();
281:
282: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
283: TaskCache.getDefault().getErrors(fileA).isEmpty());
284: assertTrue(TaskCache.getDefault().isInError(parent, true));
285: assertTrue(TaskCache.getDefault().isInError(parent, false));
286:
287: fileA.delete();
288:
289: waitScanFinished();
290:
291: assertFalse(TaskCache.getDefault().isInError(parent, true));
292: assertFalse(TaskCache.getDefault().isInError(parent, false));
293: }
294:
295: public void testDeleteUpdate2() throws Exception {
296: prepareTest("package pack; public class A { error }",
297: "package pack; public class B {A a;}");
298:
299: FileObject parent = fileA.getParent();
300:
301: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
302: TaskCache.getDefault().getErrors(fileA).isEmpty());
303: assertFalse(TaskCache.getDefault().isInError(fileB, false));
304:
305: fileA.delete();
306:
307: waitScanFinished();
308:
309: assertTrue(TaskCache.getDefault().isInError(fileB, false));
310: }
311:
312: public void testCreateUpdate1() throws Exception {
313: prepareTest("package pack; public class A { C c;}",
314: "package pack; public class B {}");
315:
316: assertTrue(TaskCache.getDefault().isInError(fileA, false));
317: assertFalse(TaskCache.getDefault().isInError(fileB, false));
318:
319: final FileObject[] fileC = new FileObject[1];
320:
321: fileA.getFileSystem().runAtomicAction(new AtomicAction() {
322: public void run() throws IOException {
323: try {
324: fileC[0] = FileUtil.createData(FileUtil
325: .toFileObject(pack), "C.java");
326: TestUtilities.copyStringToFile(fileC[0],
327: "package pack; public class C {}");
328: } catch (Exception e) {
329: throw (IOException) new IOException().initCause(e);
330: }
331: }
332: });
333:
334: waitScanFinished();
335:
336: assertFalse(TaskCache.getDefault().isInError(fileA, false));
337: assertFalse(TaskCache.getDefault().isInError(fileB, false));
338: }
339:
340: public void testFileUpdate1() throws Exception {
341: prepareTest("package pack; public class A { B.Inner x; }",
342: "package pack; public class B {public static class Inner {}}");
343: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
344: TaskCache.getDefault().isInError(fileA, false));
345: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
346: TaskCache.getDefault().isInError(fileB, false));
347:
348: TestUtilities.copyStringToFile(fileB,
349: "package pack; public class B {}");
350:
351: waitScanFinished();
352:
353: assertNotNull(recompiled);
354: assertTrue(TaskCache.getDefault().getErrors(fileA).toString(),
355: TaskCache.getDefault().isInError(fileA, false));
356: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
357: TaskCache.getDefault().isInError(fileB, false));
358: }
359:
360: public void testFileUpdate2() throws Exception {
361: prepareTest("package pack; public class A { B.Inner x; }",
362: "package pack; public class B {public static class Inner {}}");
363: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
364: TaskCache.getDefault().isInError(fileA, false));
365: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
366: TaskCache.getDefault().isInError(fileB, false));
367:
368: new FirstParseCatcher().createTask(fileB).run(
369: SourceUtilsTestUtil.getCompilationInfo(JavaSource
370: .forFileObject(fileB), Phase.RESOLVED));
371:
372: TestUtilities
373: .copyStringToFile(fileB,
374: "package pack; public class B {public static class Inner {} /**/}");
375:
376: waitScanFinished();
377:
378: assertNull(String.valueOf(recompiled), recompiled);
379: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
380: TaskCache.getDefault().isInError(fileA, false));
381: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
382: TaskCache.getDefault().isInError(fileB, false));
383: }
384:
385: public void testSourceLevelChanged() throws Exception {
386: prepareTest("package pack; public enum A { }",
387: "package pack; public class B {}", "1.4");
388: assertTrue(TaskCache.getDefault().getErrors(fileA).toString(),
389: TaskCache.getDefault().isInError(fileA, false));
390: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
391: TaskCache.getDefault().isInError(fileB, false));
392:
393: SourceUtilsTestUtil.setSourceLevel(fileA, "1.5");
394: SourceUtilsTestUtil.setSourceLevel(fileB, "1.5");
395:
396: //currently, it is not possible to listen on changes in source level query, so a file needs to be reparsed
397: //from the source root to detect the change:
398: SourceUtilsTestUtil.getCompilationInfo(JavaSource
399: .forFileObject(fileB), Phase.PARSED);
400:
401: waitScanFinished();
402:
403: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
404: TaskCache.getDefault().isInError(fileA, false));
405: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
406: TaskCache.getDefault().isInError(fileB, false));
407: }
408:
409: public void testTasklistEnableDisable() throws Exception {
410: prepareTest("package pack; public enum A { B;}",
411: "package pack; public class B {A a = A.B;}");
412: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
413: TaskCache.getDefault().isInError(fileA, false));
414: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
415: TaskCache.getDefault().isInError(fileB, false));
416:
417: assertNull(RepositoryUpdater.getDefault().getAttribute(rootURL,
418: RepositoryUpdater.DIRTY_ROOT, null));
419: TasklistSettings.setTasklistsEnabled(false);
420:
421: recompiled = null;
422:
423: TestUtilities.copyStringToFile(fileA,
424: "package pack; public enum A { C;}");
425:
426: waitScanFinished();
427:
428: assertNull(recompiled);
429: assertNull(RepositoryUpdater.getDefault().getAttribute(rootURL,
430: RepositoryUpdater.DIRTY_ROOT, null));
431:
432: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
433: TaskCache.getDefault().isInError(fileA, false));
434: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
435: TaskCache.getDefault().isInError(fileB, false));
436:
437: TasklistSettings.setTasklistsEnabled(true);
438:
439: waitScanFinished();
440:
441: assertNull(RepositoryUpdater.getDefault().getAttribute(rootURL,
442: RepositoryUpdater.DIRTY_ROOT, null));
443:
444: assertFalse(TaskCache.getDefault().getErrors(fileA).toString(),
445: TaskCache.getDefault().isInError(fileA, false));
446: assertTrue(TaskCache.getDefault().getErrors(fileB).toString(),
447: TaskCache.getDefault().isInError(fileB, false));
448:
449: //XXX: test isTasklistEnabled and isDependencyTrackingEnabled separately
450: }
451:
452: public void testFileMove() throws Exception {
453: prepareTest("package pack; public class A { B.Inner x; }",
454: "package pack; public class B {}");
455: assertTrue(TaskCache.getDefault().getErrors(fileA).toString(),
456: TaskCache.getDefault().isInError(fileA, false));
457: assertFalse(TaskCache.getDefault().getErrors(fileB).toString(),
458: TaskCache.getDefault().isInError(fileB, false));
459:
460: DataObject.find(fileA).rename("Aa.java");
461:
462: waitScanFinished();
463:
464: TestUtilities.copyStringToFile(fileA,
465: "package pack; public class Aa { }");
466:
467: waitScanFinished();
468:
469: assertFalse(TaskCache.getDefault().isInError(fileB.getParent(),
470: true));
471: }
472:
473: private void waitScanFinished() throws Exception {
474: //XXX:
475: Thread.sleep(2000);
476: while (RepositoryUpdater.getDefault().waitWorkStarted())
477: SourceUtils.waitScanFinished();
478:
479: SourceUtils.waitScanFinished();
480: }
481:
482: private static final class CPPImpl implements ClassPathProvider {
483:
484: private static final ClassPath EMPTY = ClassPathSupport
485: .createClassPath(new URL[0]);
486:
487: private ClassPath bootCP;
488: private ClassPath sourceCP;
489:
490: public CPPImpl(ClassPath bootCP, ClassPath sourceCP) {
491: this .bootCP = bootCP;
492: this .sourceCP = sourceCP;
493: }
494:
495: public ClassPath findClassPath(FileObject file, String type) {
496: // if (file != fileA && file != fileB) {
497: // return null;
498: // }
499:
500: if (ClassPath.BOOT.contains(type)) {
501: return bootCP;
502: }
503:
504: if (ClassPath.COMPILE.contains(type)) {
505: return EMPTY;
506: }
507:
508: if (ClassPath.SOURCE.contains(type)) {
509: return sourceCP;
510: }
511:
512: fail("Unhandled");
513:
514: return null;
515: }
516:
517: }
518:
519: private static final String aFileContent = "package pack;\n"
520: + "public class A {\n"
521: + "public static void main(String [] args) {\n"
522: + "B.test();\n" + "}\n" + "}\n";
523:
524: private static final String bFileContent = "package pack;\n"
525: + "public class B {\n" + "public static void test() {}\n"
526: + "}\n";
527: private static final String bFileContentNewContent = "package pack;\n"
528: + "public class B {\n"
529: + "public static void tests() {}\n"
530: + "}\n";
531: }
|