KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > project > TestUtil


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.api.project;
21
22 import java.beans.PropertyVetoException JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import junit.framework.Assert;
32 import org.netbeans.junit.NbTestCase;
33 import org.netbeans.spi.project.ProjectFactory;
34 import org.netbeans.spi.project.ProjectState;
35 import org.openide.filesystems.FileObject;
36 import org.openide.filesystems.FileUtil;
37 import org.openide.filesystems.LocalFileSystem;
38 import org.openide.filesystems.Repository;
39 import org.openide.filesystems.URLMapper;
40 import org.openide.util.Lookup;
41 import org.openide.util.lookup.Lookups;
42 import org.openide.util.lookup.ProxyLookup;
43
44 /**
45  * Help set up org.netbeans.api.project.*Test.
46  * @author Jesse Glick
47  */

48 public final class TestUtil extends ProxyLookup {
49     
50     static {
51         TestUtil.class.getClassLoader().setDefaultAssertionStatus(true);
52         System.setProperty("org.openide.util.Lookup", TestUtil.class.getName());
53         Assert.assertEquals(TestUtil.class, Lookup.getDefault().getClass());
54     }
55     
56     private static TestUtil DEFAULT;
57     /** Do not call directly */
58     public TestUtil() {
59         Assert.assertNull(DEFAULT);
60         DEFAULT = this;
61         setLookup(new Object JavaDoc[0]);
62     }
63     
64     /**
65      * Set the global default lookup.
66      * Caution: if you don't include Lookups.metaInfServices, you may have trouble,
67      * e.g. {@link #makeScratchDir} will not work.
68      */

69     public static void setLookup(Lookup l) {
70         DEFAULT.setLookups(new Lookup[] {l});
71     }
72     
73     /**
74      * Set the global default lookup with some fixed instances including META-INF/services/*.
75      */

76     public static void setLookup(Object JavaDoc[] instances) {
77         ClassLoader JavaDoc l = TestUtil.class.getClassLoader();
78         DEFAULT.setLookups(new Lookup[] {
79             Lookups.fixed(instances),
80             Lookups.metaInfServices(l),
81             Lookups.singleton(l),
82         });
83     }
84     
85     private static boolean warned = false;
86     /**
87      * Create a scratch directory for tests.
88      * Will be in /tmp or whatever, and will be empty.
89      * If you just need a java.io.File use clearWorkDir + getWorkDir.
90      */

91     public static FileObject makeScratchDir(NbTestCase test) throws IOException JavaDoc {
92         test.clearWorkDir();
93         File JavaDoc root = test.getWorkDir();
94         assert root.isDirectory() && root.list().length == 0;
95         FileObject fo = FileUtil.toFileObject(root);
96         if (fo != null) {
97             return fo;
98         } else {
99             if (!warned) {
100                 warned = true;
101                 System.err.println("No FileObject for " + root + " found.\n" +
102                                     "Maybe you need ${openide/masterfs.dir}/modules/org-netbeans-modules-masterfs.jar\n" +
103                                     "in test.unit.run.cp.extra, or make sure Lookups.metaInfServices is included in Lookup.default, so that\n" +
104                                     "Lookup.default<URLMapper>=" + Lookup.getDefault().lookupAll(URLMapper.class) + " includes MasterURLMapper\n" +
105                                     "e.g. by using TestUtil.setLookup(Object[]) rather than TestUtil.setLookup(Lookup).");
106             }
107             // For the benefit of those not using masterfs.
108
LocalFileSystem lfs = new LocalFileSystem();
109             try {
110                 lfs.setRootDirectory(root);
111             } catch (PropertyVetoException JavaDoc e) {
112                 assert false : e;
113             }
114             Repository.getDefault().addFileSystem(lfs);
115             return lfs.getRoot();
116         }
117     }
118     
119     /**
120      * Delete a file and all subfiles.
121      */

122     public static void deleteRec(File JavaDoc f) throws IOException JavaDoc {
123         if (f.isDirectory()) {
124             File JavaDoc[] kids = f.listFiles();
125             if (kids == null) {
126                 throw new IOException JavaDoc("List " + f);
127             }
128             for (File JavaDoc kid : kids) {
129                 deleteRec(kid);
130             }
131         }
132         if (!f.delete()) {
133             throw new IOException JavaDoc("Delete " + f);
134         }
135     }
136     
137     /**
138      * Create a testing project factory which recognizes directories containing
139      * a subdirectory called "testproject".
140      * If that subdirectory contains a file named "broken" then loading the project
141      * will fail with an IOException.
142      */

143     public static ProjectFactory testProjectFactory() {
144         return new TestProjectFactory();
145     }
146     
147     /**
148      * Try to force a GC.
149      */

150     public static void gc() {
151         System.gc();
152         System.runFinalization();
153         System.gc();
154     }
155     
156     private static final Map JavaDoc<FileObject,Integer JavaDoc> loadCount = new WeakHashMap JavaDoc<FileObject,Integer JavaDoc>();
157     
158     /**
159      * Check how many times {@link ProjectFactory#loadProject} has been called
160      * (with any outcome) on a given project directory.
161      */

162     public static int projectLoadCount(FileObject dir) {
163         Integer JavaDoc i = loadCount.get(dir);
164         if (i != null) {
165             return i;
166         } else {
167             return 0;
168         }
169     }
170     
171     /**
172      * Mark a test project to fail with a given error when it is next saved.
173      * The error only applies to the next save, not subsequent ones.
174      * @param p a test project
175      * @param error an error to throw (IOException or Error or RuntimeException),
176      * or null if it should succeed
177      */

178     public static void setProjectSaveWillFail(Project p, Throwable JavaDoc error) {
179         ((TestProject)p).error = error;
180     }
181     
182     /**
183      * Get the number of times a test project was successfully saved with no error.
184      * @param p a test project
185      * @return the save count
186      */

187     public static int projectSaveCount(Project p) {
188         return ((TestProject)p).saveCount;
189     }
190     
191     /**
192      * Mark a test project as modified.
193      * @param p a test project
194      */

195     public static void modify(Project p) {
196         ((TestProject)p).state.markModified();
197     }
198     
199     /**
200      * Mark a test project as modified.
201      * @param p a test project
202      */

203     public static void notifyDeleted(Project p) {
204         ((TestProject)p).state.notifyDeleted();
205     }
206     
207     /**
208      * If set to something non-null, loading a broken project will wait for
209      * notification on this monitor before throwing an exception.
210      * @see ProjectManagerTest#testLoadExceptionWithConcurrentLoad
211      */

212     public static Object JavaDoc BROKEN_PROJECT_LOAD_LOCK = null;
213     
214     private static final class TestProjectFactory implements ProjectFactory {
215         
216         TestProjectFactory() {}
217         
218         public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException JavaDoc {
219             Integer JavaDoc i = loadCount.get(projectDirectory);
220             if (i == null) {
221                 i = 1;
222             } else {
223                 i = i + 1;
224             }
225             loadCount.put(projectDirectory, i);
226             FileObject testproject = projectDirectory.getFileObject("testproject");
227             if (testproject != null && testproject.isFolder()) {
228                 if (testproject.getFileObject("broken") != null) {
229                     if (BROKEN_PROJECT_LOAD_LOCK != null) {
230                         synchronized (BROKEN_PROJECT_LOAD_LOCK) {
231                             try {
232                                 BROKEN_PROJECT_LOAD_LOCK.wait();
233                             } catch (InterruptedException JavaDoc e) {
234                                 assert false : e;
235                             }
236                         }
237                     }
238                     throw new IOException JavaDoc("Load failed of " + projectDirectory);
239                 } else {
240                     return new TestProject(projectDirectory, state);
241                 }
242             } else {
243                 return null;
244             }
245         }
246         
247         public void saveProject(Project project) throws IOException JavaDoc, ClassCastException JavaDoc {
248             TestProject p = (TestProject)project;
249             Throwable JavaDoc t = p.error;
250             if (t != null) {
251                 p.error = null;
252                 if (t instanceof IOException JavaDoc) {
253                     throw (IOException JavaDoc)t;
254                 } else if (t instanceof Error JavaDoc) {
255                     throw (Error JavaDoc)t;
256                 } else {
257                     throw (RuntimeException JavaDoc)t;
258                 }
259             }
260             p.saveCount++;
261         }
262         
263         public boolean isProject(FileObject dir) {
264             FileObject testproject = dir.getFileObject("testproject");
265             return testproject != null && testproject.isFolder();
266         }
267         
268     }
269     
270     private static final class TestProject implements Project {
271         
272         private final FileObject dir;
273         final ProjectState state;
274         Throwable JavaDoc error;
275         int saveCount = 0;
276         
277         public TestProject(FileObject dir, ProjectState state) {
278             this.dir = dir;
279             this.state = state;
280         }
281         
282         public Lookup getLookup() {
283             return Lookup.EMPTY;
284         }
285         
286         public FileObject getProjectDirectory() {
287             return dir;
288         }
289         
290         public String JavaDoc toString() {
291             return "testproject:" + getProjectDirectory().getNameExt();
292         }
293
294         /* Probably unnecessary to have a ProjectInformation here:
295         public String getName() {
296             return "testproject:" + getProjectDirectory().getNameExt();
297         }
298         
299         public String getDisplayName() {
300             return "Test Project in " + getProjectDirectory().getNameExt();
301         }
302         
303         public Image getIcon() {
304             return null;
305         }
306         
307         public void addPropertyChangeListener(PropertyChangeListener listener) {}
308         public void removePropertyChangeListener(PropertyChangeListener listener) {}
309          */

310         
311     }
312     
313     /**
314      * Open a URL of content (for example from {@link Class#getResource}) and copy it to a named file.
315      * The new file can be given as a parent directory plus a relative (slash-separated) path.
316      * The file may not already exist, but intermediate directories may or may not.
317      * If the content URL is null, the file is just created, no more; if it already existed
318      * it is touched (timestamp updated) and its contents are cleared.
319      * @return the file object
320      */

321     public static FileObject createFileFromContent(URL JavaDoc content, FileObject parent, String JavaDoc path) throws IOException JavaDoc {
322         if (parent == null) {
323             throw new IllegalArgumentException JavaDoc("null parent");
324         }
325         Assert.assertTrue("folder", parent.isFolder());
326         FileObject fo = parent;
327         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(path, "/");
328         boolean touch = false;
329         while (tok.hasMoreTokens()) {
330             Assert.assertNotNull("fo is null (parent=" + parent + " path=" + path + ")", fo);
331             String JavaDoc name = tok.nextToken();
332             if (tok.hasMoreTokens()) {
333                 FileObject sub = fo.getFileObject(name);
334                 if (sub == null) {
335                     FileObject fo2 = fo.createFolder(name);
336                     Assert.assertNotNull("createFolder(" + fo + ", " + name + ") -> null", fo2);
337                     fo = fo2;
338                 } else {
339                     Assert.assertTrue("folder", sub.isFolder());
340                     fo = sub;
341                 }
342             } else {
343                 FileObject sub = fo.getFileObject(name);
344                 if (sub == null) {
345                     FileObject fo2 = fo.createData(name);
346                     Assert.assertNotNull("createData(" + fo + ", " + name + ") -> null", fo2);
347                     fo = fo2;
348                 } else {
349                     fo = sub;
350                     touch = true;
351                 }
352             }
353         }
354         assert fo.isData();
355         if (content != null || touch) {
356             OutputStream JavaDoc os = fo.getOutputStream();
357             try {
358                 if (content != null) {
359                     InputStream JavaDoc is = content.openStream();
360                     try {
361                         FileUtil.copy(is, os);
362                     } finally {
363                         is.close();
364                     }
365                 }
366             } finally {
367                 os.close();
368             }
369         }
370         return fo;
371     }
372     
373 }
374
Popular Tags