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-2006 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.api.project;
043:
044: import java.lang.ref.Reference;
045: import java.lang.ref.WeakReference;
046: import java.net.URI;
047: import org.netbeans.junit.NbTestCase;
048: import org.netbeans.modules.projectapi.TimedWeakReference;
049: import org.openide.filesystems.FileObject;
050: import org.openide.filesystems.FileUtil;
051: import org.openide.filesystems.test.TestFileUtils;
052: import org.openide.util.test.MockLookup;
053:
054: /**
055: * Test functionality of FileOwnerQuery.
056: * @author Jesse Glick
057: */
058: public class FileOwnerQueryTest extends NbTestCase {
059:
060: public FileOwnerQueryTest(String name) {
061: super (name);
062: }
063:
064: static {
065: TimedWeakReference.TIMEOUT = 0;
066: }
067:
068: private FileObject scratch;
069: private FileObject projdir;
070: private FileObject randomfile;
071: private FileObject projfile;
072: private FileObject projfile2;
073: private FileObject subprojdir;
074: private FileObject subprojfile;
075: private FileObject hashedFile;
076: private Project p;
077: private FileObject zippedfile;
078:
079: protected @Override
080: void setUp() throws Exception {
081: MockLookup.setInstances(TestUtil.testProjectFactory());
082: ProjectManager.getDefault().reset();
083: FileOwnerQuery.reset();
084: scratch = TestUtil.makeScratchDir(this );
085: projdir = scratch.createFolder("my-project");
086: projdir.createFolder("testproject");
087: randomfile = scratch.createData("randomfile");
088: projfile = projdir.createData("projfile");
089: FileObject projsubdir = projdir.createFolder("projsubdir");
090: projfile2 = projsubdir.createData("projfile2");
091: subprojdir = projdir.createFolder("subproject");
092: subprojdir.createFolder("testproject");
093: subprojfile = subprojdir.createData("subprojfile");
094: scratch.createFolder("external1").createFolder("subdir")
095: .createData("file");
096: scratch.createFolder("external2").createFolder("subdir")
097: .createData("file");
098: scratch.createFolder("external3").createFolder("subproject")
099: .createFolder("testproject");
100: p = ProjectManager.getDefault().findProject(projdir);
101: assertNotNull("found a project successfully", p);
102:
103: // make jar:file:/.../projdir/foo.jar!/zipfile/zippedfile
104: FileObject foojar = TestFileUtils.writeZipFile(projdir,
105: "foo.jar", "zipdir/zippedfile:");
106: FileObject foojarRoot = FileUtil.getArchiveRoot(foojar);
107: assertNotNull("have an archive in " + foojar, foojarRoot);
108: zippedfile = foojarRoot.getFileObject("zipdir/zippedfile");
109: assertNotNull("zippedfile found in it", zippedfile);
110:
111: hashedFile = TestFileUtils.writeZipFile(projdir,
112: ".#webapp.jar.1.45", "zipdir/zippedfile:");
113: foojarRoot = FileUtil.getArchiveRoot(hashedFile);
114: assertNotNull("have an archive in " + hashedFile, foojarRoot);
115: hashedFile = foojarRoot.getFileObject("zipdir/zippedfile");
116:
117: }
118:
119: protected @Override
120: void tearDown() throws Exception {
121: scratch = null;
122: projdir = null;
123: randomfile = null;
124: projfile = null;
125: p = null;
126: }
127:
128: public void testFileOwner() throws Exception {
129: assertEquals("correct project from projfile FileObject", p,
130: FileOwnerQuery.getOwner(projfile));
131: URI u = FileUtil.toFile(projfile).toURI();
132: assertEquals("correct project from projfile URI " + u, p,
133: FileOwnerQuery.getOwner(u));
134: assertEquals("correct project from projfile2 FileObject", p,
135: FileOwnerQuery.getOwner(projfile2));
136: assertEquals("correct project from projfile2 URI", p,
137: FileOwnerQuery.getOwner(FileUtil.toFile(projfile2)
138: .toURI()));
139: assertEquals("correct project from projdir FileObject", p,
140: FileOwnerQuery.getOwner(projdir));
141: assertEquals("correct project from projdir URI", p,
142: FileOwnerQuery.getOwner(FileUtil.toFile(projdir)
143: .toURI()));
144: // Check that it loads the project even though we have not touched it yet:
145: Project p2 = FileOwnerQuery.getOwner(subprojfile);
146: Project subproj = ProjectManager.getDefault().findProject(
147: subprojdir);
148: assertEquals("correct project from subprojdir FileObject",
149: subproj, p2);
150: assertEquals("correct project from subprojdir URI", subproj,
151: FileOwnerQuery.getOwner(FileUtil.toFile(subprojdir)
152: .toURI()));
153: assertEquals("correct project from subprojfile FileObject",
154: subproj, FileOwnerQuery.getOwner(subprojfile));
155: assertEquals("correct project from subprojfile URI", subproj,
156: FileOwnerQuery.getOwner(FileUtil.toFile(subprojfile)
157: .toURI()));
158: assertEquals("no project from randomfile FileObject", null,
159: FileOwnerQuery.getOwner(randomfile));
160: assertEquals("no project from randomfile URI", null,
161: FileOwnerQuery.getOwner(FileUtil.toFile(randomfile)
162: .toURI()));
163: assertEquals("no project in C:\\", null, FileOwnerQuery
164: .getOwner(URI.create("file:/C:/")));
165: }
166:
167: public void testJarOwners() throws Exception {
168: assertEquals("correct owner of a ZIPped file", p,
169: FileOwnerQuery.getOwner(zippedfile));
170: assertEquals("correct owner of a ZIPped file URL", p,
171: FileOwnerQuery.getOwner(URI.create(zippedfile.getURL()
172: .toExternalForm())));
173: assertEquals("correct owner of a ZIPped file", p,
174: FileOwnerQuery.getOwner(hashedFile));
175: assertEquals("correct owner of a ZIPped file URL", p,
176: FileOwnerQuery.getOwner(URI.create(hashedFile.getURL()
177: .toExternalForm())));
178: }
179:
180: public void testExternalOwner() throws Exception {
181: FileObject ext1 = scratch.getFileObject("external1");
182: FileObject extfile1 = ext1.getFileObject("subdir/file");
183: assertEquals("no owner yet", null, FileOwnerQuery
184: .getOwner(extfile1));
185: FileOwnerQuery.markExternalOwner(ext1, p,
186: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
187: assertEquals("now have an owner", p, FileOwnerQuery
188: .getOwner(extfile1));
189: assertEquals("even for the projdir", p, FileOwnerQuery
190: .getOwner(ext1));
191: assertEquals("but not for something else", null, FileOwnerQuery
192: .getOwner(scratch));
193: FileObject ext2 = scratch.getFileObject("external2");
194: FileObject extfile2 = ext2.getFileObject("subdir/file");
195: assertEquals("no owner yet", null, FileOwnerQuery
196: .getOwner(extfile2));
197: Project p2 = ProjectManager.getDefault()
198: .findProject(subprojdir);
199: FileOwnerQuery.markExternalOwner(ext2, p2,
200: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
201: assertEquals("now have an owner", p2, FileOwnerQuery
202: .getOwner(extfile2));
203: assertEquals("even for the projdir", p2, FileOwnerQuery
204: .getOwner(ext2));
205: assertEquals("but not for something else", null, FileOwnerQuery
206: .getOwner(scratch));
207: assertEquals("still correct for first proj", p, FileOwnerQuery
208: .getOwner(extfile1));
209: FileObject ext3 = scratch.getFileObject("external3");
210: assertEquals("no owner yet", null, FileOwnerQuery
211: .getOwner(ext3));
212: FileOwnerQuery.markExternalOwner(ext3, p,
213: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
214: assertEquals("now have an owner", p, FileOwnerQuery
215: .getOwner(ext3));
216: FileObject ext3subproj = ext3.getFileObject("subproject");
217: Project p3 = FileOwnerQuery.getOwner(ext3subproj);
218: assertNotSame("different project", p, p3);
219: assertEquals("but subprojects are not part of it",
220: ProjectManager.getDefault().findProject(ext3subproj),
221: p3);
222: FileOwnerQuery.markExternalOwner(ext3, null,
223: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
224: assertEquals("unmarking an owner works", null, FileOwnerQuery
225: .getOwner(ext3));
226: }
227:
228: public void testExternalOwnerFile() throws Exception {
229: FileObject ext1 = scratch.getFileObject("external1");
230: FileObject extfile1 = ext1.getFileObject("subdir/file");
231: assertEquals("no owner yet", null, FileOwnerQuery
232: .getOwner(extfile1));
233: FileOwnerQuery.markExternalOwner(extfile1, p,
234: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
235: assertEquals("now have an owner", p, FileOwnerQuery
236: .getOwner(extfile1));
237: assertEquals("not for the projdir", null, FileOwnerQuery
238: .getOwner(ext1));
239: assertEquals("and not for something else", null, FileOwnerQuery
240: .getOwner(scratch));
241: FileObject ext2 = scratch.getFileObject("external2");
242: FileObject extfile2 = ext2.getFileObject("subdir/file");
243: assertEquals("no owner yet", null, FileOwnerQuery
244: .getOwner(extfile2));
245: Project p2 = ProjectManager.getDefault()
246: .findProject(subprojdir);
247: FileOwnerQuery.markExternalOwner(extfile2, p2,
248: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
249: assertEquals("now have an owner", p2, FileOwnerQuery
250: .getOwner(extfile2));
251: assertEquals("not for the projdir", null, FileOwnerQuery
252: .getOwner(ext2));
253: assertEquals("and not for something else", null, FileOwnerQuery
254: .getOwner(scratch));
255: assertEquals("still correct for first proj", p, FileOwnerQuery
256: .getOwner(extfile1));
257:
258: //XXX: unmarking files.
259: }
260:
261: public void testExternalOwnerURI() throws Exception {
262: FileObject ext1 = scratch.getFileObject("external1");
263: FileObject extfile1 = ext1.getFileObject("subdir/file");
264: assertEquals("no owner yet through FileObjects", null,
265: FileOwnerQuery.getOwner(extfile1));
266: assertEquals("no owner yet through URI", null, FileOwnerQuery
267: .getOwner(extfile1));
268: FileOwnerQuery.markExternalOwner(fileObject2URI(ext1), p,
269: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
270: assertEquals("now have an owner through FileObjects", p,
271: FileOwnerQuery.getOwner(extfile1));
272: assertEquals("now have an owner through URI", p, FileOwnerQuery
273: .getOwner(fileObject2URI(extfile1)));
274: assertEquals("even for the projdir throught FileObjects", p,
275: FileOwnerQuery.getOwner(ext1));
276: assertEquals("even for the projdir throught URI", p,
277: FileOwnerQuery.getOwner(fileObject2URI(ext1)));
278: assertEquals("but not for something else throught FileObjects",
279: null, FileOwnerQuery.getOwner(scratch));
280: assertEquals("but not for something else throught URI", null,
281: FileOwnerQuery.getOwner(fileObject2URI(scratch)));
282: FileObject ext2 = scratch.getFileObject("external2");
283: FileObject extfile2 = ext2.getFileObject("subdir/file");
284: assertEquals("no owner yet through FileObjects", null,
285: FileOwnerQuery.getOwner(extfile2));
286: assertEquals("no owner yet through URI", null, FileOwnerQuery
287: .getOwner(fileObject2URI(extfile2)));
288: Project p2 = ProjectManager.getDefault()
289: .findProject(subprojdir);
290: FileOwnerQuery.markExternalOwner(fileObject2URI(ext2), p2,
291: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
292: assertEquals("now have an owner through FileObjects", p2,
293: FileOwnerQuery.getOwner(extfile2));
294: assertEquals("now have an owner through URI", p2,
295: FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
296: assertEquals("even for the projdir through FileObjects", p2,
297: FileOwnerQuery.getOwner(ext2));
298: assertEquals("even for the projdir through URI", p2,
299: FileOwnerQuery.getOwner(ext2));
300: assertEquals("but not for something else through FileObjects",
301: null, FileOwnerQuery.getOwner(scratch));
302: assertEquals("but not for something else through URI", null,
303: FileOwnerQuery.getOwner(fileObject2URI(scratch)));
304: assertEquals(
305: "still correct for first proj through FileObjects", p,
306: FileOwnerQuery.getOwner(extfile1));
307: assertEquals("still correct for first proj through URI", p,
308: FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
309: FileObject ext3 = scratch.getFileObject("external3");
310: assertEquals("no owner yet through FileObjects", null,
311: FileOwnerQuery.getOwner(ext3));
312: assertEquals("no owner yet through URI", null, FileOwnerQuery
313: .getOwner(fileObject2URI(ext3)));
314: FileOwnerQuery.markExternalOwner(fileObject2URI(ext3), p,
315: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
316: assertEquals("now have an owner through FileObjects", p,
317: FileOwnerQuery.getOwner(ext3));
318: assertEquals("now have an owner through URI", p, FileOwnerQuery
319: .getOwner(fileObject2URI(ext3)));
320: FileObject ext3subproj = ext3.getFileObject("subproject");
321: Project p3 = FileOwnerQuery.getOwner(ext3subproj);
322: assertNotSame("different project", p, p3);
323: assertEquals("but subprojects are not part of it",
324: ProjectManager.getDefault().findProject(ext3subproj),
325: p3);
326: FileOwnerQuery.markExternalOwner(fileObject2URI(ext3), null,
327: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
328: assertEquals("unmarking an owner works through FileObjects",
329: null, FileOwnerQuery.getOwner(ext3));
330: assertEquals("unmarking an owner works through URI", null,
331: FileOwnerQuery.getOwner(fileObject2URI(ext3)));
332: }
333:
334: public void testExternalOwnerFileURI() throws Exception {
335: FileObject ext1 = scratch.getFileObject("external1");
336: FileObject extfile1 = ext1.getFileObject("subdir/file");
337: assertEquals("no owner yet through FileObjects", null,
338: FileOwnerQuery.getOwner(extfile1));
339: assertEquals("no owner yet through URI", null, FileOwnerQuery
340: .getOwner(fileObject2URI(extfile1)));
341: FileOwnerQuery.markExternalOwner(fileObject2URI(extfile1), p,
342: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
343: assertEquals("now have an owner through FileObjects", p,
344: FileOwnerQuery.getOwner(extfile1));
345: assertEquals("now have an owner through URI", p, FileOwnerQuery
346: .getOwner(fileObject2URI(extfile1)));
347: assertEquals("not for the projdir through FileObjects", null,
348: FileOwnerQuery.getOwner(ext1));
349: assertEquals("not for the projdir through URI", null,
350: FileOwnerQuery.getOwner(fileObject2URI(ext1)));
351: assertEquals("and not for something else through FileObjects",
352: null, FileOwnerQuery.getOwner(scratch));
353: assertEquals("and not for something else through URI", null,
354: FileOwnerQuery.getOwner(fileObject2URI(scratch)));
355: FileObject ext2 = scratch.getFileObject("external2");
356: FileObject extfile2 = ext2.getFileObject("subdir/file");
357: assertEquals("no owner yet through FileObjects", null,
358: FileOwnerQuery.getOwner(extfile2));
359: assertEquals("no owner yet through URI", null, FileOwnerQuery
360: .getOwner(fileObject2URI(extfile2)));
361: Project p2 = ProjectManager.getDefault()
362: .findProject(subprojdir);
363: FileOwnerQuery.markExternalOwner(fileObject2URI(extfile2), p2,
364: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
365: assertEquals("now have an owner through FileObjects", p2,
366: FileOwnerQuery.getOwner(extfile2));
367: assertEquals("now have an owner through URI", p2,
368: FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
369: assertEquals("not for the projdir through FileObjects", null,
370: FileOwnerQuery.getOwner(ext2));
371: assertEquals("not for the projdir through URI", null,
372: FileOwnerQuery.getOwner(fileObject2URI(ext2)));
373: assertEquals("and not for something else through FileObjects",
374: null, FileOwnerQuery.getOwner(scratch));
375: assertEquals("and not for something else through URI", null,
376: FileOwnerQuery.getOwner(fileObject2URI(scratch)));
377: assertEquals(
378: "still correct for first proj through FileObjects", p,
379: FileOwnerQuery.getOwner(extfile1));
380: assertEquals("still correct for first proj through URI", p,
381: FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
382:
383: //XXX: unmarking files.
384: }
385:
386: public void testIsProjectDirCollectible() throws Exception {
387: Project p2 = ProjectManager.getDefault()
388: .findProject(subprojdir);
389: FileObject root = p2.getProjectDirectory();
390: FileObject ext2 = scratch.getFileObject("external2");
391: FileObject extfile2 = ext2.getFileObject("subdir/file");
392:
393: FileOwnerQuery.markExternalOwner(fileObject2URI(extfile2), p2,
394: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
395:
396: Reference<?> p2WR = new WeakReference<Object>(p2);
397: Reference<?> rootWR = new WeakReference<Object>(root);
398:
399: p2 = null;
400: root = null;
401: ext2 = null;
402: extfile2 = null;
403: subprojdir = null;
404: subprojfile = null;
405:
406: assertGC("project 2 collected", p2WR);
407: assertGC("project 2's project dir collected", rootWR);
408: }
409:
410: /**
411: * Tests the issue 60297. GC causes previosly registered extenral roots
412: * for project to be released. Only one extenral root per project is kept.
413: *
414: */
415: public void testIssue60297() throws Exception {
416: FileObject ext1 = scratch.getFileObject("external1");
417: assertEquals("no owner yet", null, FileOwnerQuery
418: .getOwner(ext1));
419: FileOwnerQuery.markExternalOwner(ext1, p,
420: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
421: assertEquals("now have an owner", p, FileOwnerQuery
422: .getOwner(ext1));
423: FileObject ext2 = scratch.getFileObject("external2");
424: assertEquals("no owner yet", null, FileOwnerQuery
425: .getOwner(ext2));
426: FileOwnerQuery.markExternalOwner(ext2, p,
427: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
428: System.gc();
429: assertEquals("now have an owner", p, FileOwnerQuery
430: .getOwner(ext2));
431: assertEquals("still correct for the first external root", p,
432: FileOwnerQuery.getOwner(ext1));
433: }
434:
435: private static URI fileObject2URI(FileObject f) throws Exception {
436: return URI.create(f.getURL().toString());
437: }
438:
439: // XXX test URI usage of external owner
440: // XXX test GC of roots and projects used in external ownership:
441: // - the owning Project is not held strongly (just PM's soft cache)
442: // - the root is not held strongly (note - FOQ won't be accurate after it is collected)
443: // XXX test IAE from illegal calls to FOQ.markExternalOwner
444: // XXX test an owner which is above the project directory
445:
446: }
|