KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > classpath > MergedClassPathImplementationTest


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.javacore.classpath;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.SortedSet JavaDoc;
32 import java.util.TreeSet JavaDoc;
33 import java.util.concurrent.CountDownLatch JavaDoc;
34 import java.util.logging.Handler JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import java.util.logging.LogRecord JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38 import junit.framework.Assert;
39 import org.netbeans.api.java.classpath.ClassPath;
40 import org.netbeans.api.java.classpath.GlobalPathRegistry;
41 import org.netbeans.api.java.queries.SourceForBinaryQuery.Result;
42 import org.netbeans.junit.NbTestCase;
43 import org.netbeans.spi.java.classpath.ClassPathFactory;
44 import org.netbeans.spi.java.classpath.ClassPathImplementation;
45 import org.netbeans.spi.java.classpath.PathResourceImplementation;
46 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
47 import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
48 import org.openide.filesystems.FileObject;
49 import org.openide.filesystems.FileUtil;
50 import org.openide.filesystems.URLMapper;
51 import org.openide.util.Lookup;
52 import org.openide.util.lookup.Lookups;
53 import org.openide.util.lookup.ProxyLookup;
54
55 /**
56  * @author tom
57  */

58 public class MergedClassPathImplementationTest extends NbTestCase {
59
60     private boolean failed;
61     
62     // Copied from org.netbeans.api.project.TestUtil:
63
static {
64         // XXX replace with MockServices
65
System.setProperty("org.openide.util.Lookup", Lkp.class.getName());
66         Assert.assertEquals(Lkp.class, Lookup.getDefault().getClass());
67     }
68
69     public static final class Lkp extends ProxyLookup {
70         private static Lkp DEFAULT;
71         public Lkp() {
72             Assert.assertNull(DEFAULT);
73             DEFAULT = this;
74             setLookup(new Object JavaDoc[0]);
75         }
76         public static void setLookup(Object JavaDoc[] instances) {
77             ClassLoader JavaDoc l = Lkp.class.getClassLoader();
78             DEFAULT.setLookups(new Lookup[] {
79                 Lookups.fixed(instances),
80                 Lookups.metaInfServices(l),
81                 Lookups.singleton(l),
82             });
83         }
84     }
85     
86     private static final String JavaDoc ROOT = "cproot_";
87     private static final int ROOT_COUNT = 6;
88     private FileObject[] roots;
89     
90     /** Creates a new instance of MergedClassPathImplementationTest */
91     public MergedClassPathImplementationTest (String JavaDoc name) {
92         super (name);
93     }
94     
95     
96     
97     protected void setUp() throws Exception JavaDoc {
98         super.setUp();
99         this.clearWorkDir();
100         File JavaDoc f = this.getWorkDir();
101         FileObject wd = getWorkDirFileObject ();
102         this.roots = new FileObject[ROOT_COUNT];
103         for (int i=0; i< ROOT_COUNT; i++) {
104             this.roots[i] = wd.createFolder(ROOT+i);
105         }
106     }
107     
108     protected void tearDown() throws Exception JavaDoc {
109         super.tearDown();
110     }
111     
112     
113     public void testMergedClassPath () throws IOException JavaDoc {
114         ClassPath cp_1 = ClassPathSupport.createClassPath (new FileObject[] {roots[0], roots[1]});
115         assertNotNull ("ClassPathSupport.createClassPath() returned null",cp_1);
116         ClassPath cp_2 = ClassPathSupport.createClassPath (new FileObject[] {roots[2], roots[3]});
117         assertNotNull ("ClassPathSupport.createClassPath() returned null",cp_2);
118         DynamicClassPath dympl = new DynamicClassPath();
119         ClassPath cp_3 = ClassPathFactory.createClassPath(dympl);
120         assertNotNull ("ClassPathSupport.createClassPath() returned null",cp_3);
121         GlobalPathRegistry regs = GlobalPathRegistry.getDefault();
122         regs.register(ClassPath.COMPILE, new ClassPath[] {cp_1, cp_3});
123         MergedClassPathImplementation mcpi = MergedClassPathImplementation.getDefault();
124         ClassPath mcp = ClassPathFactory.createClassPath (mcpi);
125         assertNotNull ("ClassPathSupport.createClassPath() returned null for MergedClassPathImplementation" ,mcp);
126         PathResourceImplementation[] resources = mcpi.getUnresolvedRoots();
127         assertEquivalent (resources, new FileObject[] {roots[0],roots[1]});
128         regs.register(ClassPath.COMPILE, new ClassPath[] {cp_2});
129         resources = mcpi.getUnresolvedRoots();
130         assertEquivalent (resources,new FileObject[] {roots[0],roots[1],roots[2],roots[3]});
131         dympl.setRoots(new FileObject[]{roots[4],roots[5]});
132         resources = mcpi.getUnresolvedRoots();
133         assertEquivalent (resources,new FileObject[] {roots[0],roots[1],roots[2],roots[3],roots[4],roots[5]});
134         dympl.setRoots(new FileObject[]{});
135         resources = mcpi.getUnresolvedRoots();
136         assertEquivalent (resources,new FileObject[] {roots[0],roots[1],roots[2],roots[3]});
137         dympl.setRoots(new FileObject[]{roots[2],roots[3]});
138         resources = mcpi.getUnresolvedRoots();
139         assertEquivalent (resources,new FileObject[] {roots[0],roots[1],roots[2],roots[3],roots[2],roots[3]});
140         dympl.setRoots(new FileObject[]{});
141         resources = mcpi.getUnresolvedRoots();
142         assertEquivalent (resources,new FileObject[] {roots[0],roots[1],roots[2],roots[3]});
143     }
144
145     public void testDeadlock() throws Exception JavaDoc {
146         // instantiate singleton
147
final MergedClassPathImplementation mcpi = MergedClassPathImplementation.getDefault();
148         Lkp.setLookup(new Object JavaDoc[] {
149             new SourceForBinaryQueryImplementation() {
150                 public Result findSourceRoots(URL JavaDoc binaryRoot) {
151                     Thread JavaDoc mcpiLocker = new Thread JavaDoc(new Runnable JavaDoc() {
152                         public void run() {
153                             synchronized(mcpi) {}
154                         }
155                     });
156                     mcpiLocker.start();
157                     try {
158                         mcpiLocker.join();
159                     } catch (InterruptedException JavaDoc ie) {
160                         ie.printStackTrace();
161                         failed = true;
162                     }
163                     return null;
164                 }
165             }
166         });
167         final DynamicClassPath dympl = new DynamicClassPath();
168         ClassPath cp = ClassPathFactory.createClassPath(dympl);
169         GlobalPathRegistry regs = GlobalPathRegistry.getDefault();
170         regs.register(ClassPath.COMPILE, new ClassPath[] {cp});
171         dympl.setRoots(new FileObject[]{roots[0]});
172         assertFalse(failed);
173     }
174     
175     public void testRaceCondition84603 () throws Exception JavaDoc {
176         final MergedClassPathImplementation mcpi = MergedClassPathImplementation.getDefault();
177         final DynamicClassPath dympl = new DynamicClassPath();
178         final ClassPath cp = ClassPathFactory.createClassPath(dympl);
179         final GlobalPathRegistry regs = GlobalPathRegistry.getDefault();
180         regs.register(ClassPath.COMPILE, new ClassPath[] {cp});
181         final CountDownLatch JavaDoc start = new CountDownLatch JavaDoc (1);
182         final CountDownLatch JavaDoc end = new CountDownLatch JavaDoc (1);
183         class RCHandler extends Handler JavaDoc implements Runnable JavaDoc {
184             
185             private Thread JavaDoc thread;
186             
187             public void publish(LogRecord JavaDoc record) {
188                 if (this.thread == Thread.currentThread()) {
189                     start.countDown();
190                     try {
191                         end.await();
192                     } catch (InterruptedException JavaDoc ie) {}
193                 }
194             }
195             
196             public void run () {
197                 try {
198                     this.thread = Thread.currentThread();
199                     dympl.setRoots(new FileObject[] {roots[0]});
200                 } catch (IOException JavaDoc ioe) {
201                     ioe.printStackTrace();
202                 }
203             }
204
205             public void flush() {
206             }
207
208             public void close() throws SecurityException JavaDoc {
209             }
210         };
211                 
212         final RCHandler handler = new RCHandler ();
213         final Logger JavaDoc log = Logger.getLogger("TEST-"+MergedClassPathImplementation.class.getName());
214         log.addHandler(handler);
215         try {
216         Thread JavaDoc t = new Thread JavaDoc (handler);
217         t.start();
218         try {
219             start.await();
220             dympl.setRoots(new FileObject[] {roots[1]}); //when racecondition an AssertionError is thrown from the MCPI
221
} finally {
222             end.countDown();
223         }
224         } finally {
225             log.removeHandler(handler);
226         }
227     }
228     
229     private FileObject getWorkDirFileObject () throws IOException JavaDoc {
230         FileObject fos = FileUtil.toFileObject(this.getWorkDir());
231         if (fos != null) {
232             return fos;
233         }
234         else {
235             throw new IllegalStateException JavaDoc ("Can not resolve FileObject for home dir");
236         }
237     }
238     
239     private static void assertEquivalent(List JavaDoc entries, FileObject[] roots) throws IOException JavaDoc {
240         assertNotNull("Entries are null", entries);
241         assertNotNull("Roots are null", roots);
242         SortedSet JavaDoc/*<String>*/ expected = new TreeSet JavaDoc(), actual = new TreeSet JavaDoc();
243         for (int i = 0; i < roots.length; i++) {
244             expected.add(roots[i].getURL().toExternalForm());
245         }
246         Iterator JavaDoc it = entries.iterator();
247         while (it.hasNext()) {
248             ClassPath.Entry entry = (ClassPath.Entry) it.next();
249             actual.add(entry.getURL().toExternalForm());
250         }
251         assertEquals("Correct entry URLs", expected, actual);
252     }
253     
254     private static void assertEquivalent (PathResourceImplementation[] resources, FileObject[] roots) {
255         assertNotNull("Entries are null", resources);
256         assertNotNull("Roots are null", roots);
257         assertEquals("Different length",resources.length,roots.length);
258         for (int i=0; i<resources.length; i++) {
259             URL JavaDoc[] urls = resources[i].getRoots();
260             for (int j=0; j<urls.length; j++) {
261                 FileObject fo = URLMapper.findFileObject(urls[j]);
262                 assertNotNull (fo);
263                 assertEquals ("Invalid root",roots[i],fo);
264             }
265         }
266     }
267
268     protected Level JavaDoc logLevel() {
269         return Level.FINEST;
270     }
271     
272     private static class DynamicClassPath implements ClassPathImplementation {
273         
274         public PropertyChangeSupport JavaDoc support;
275         private List JavaDoc roots = Collections.EMPTY_LIST;
276         
277         public DynamicClassPath () {
278             this.support = new PropertyChangeSupport JavaDoc (this);
279         }
280         
281         public void setRoots (FileObject[] roots) throws IOException JavaDoc {
282             List JavaDoc newRoots = new ArrayList JavaDoc ();
283             for (int i=0; i< roots.length; i++) {
284                 PathResourceImplementation impl = ClassPathSupport.createResource(roots[i].getURL());
285                 newRoots.add(impl);
286             }
287             this.roots = newRoots;
288             this.support.firePropertyChange(PROP_RESOURCES,null,null);
289         }
290         
291         public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
292             this.support.addPropertyChangeListener (listener);
293         }
294         
295         public List JavaDoc getResources() {
296             return Collections.unmodifiableList(this.roots);
297         }
298         
299         public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
300             this.support.removePropertyChangeListener (listener);
301         }
302     }
303 }
304
Popular Tags