KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > clientproject > 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.j2ee.clientproject.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.clientproject.TestPlatformProvider;
43 import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry;
44 import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
45 import org.netbeans.spi.project.ProjectFactory;
46 import org.netbeans.spi.project.ProjectState;
47 import org.openide.filesystems.FileLock;
48 import org.openide.filesystems.FileObject;
49 import org.openide.filesystems.FileSystem;
50 import org.openide.filesystems.FileUtil;
51 import org.openide.filesystems.LocalFileSystem;
52 import org.openide.filesystems.MultiFileSystem;
53 import org.openide.filesystems.Repository;
54 import org.openide.filesystems.URLMapper;
55 import org.openide.filesystems.XMLFileSystem;
56 import org.openide.util.Lookup;
57 import org.openide.util.lookup.Lookups;
58 import org.openide.util.lookup.ProxyLookup;
59 import org.xml.sax.SAXException JavaDoc;
60
61 /**
62  * Help set up org.netbeans.api.project.*Test.
63  * @author Jesse Glick
64  * @author Lukas Jungmann
65  */

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

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

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

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

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

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

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

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

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

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

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

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

241     public static String JavaDoc registerSunAppServer(NbTestCase test) throws Exception JavaDoc {
242         String JavaDoc oldNbHome = System.getProperty("netbeans.home"); // NOI18N
243
String JavaDoc oldNbUser = System.getProperty("netbeans.user"); // NOI18N
244
File JavaDoc workDir = test.getWorkDir();
245         File JavaDoc systemDir = new File JavaDoc(workDir, "ud/system"); // NOI18N
246
new File JavaDoc(systemDir, "J2EE/InstalledServers").mkdirs(); // NOI18N
247
new File JavaDoc(systemDir, "J2EE/DeploymentPlugins").mkdirs(); // NOI18N
248
new File JavaDoc(workDir, "nb").mkdirs(); // NOI18N
249
System.setProperty("netbeans.home", new File JavaDoc(workDir, "nb").getAbsolutePath()); // NOI18N
250
System.setProperty("netbeans.user", new File JavaDoc(workDir, "ud").getAbsolutePath()); // NOI18N
251
TestUtil.setLookup(new Object JavaDoc[] {new Repo(test), new TestPlatformProvider()});
252         File JavaDoc asRoot = extractAppSrv(workDir, new File JavaDoc(test.getDataDir(), "SunAppServer.zip")); // NOI18N
253
FileObject dir = Repository.getDefault().getDefaultFileSystem().findResource("/J2EE/InstalledServers"); // NOI18N
254
String JavaDoc name = FileUtil.findFreeFileName(dir, "instance", null); // NOI18N
255
FileObject instanceFO = dir.createData(name);
256         String JavaDoc serverID = "[" + asRoot.getAbsolutePath() + "]deployer:Sun:AppServer::localhost:4848"; // NOI18N
257
instanceFO.setAttribute(InstanceProperties.URL_ATTR, serverID);
258         instanceFO.setAttribute(InstanceProperties.USERNAME_ATTR, "admin"); // NOI18N
259
instanceFO.setAttribute(InstanceProperties.PASSWORD_ATTR, "adminadmin"); // NOI18N
260
instanceFO.setAttribute(InstanceProperties.DISPLAY_NAME_ATTR, "testdname"); // NOI18N
261
instanceFO.setAttribute(InstanceProperties.HTTP_PORT_NUMBER, "4848"); // NOI18N
262
instanceFO.setAttribute("DOMAIN", "testdomain1"); // NOI18N
263
instanceFO.setAttribute("LOCATION", new File JavaDoc(asRoot, "domains").getAbsolutePath()); // NOI18N
264
ServerRegistry sr = ServerRegistry.getInstance();
265         sr.addInstance(instanceFO);
266         if (oldNbHome != null) {
267             System.setProperty("netbeans.home", oldNbHome); // NOI18N
268
}
269         if (oldNbUser != null) {
270             System.setProperty("netbeans.user", oldNbUser); // NOI18N
271
}
272         return serverID;
273     }
274     
275     private static File JavaDoc extractAppSrv(File JavaDoc destDir, File JavaDoc archiveFile) throws IOException JavaDoc {
276         ZipInputStream JavaDoc zis = null;
277         BufferedOutputStream JavaDoc dest = null;
278         try {
279             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(archiveFile);
280             zis = new ZipInputStream JavaDoc(new BufferedInputStream JavaDoc(fis));
281             ZipEntry JavaDoc entry;
282             while((entry = zis.getNextEntry()) != null) {
283                 byte data[] = new byte[BUFFER];
284                 File JavaDoc entryFile = new File JavaDoc(destDir, entry.getName());
285                 if (entry.isDirectory()) {
286                     entryFile.mkdirs();
287                 } else {
288                     entryFile.getParentFile().mkdirs();
289                     FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(entryFile);
290                     dest = new BufferedOutputStream JavaDoc(fos, BUFFER);
291                     int count;
292                     while ((count = zis.read(data, 0, BUFFER)) != -1) {
293                         dest.write(data, 0, count);
294                     }
295                     dest.flush();
296                 }
297             }
298         } finally {
299             if (zis != null) { zis.close(); }
300             if (dest != null) { dest.close(); }
301         }
302         return new File JavaDoc(destDir, archiveFile.getName().substring(0, archiveFile.getName().length() - 4));
303     }
304     
305     /**
306      * If set to something non-null, loading a broken project will wait for
307      * notification on this monitor before throwing an exception.
308      * @see ProjectManagerTest#testLoadExceptionWithConcurrentLoad
309      */

310     public static Object JavaDoc BROKEN_PROJECT_LOAD_LOCK = null;
311     
312     private static final class TestProjectFactory implements ProjectFactory {
313         
314         TestProjectFactory() {}
315         
316         public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException JavaDoc {
317             Integer JavaDoc i = loadCount.get(projectDirectory);
318             if (i == null) {
319                 i = 1;
320             } else {
321                 i++;
322             }
323             loadCount.put(projectDirectory, i);
324             FileObject testproject = projectDirectory.getFileObject("testproject");
325             if (testproject != null && testproject.isFolder()) {
326                 if (testproject.getFileObject("broken") != null) {
327                     if (BROKEN_PROJECT_LOAD_LOCK != null) {
328                         synchronized (BROKEN_PROJECT_LOAD_LOCK) {
329                             try {
330                                 BROKEN_PROJECT_LOAD_LOCK.wait();
331                             } catch (InterruptedException JavaDoc e) {
332                                 assert false : e;
333                             }
334                         }
335                     }
336                     throw new IOException JavaDoc("Load failed of " + projectDirectory);
337                 } else {
338                     return new TestProject(projectDirectory, state);
339                 }
340             } else {
341                 return null;
342             }
343         }
344         
345         public void saveProject(Project project) throws IOException JavaDoc, ClassCastException JavaDoc {
346             TestProject p = (TestProject)project;
347             Throwable JavaDoc t = p.error;
348             if (t != null) {
349                 p.error = null;
350                 if (t instanceof IOException JavaDoc) {
351                     throw (IOException JavaDoc)t;
352                 } else if (t instanceof Error JavaDoc) {
353                     throw (Error JavaDoc)t;
354                 } else {
355                     throw (RuntimeException JavaDoc)t;
356                 }
357             }
358             p.saveCount++;
359         }
360         
361         public boolean isProject(FileObject dir) {
362             FileObject testproject = dir.getFileObject("testproject");
363             return testproject != null && testproject.isFolder();
364         }
365         
366     }
367     
368     private static final class TestProject implements Project {
369         
370         private final FileObject dir;
371         final ProjectState state;
372         Throwable JavaDoc error;
373         int saveCount = 0;
374         
375         public TestProject(FileObject dir, ProjectState state) {
376             this.dir = dir;
377             this.state = state;
378         }
379         
380         public Lookup getLookup() {
381             return Lookup.EMPTY;
382         }
383         
384         public FileObject getProjectDirectory() {
385             return dir;
386         }
387         
388         public String JavaDoc toString() {
389             return "testproject:" + getProjectDirectory().getNameExt();
390         }
391         
392         /* Probably unnecessary to have a ProjectInformation here:
393         public String getName() {
394             return "testproject:" + getProjectDirectory().getNameExt();
395         }
396          
397         public String getDisplayName() {
398             return "Test Project in " + getProjectDirectory().getNameExt();
399         }
400          
401         public Image getIcon() {
402             return null;
403         }
404          
405         public void addPropertyChangeListener(PropertyChangeListener listener) {}
406         public void removePropertyChangeListener(PropertyChangeListener listener) {}
407          */

408         
409     }
410     
411     /**
412      * Open a URL of content (for example from {@link Class#getResource}) and copy it to a named file.
413      * The new file can be given as a parent directory plus a relative (slash-separated) path.
414      * The file may not already exist, but intermediate directories may or may not.
415      * If the content URL is null, the file is just created, no more; if it already existed
416      * it is touched (timestamp updated) and its contents are cleared.
417      * @return the file object
418      */

419     public static FileObject createFileFromContent(URL JavaDoc content, FileObject parent, String JavaDoc path) throws IOException JavaDoc {
420         if (parent == null) {
421             throw new IllegalArgumentException JavaDoc("null parent");
422         }
423         Assert.assertTrue("folder", parent.isFolder());
424         FileObject fo = parent;
425         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(path, "/");
426         boolean touch = false;
427         while (tok.hasMoreTokens()) {
428             Assert.assertNotNull("fo is null (parent=" + parent + " path=" + path + ")", fo);
429             String JavaDoc name = tok.nextToken();
430             if (tok.hasMoreTokens()) {
431                 FileObject sub = fo.getFileObject(name);
432                 if (sub == null) {
433                     FileObject fo2 = fo.createFolder(name);
434                     Assert.assertNotNull("createFolder(" + fo + ", " + name + ") -> null", fo2);
435                     fo = fo2;
436                 } else {
437                     Assert.assertTrue("folder", sub.isFolder());
438                     fo = sub;
439                 }
440             } else {
441                 FileObject sub = fo.getFileObject(name);
442                 if (sub == null) {
443                     FileObject fo2 = fo.createData(name);
444                     Assert.assertNotNull("createData(" + fo + ", " + name + ") -> null", fo2);
445                     fo = fo2;
446                 } else {
447                     fo = sub;
448                     touch = true;
449                 }
450             }
451         }
452         assert fo.isData();
453         if (content != null || touch) {
454             FileLock lock = fo.lock();
455             try {
456                 OutputStream JavaDoc os = fo.getOutputStream(lock);
457                 try {
458                     if (content != null) {
459                         InputStream JavaDoc is = content.openStream();
460                         try {
461                             FileUtil.copy(is, os);
462                         } finally {
463                             is.close();
464                         }
465                     }
466                 } finally {
467                     os.close();
468                 }
469             } finally {
470                 lock.releaseLock();
471             }
472         }
473         return fo;
474     }
475
476     private static final class Repo extends Repository {
477         
478         public Repo(NbTestCase t) throws Exception JavaDoc {
479             super(mksystem(t));
480         }
481         
482         private static FileSystem mksystem(NbTestCase t) throws Exception JavaDoc {
483             LocalFileSystem lfs = new LocalFileSystem();
484             File JavaDoc systemDir = new File JavaDoc(t.getWorkDir(), "ud/system");
485             systemDir.mkdirs();
486             lfs.setRootDirectory(systemDir);
487             lfs.setReadOnly(false);
488             List JavaDoc<FileSystem> layers = new ArrayList JavaDoc<FileSystem>();
489             layers.add(lfs);
490             // get layer for the AS/GlassFish
491
addLayer(layers, "org/netbeans/modules/j2ee/sun/ide/j2ee/layer.xml");
492             // get layer for the j2ee/clientproject
493
addLayer(layers, "org/netbeans/modules/j2ee/clientproject/ui/resources/layer.xml");
494             // get layer for the websvc/core
495
addLayer(layers, "org/netbeans/modules/websvc/core/resources/mf-layer.xml");
496             // get layer for the java support (for Main class template)
497
addLayer(layers, "org/netbeans/modules/java/resources/mf-layer.xml");
498             MultiFileSystem mfs = new MultiFileSystem((FileSystem[]) layers.toArray(new FileSystem[layers.size()]));
499             return mfs;
500         }
501         
502         private static void addLayer(List JavaDoc<FileSystem> layers, String JavaDoc layerRes) throws SAXException JavaDoc {
503             URL JavaDoc layerFile = Repo.class.getClassLoader().getResource(layerRes);
504             assert layerFile != null;
505             layers.add(new XMLFileSystem(layerFile));
506         }
507         
508     }
509     
510     /**
511      * Make a temporary copy of a whole folder into some new dir in the scratch
512      * area. Stolen from ant/freeform.
513      */

514     public static File JavaDoc copyFolder(final File JavaDoc targetDir, final File JavaDoc d) throws IOException JavaDoc {
515         assert d.isDirectory();
516         File JavaDoc workdir = targetDir;
517         String JavaDoc name = d.getName();
518         while (name.length() < 3) {
519             name = name + "x";
520         }
521         File JavaDoc todir = workdir.createTempFile(name, null, workdir);
522         todir.delete();
523         doCopy(d, todir);
524         return todir;
525     }
526     
527     private static void doCopy(File JavaDoc from, File JavaDoc to) throws IOException JavaDoc {
528         if (from.isDirectory()) {
529             if (from.getName().equals("CVS")) {
530                 return;
531             }
532             to.mkdir();
533             String JavaDoc[] kids = from.list();
534             for (int i = 0; i < kids.length; i++) {
535                 doCopy(new File JavaDoc(from, kids[i]), new File JavaDoc(to, kids[i]));
536             }
537         } else {
538             assert from.isFile();
539             InputStream JavaDoc is = new FileInputStream JavaDoc(from);
540             try {
541                 OutputStream JavaDoc os = new FileOutputStream JavaDoc(to);
542                 try {
543                     FileUtil.copy(is, os);
544                 } finally {
545                     os.close();
546                 }
547             } finally {
548                 is.close();
549             }
550         }
551     }
552     
553 }
554
Popular Tags