KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > project > test > 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.modules.web.project.test;
21
22 import java.beans.PropertyVetoException JavaDoc;
23 import java.io.BufferedInputStream JavaDoc;
24 import java.io.BufferedOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileInputStream JavaDoc;
27 import java.io.FileOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36 import java.util.WeakHashMap JavaDoc;
37 import java.util.zip.ZipEntry JavaDoc;
38 import java.util.zip.ZipInputStream JavaDoc;
39 import junit.framework.Assert;
40 import org.netbeans.api.project.Project;
41 import org.netbeans.junit.NbTestCase;
42 import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry;
43 import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
44 import org.netbeans.spi.project.ProjectFactory;
45 import org.netbeans.spi.project.ProjectState;
46 import org.netbeans.spi.project.support.ant.AntProjectHelper;
47 import org.netbeans.spi.project.support.ant.EditableProperties;
48 import org.openide.filesystems.FileLock;
49 import org.openide.filesystems.FileObject;
50 import org.openide.filesystems.FileSystem;
51 import org.openide.filesystems.FileUtil;
52 import org.openide.filesystems.LocalFileSystem;
53 import org.openide.filesystems.MultiFileSystem;
54 import org.openide.filesystems.Repository;
55 import org.openide.filesystems.URLMapper;
56 import org.openide.filesystems.XMLFileSystem;
57 import org.openide.modules.InstalledFileLocator;
58 import org.openide.util.Lookup;
59 import org.openide.util.lookup.Lookups;
60 import org.openide.util.lookup.ProxyLookup;
61 import org.xml.sax.SAXException JavaDoc;
62
63 /**
64  * Help set up org.netbeans.api.project.*Test.
65  * @author Jesse Glick
66  */

67 public final class TestUtil extends ProxyLookup {
68     
69     static {
70         TestUtil.class.getClassLoader().setDefaultAssertionStatus(true);
71         System.setProperty("org.openide.util.Lookup", TestUtil.class.getName());
72         Assert.assertEquals(TestUtil.class, Lookup.getDefault().getClass());
73     }
74     
75     private static TestUtil DEFAULT;
76     private static final int BUFFER = 2048;
77     
78     /** Do not call directly */
79     public TestUtil() {
80         Assert.assertNull(DEFAULT);
81         DEFAULT = this;
82         setLookup(new Object JavaDoc[0]);
83     }
84     
85     /**
86      * Set the global default lookup.
87      * Caution: if you don't include Lookups.metaInfServices, you may have trouble,
88      * e.g. {@link #makeScratchDir} will not work.
89      */

90     public static void setLookup(Lookup l) {
91         DEFAULT.setLookups(new Lookup[] {l});
92     }
93     
94     /**
95      * Set the global default lookup with some fixed instances including META-INF/services/*.
96      */

97     public static void setLookup(Object JavaDoc[] instances) {
98         ClassLoader JavaDoc l = TestUtil.class.getClassLoader();
99         DEFAULT.setLookups(new Lookup[] {
100             Lookups.fixed(instances),
101             Lookups.metaInfServices(l),
102             Lookups.singleton(l),
103         });
104     }
105     
106     private static boolean warned = false;
107     /**
108      * Create a scratch directory for tests.
109      * Will be in /tmp or whatever, and will be empty.
110      * If you just need a java.io.File use clearWorkDir + getWorkDir.
111      */

112     public static FileObject makeScratchDir(NbTestCase test) throws IOException JavaDoc {
113         test.clearWorkDir();
114         File JavaDoc root = test.getWorkDir();
115         assert root.isDirectory() && root.list().length == 0;
116         FileObject fo = FileUtil.toFileObject(root);
117         if (fo != null) {
118             return fo;
119         } else {
120             if (!warned) {
121                 warned = true;
122                 System.err.println("No FileObject for " + root + " found.\n" +
123                                     "Maybe you need ${openide/masterfs.dir}/modules/org-netbeans-modules-masterfs.jar\n" +
124                                     "in test.unit.run.cp.extra, or make sure Lookups.metaInfServices is included in Lookup.default, so that\n" +
125                                     "Lookup.default<URLMapper>=" + Lookup.getDefault().lookup(new Lookup.Template(URLMapper.class)).allInstances() + " includes MasterURLMapper\n" +
126                                     "e.g. by using TestUtil.setLookup(Object[]) rather than TestUtil.setLookup(Lookup).");
127             }
128             // For the benefit of those not using masterfs.
129
LocalFileSystem lfs = new LocalFileSystem();
130             try {
131                 lfs.setRootDirectory(root);
132             } catch (PropertyVetoException JavaDoc e) {
133                 assert false : e;
134             }
135             Repository.getDefault().addFileSystem(lfs);
136             return lfs.getRoot();
137         }
138     }
139     
140     /**
141      * Delete a file and all subfiles.
142      */

143     public static void deleteRec(File JavaDoc f) throws IOException JavaDoc {
144         if (f.isDirectory()) {
145             File JavaDoc[] kids = f.listFiles();
146             if (kids == null) {
147                 throw new IOException JavaDoc("List " + f);
148             }
149             for (int i = 0; i < kids.length; i++) {
150                 deleteRec(kids[i]);
151             }
152         }
153         if (!f.delete()) {
154             throw new IOException JavaDoc("Delete " + f);
155         }
156     }
157     
158     /**
159      * Create a testing project factory which recognizes directories containing
160      * a subdirectory called "testproject".
161      * If that subdirectory contains a file named "broken" then loading the project
162      * will fail with an IOException.
163      */

164     public static ProjectFactory testProjectFactory() {
165         return new TestProjectFactory();
166     }
167     
168     /**
169      * Try to force a GC.
170      */

171     public static void gc() {
172         System.gc();
173         System.runFinalization();
174         System.gc();
175     }
176     
177     private static final Map JavaDoc<FileObject,Integer JavaDoc> loadCount = new WeakHashMap JavaDoc();
178     
179     /**
180      * Check how many times {@link ProjectFactory#loadProject} has been called
181      * (with any outcome) on a given project directory.
182      */

183     public static int projectLoadCount(FileObject dir) {
184         Integer JavaDoc i = (Integer JavaDoc)loadCount.get(dir);
185         if (i != null) {
186             return i.intValue();
187         } else {
188             return 0;
189         }
190     }
191     
192     /**
193      * Mark a test project to fail with a given error when it is next saved.
194      * The error only applies to the next save, not subsequent ones.
195      * @param p a test project
196      * @param error an error to throw (IOException or Error or RuntimeException),
197      * or null if it should succeed
198      */

199     public static void setProjectSaveWillFail(Project p, Throwable JavaDoc error) {
200         ((TestProject)p).error = error;
201     }
202     
203     /**
204      * Get the number of times a test project was successfully saved with no error.
205      * @param p a test project
206      * @return the save count
207      */

208     public static int projectSaveCount(Project p) {
209         return ((TestProject)p).saveCount;
210     }
211     
212     /**
213      * Mark a test project as modified.
214      * @param p a test project
215      */

216     public static void modify(Project p) {
217         ((TestProject)p).state.markModified();
218     }
219     
220     /**
221      * Mark a test project as modified.
222      * @param p a test project
223      */

224     public static void notifyDeleted(Project p) {
225         ((TestProject)p).state.notifyDeleted();
226     }
227     
228     /**
229      * Register Sun Application Server in the "IDE" to be used by unit test.
230      * This method creates dummy userdir as well as dummy NetBeans home
231      * in test's working directory. Both properties - <code>netbeans.home</code>
232      * and <code>netbeans.user</code> - will be set by this method if they are
233      * not already defined.
234      *
235      * @param test a test which requires SunAppServer
236      * @return id of registered server
237      */

238     public static String JavaDoc registerSunAppServer(NbTestCase test) throws Exception JavaDoc {
239         return registerSunAppServer(test, new Object JavaDoc[0]);
240 }
241     
242     public static String JavaDoc registerSunAppServer(NbTestCase test, Object JavaDoc[] additionalLookupItems) throws Exception JavaDoc {
243         String JavaDoc oldNbHome = System.getProperty("netbeans.home"); // NOI18N
244
String JavaDoc oldNbUser = System.getProperty("netbeans.user"); // NOI18N
245
File JavaDoc root = test.getWorkDir();
246         File JavaDoc systemDir = new File JavaDoc(root, "ud/system"); // NOI18N
247
new File JavaDoc(systemDir, "J2EE/InstalledServers").mkdirs(); // NOI18N
248
new File JavaDoc(systemDir, "J2EE/DeploymentPlugins").mkdirs(); // NOI18N
249
new File JavaDoc(root, "nb").mkdirs(); // NOI18N
250
System.setProperty("netbeans.home", new File JavaDoc(test.getWorkDir(), "nb").getAbsolutePath()); // NOI18N
251
System.setProperty("netbeans.user", new File JavaDoc(test.getWorkDir(), "ud").getAbsolutePath()); // NOI18N
252

253         // lookup content
254
Object JavaDoc[] appServerNeed = new Object JavaDoc[] { new Repo(test), new IFL() };
255         Object JavaDoc[] instances = new Object JavaDoc[additionalLookupItems.length + appServerNeed.length];
256         System.arraycopy(additionalLookupItems, 0, instances, 0, additionalLookupItems.length);
257         System.arraycopy(appServerNeed, 0, instances, additionalLookupItems.length, appServerNeed.length);
258         TestUtil.setLookup(instances);
259         
260         File JavaDoc asRoot = null;
261         if (System.getProperty("appserv.home") != null) { // NOI18N
262
asRoot = new File JavaDoc(System.getProperty("appserv.home")); // NOI18N
263
} else {
264             asRoot = extractAppSrv(test.getWorkDir(), new File JavaDoc(test.getDataDir(), "SunAppServer.zip")); // NOI18N
265
}
266         FileObject dir = Repository.getDefault().getDefaultFileSystem().findResource("/J2EE/InstalledServers"); // NOI18N
267
String JavaDoc name = FileUtil.findFreeFileName(dir, "instance", null); // NOI18N
268
FileObject instanceFO = dir.createData(name);
269         String JavaDoc serverID = "[" + asRoot.getAbsolutePath() + "]deployer:Sun:AppServer::localhost:4848"; // NOI18N
270
instanceFO.setAttribute(InstanceProperties.URL_ATTR, serverID);
271         instanceFO.setAttribute(InstanceProperties.USERNAME_ATTR, "admin"); // NOI18N
272
instanceFO.setAttribute(InstanceProperties.PASSWORD_ATTR, "adminadmin"); // NOI18N
273
instanceFO.setAttribute(InstanceProperties.DISPLAY_NAME_ATTR, "testdname"); // NOI18N
274
instanceFO.setAttribute(InstanceProperties.HTTP_PORT_NUMBER, "4848"); // NOI18N
275
instanceFO.setAttribute("DOMAIN", "testdomain1"); // NOI18N
276
instanceFO.setAttribute("LOCATION", new File JavaDoc(asRoot, "domains").getAbsolutePath()); // NOI18N
277
ServerRegistry sr = ServerRegistry.getInstance();
278         sr.addInstance(instanceFO);
279         if (oldNbHome != null) {
280             System.setProperty("netbeans.home", oldNbHome); // NOI18N
281
}
282         if (oldNbUser != null) {
283             System.setProperty("netbeans.user", oldNbUser); // NOI18N
284
}
285         return serverID;
286     }
287
288     private static File JavaDoc extractAppSrv(File JavaDoc destDir, File JavaDoc archiveFile) throws IOException JavaDoc {
289         ZipInputStream JavaDoc zis = null;
290         BufferedOutputStream JavaDoc dest = null;
291         try {
292             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(archiveFile);
293             zis = new ZipInputStream JavaDoc(new BufferedInputStream JavaDoc(fis));
294             ZipEntry JavaDoc entry;
295             while((entry = zis.getNextEntry()) != null) {
296                 byte data[] = new byte[BUFFER];
297                 File JavaDoc entryFile = new File JavaDoc(destDir, entry.getName());
298                 if (entry.isDirectory()) {
299                     entryFile.mkdirs();
300                 } else {
301                     entryFile.getParentFile().mkdirs();
302                     FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(entryFile);
303                     dest = new BufferedOutputStream JavaDoc(fos, BUFFER);
304                     int count;
305                     while ((count = zis.read(data, 0, BUFFER)) != -1) {
306                         dest.write(data, 0, count);
307                     }
308                     dest.flush();
309                 }
310             }
311         } finally {
312             if (zis != null) { zis.close(); }
313             if (dest != null) { dest.close(); }
314         }
315         return new File JavaDoc(destDir, archiveFile.getName().substring(0, archiveFile.getName().length() - 4));
316     }
317
318     public static EditableProperties loadProjectProperties(
319             final FileObject projectDir) throws IOException JavaDoc {
320         FileObject propsFO = projectDir.getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
321         InputStream JavaDoc propsIS = propsFO.getInputStream();
322         EditableProperties props = new EditableProperties(true);
323         try {
324             props.load(propsIS);
325         } finally {
326             propsIS.close();
327         }
328         return props;
329     }
330     
331     public static void storeProjectProperties(FileObject projectDir, EditableProperties props) throws IOException JavaDoc {
332         FileObject propsFO = projectDir.getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
333         FileLock lock = propsFO.lock();
334         try {
335             OutputStream JavaDoc os = propsFO.getOutputStream(lock);
336             try {
337                 props.store(os);
338             } finally {
339                 os.close();
340             }
341         } finally {
342             lock.releaseLock();
343         }
344     }
345     
346     /**
347      * If set to something non-null, loading a broken project will wait for
348      * notification on this monitor before throwing an exception.
349      * @see ProjectManagerTest#testLoadExceptionWithConcurrentLoad
350      */

351     public static Object JavaDoc BROKEN_PROJECT_LOAD_LOCK = null;
352     
353     private static final class TestProjectFactory implements ProjectFactory {
354         
355         TestProjectFactory() {}
356         
357         public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException JavaDoc {
358             Integer JavaDoc i = loadCount.get(projectDirectory);
359             if (i == null) {
360                 i = 1;
361             } else {
362                 i++;
363             }
364             loadCount.put(projectDirectory, i);
365             FileObject testproject = projectDirectory.getFileObject("testproject");
366             if (testproject != null && testproject.isFolder()) {
367                 if (testproject.getFileObject("broken") != null) {
368                     if (BROKEN_PROJECT_LOAD_LOCK != null) {
369                         synchronized (BROKEN_PROJECT_LOAD_LOCK) {
370                             try {
371                                 BROKEN_PROJECT_LOAD_LOCK.wait();
372                             } catch (InterruptedException JavaDoc e) {
373                                 assert false : e;
374                             }
375                         }
376                     }
377                     throw new IOException JavaDoc("Load failed of " + projectDirectory);
378                 } else {
379                     return new TestProject(projectDirectory, state);
380                 }
381             } else {
382                 return null;
383             }
384         }
385         
386         public void saveProject(Project project) throws IOException JavaDoc, ClassCastException JavaDoc {
387             TestProject p = (TestProject)project;
388             Throwable JavaDoc t = p.error;
389             if (t != null) {
390                 p.error = null;
391                 if (t instanceof IOException JavaDoc) {
392                     throw (IOException JavaDoc)t;
393                 } else if (t instanceof Error JavaDoc) {
394                     throw (Error JavaDoc)t;
395                 } else {
396                     throw (RuntimeException JavaDoc)t;
397                 }
398             }
399             p.saveCount++;
400         }
401         
402         public boolean isProject(FileObject dir) {
403             FileObject testproject = dir.getFileObject("testproject");
404             return testproject != null && testproject.isFolder();
405         }
406         
407     }
408     
409     private static final class TestProject implements Project {
410         
411         private final FileObject dir;
412         final ProjectState state;
413         Throwable JavaDoc error;
414         int saveCount = 0;
415         
416         public TestProject(FileObject dir, ProjectState state) {
417             this.dir = dir;
418             this.state = state;
419         }
420         
421         public Lookup getLookup() {
422             return Lookup.EMPTY;
423         }
424         
425         public FileObject getProjectDirectory() {
426             return dir;
427         }
428         
429         public String JavaDoc toString() {
430             return "testproject:" + getProjectDirectory().getNameExt();
431         }
432
433         /* Probably unnecessary to have a ProjectInformation here:
434         public String getName() {
435             return "testproject:" + getProjectDirectory().getNameExt();
436         }
437         
438         public String getDisplayName() {
439             return "Test Project in " + getProjectDirectory().getNameExt();
440         }
441         
442         public Image getIcon() {
443             return null;
444         }
445         
446         public void addPropertyChangeListener(PropertyChangeListener listener) {}
447         public void removePropertyChangeListener(PropertyChangeListener listener) {}
448          */

449         
450     }
451     
452     /**
453      * Open a URL of content (for example from {@link Class#getResource}) and copy it to a named file.
454      * The new file can be given as a parent directory plus a relative (slash-separated) path.
455      * The file may not already exist, but intermediate directories may or may not.
456      * If the content URL is null, the file is just created, no more; if it already existed
457      * it is touched (timestamp updated) and its contents are cleared.
458      * @return the file object
459      */

460     public static FileObject createFileFromContent(URL JavaDoc content, FileObject parent, String JavaDoc path) throws IOException JavaDoc {
461         if (parent == null) {
462             throw new IllegalArgumentException JavaDoc("null parent");
463         }
464         Assert.assertTrue("folder", parent.isFolder());
465         FileObject fo = parent;
466         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(path, "/");
467         boolean touch = false;
468         while (tok.hasMoreTokens()) {
469             Assert.assertNotNull("fo is null (parent=" + parent + " path=" + path + ")", fo);
470             String JavaDoc name = tok.nextToken();
471             if (tok.hasMoreTokens()) {
472                 FileObject sub = fo.getFileObject(name);
473                 if (sub == null) {
474                     FileObject fo2 = fo.createFolder(name);
475                     Assert.assertNotNull("createFolder(" + fo + ", " + name + ") -> null", fo2);
476                     fo = fo2;
477                 } else {
478                     Assert.assertTrue("folder", sub.isFolder());
479                     fo = sub;
480                 }
481             } else {
482                 FileObject sub = fo.getFileObject(name);
483                 if (sub == null) {
484                     FileObject fo2 = fo.createData(name);
485                     Assert.assertNotNull("createData(" + fo + ", " + name + ") -> null", fo2);
486                     fo = fo2;
487                 } else {
488                     fo = sub;
489                     touch = true;
490                 }
491             }
492         }
493         assert fo.isData();
494         if (content != null || touch) {
495             FileLock lock = fo.lock();
496             try {
497                 OutputStream JavaDoc os = fo.getOutputStream(lock);
498                 try {
499                     if (content != null) {
500                         InputStream JavaDoc is = content.openStream();
501                         try {
502                             FileUtil.copy(is, os);
503                         } finally {
504                             is.close();
505                         }
506                     }
507                 } finally {
508                     os.close();
509                 }
510             } finally {
511                 lock.releaseLock();
512             }
513         }
514         return fo;
515     }
516     
517     private static final class Repo extends Repository {
518         
519         public Repo(NbTestCase t) throws Exception JavaDoc {
520             super(mksystem(t));
521         }
522         
523         private static FileSystem mksystem(NbTestCase t) throws Exception JavaDoc {
524             LocalFileSystem lfs = new LocalFileSystem();
525             File JavaDoc systemDir = new File JavaDoc(t.getWorkDir(), "ud/system");
526             systemDir.mkdirs();
527             lfs.setRootDirectory(systemDir);
528             lfs.setReadOnly(false);
529             List JavaDoc<FileSystem> layers = new ArrayList JavaDoc<FileSystem>();
530             layers.add(lfs);
531             /*
532             //get layer for the generic server
533             java.net.URL layerFile = Repo.class.getClassLoader().getResource("org/netbeans/modules/j2ee/genericserver/resources/layer.xml");
534             assert layerFile != null;
535             layers.add(new XMLFileSystem(layerFile));
536              */

537             
538             // get layer for the AS/GlassFish
539
// addLayer(layers, "org/netbeans/modules/j2ee/sun/ide/j2ee/layer.xml");
540
// addLayer(layers, "org/netbeans/modules/tomcat5/resources/layer.xml");
541
MultiFileSystem mfs = new MultiFileSystem((FileSystem[]) layers.toArray(new FileSystem[layers.size()]));
542             return mfs;
543         }
544         
545         private static void addLayer(List JavaDoc<FileSystem> layers, String JavaDoc layerRes) throws SAXException JavaDoc {
546             URL JavaDoc layerFile = Repo.class.getClassLoader().getResource(layerRes);
547             assert layerFile != null;
548             layers.add(new XMLFileSystem(layerFile));
549         }
550         
551     }
552     
553     /** Copied from AntLoggerTest. */
554     private static final class IFL extends InstalledFileLocator {
555         
556         public IFL() {}
557         
558         public File JavaDoc locate(String JavaDoc relativePath, String JavaDoc codeNameBase, boolean localized) {
559             if (relativePath.equals("modules/ext/appsrvbridge.jar")) {
560                 String JavaDoc path = System.getProperty("test.appsrvbridge.jar");
561                 Assert.assertNotNull("must set test.appsrvbridge.jar", path);
562                 return new File JavaDoc(path);
563             }
564             return null;
565         }
566     }
567     
568 }
569
Popular Tags