1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.discovery.test;
18  
19  import static junit.framework.Assert.assertEquals;
20  import static junit.framework.Assert.assertNotNull;
21  import static junit.framework.Assert.assertTrue;
22  import static junit.framework.Assert.fail;
23  import static org.apache.commons.discovery.tools.SPInterface.newSPInterface;
24  import static org.apache.commons.discovery.tools.Service.providers;
25  
26  import java.net.URL;
27  import java.util.Enumeration;
28  import java.util.Properties;
29  
30  import org.apache.commons.discovery.Resource;
31  import org.apache.commons.discovery.ResourceClass;
32  import org.apache.commons.discovery.ResourceClassIterator;
33  import org.apache.commons.discovery.ResourceIterator;
34  import org.apache.commons.discovery.jdk.JDKHooks;
35  import org.apache.commons.discovery.resource.ClassLoaders;
36  import org.apache.commons.discovery.resource.DiscoverResources;
37  import org.apache.commons.discovery.resource.classes.DiscoverClasses;
38  import org.apache.commons.discovery.tools.DefaultClassHolder;
39  import org.apache.commons.discovery.tools.DiscoverClass;
40  import org.apache.commons.discovery.tools.DiscoverSingleton;
41  import org.apache.commons.discovery.tools.ManagedProperties;
42  import org.apache.commons.discovery.tools.PropertiesHolder;
43  import org.apache.commons.discovery.tools.SPInterface;
44  import org.apache.commons.logging.Log;
45  import org.junit.Test;
46  
47  /**
48   * @version $Revision: 1090705 $
49   */
50  public class TestAll {
51  
52      @Test
53      public void findDefaultImpl_1() {
54          TestInterface1 ti = null;
55  
56          try {
57              ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName());
58  
59              assertTrue(ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
60                         ti.getClass().getName().equals(TestImpl1_1.class.getName()));
61          } finally {
62              DiscoverSingleton.release();
63          }
64      }
65  
66      @Test
67      public void findDefaultImpl_2() {
68          TestInterface1 ti = null;
69  
70          try {
71              ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName());
72  
73              assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
74                         ti.getClass().getName().equals(TestImpl1_2.class.getName()));
75          } finally {
76              DiscoverSingleton.release();
77          }
78      }
79  
80      @Test
81      public void cacheAssertions() {
82          TestInterface1 ti = null;
83  
84          try {
85              ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName());
86  
87              assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
88                         ti.getClass().getName().equals(TestImpl1_1.class.getName()));
89  
90              // no release, should get cached value..
91  
92              ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName());
93  
94              // factory should be cached
95              assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
96                         ti.getClass().getName().equals(TestImpl1_1.class.getName()));
97          } finally {
98              DiscoverSingleton.release();
99          }
100     }
101 
102     @Test
103     public void releaseAssertions() {
104         TestInterface1 ti = null;
105 
106         try {
107             ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName());
108 
109             assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
110                        ti.getClass().getName().equals(TestImpl1_1.class.getName()));
111 
112             DiscoverSingleton.release();
113 
114             ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName());
115 
116             // factory should be cached
117             assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
118                        ti.getClass().getName().equals(TestImpl1_2.class.getName()));
119         } finally {
120             DiscoverSingleton.release();
121         }
122     }
123 
124     @Test
125     public void findPropertyImpl_1() {
126         TestInterface1 ti = null;
127 
128         try {
129             Properties props = new Properties();
130 
131             props.setProperty(TestInterface1.class.getName(), TestImpl1_2.class.getName());
132 
133             ti = DiscoverSingleton.find(TestInterface1.class, props);
134 
135             assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
136                        ti.getClass().getName().equals(TestImpl1_2.class.getName()));
137         } finally {
138             DiscoverSingleton.release();
139         }
140     }
141 
142     @Test
143     public void myFactoryManagedProperty() {
144         TestInterface1 ti = null;
145 
146         try {
147             ManagedProperties.setProperty(TestInterface1.class.getName(), TestImpl1_2.class.getName());
148 
149             ti = DiscoverSingleton.find(TestInterface1.class);
150 
151             assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
152                        ti.getClass().getName().equals(TestImpl1_2.class.getName()));
153         } finally {
154             DiscoverSingleton.release();
155 
156             /*
157              * Cleanup, don't want to affect next test..
158              */
159             ManagedProperties.setProperty(TestInterface1.class.getName(), null);
160         }
161     }
162 
163     @Test
164     public void findPropFileDefault() {
165         TestInterface1 ti = null;
166 
167         try {
168             ti = DiscoverSingleton.find(null,
169                                    new SPInterface<TestInterface1>(TestInterface1.class),
170                                    new PropertiesHolder("TestInterface.properties"),
171                                    new DefaultClassHolder<TestInterface1>(TestImpl1_2.class.getName()));
172 
173             assertTrue(ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
174                        ti.getClass().getName().equals(TestImpl1_1.class.getName()));
175         } finally {
176             DiscoverSingleton.release();
177         }
178     }
179 
180     @Test
181     public void findServiceFileDefault() {
182         TestInterface2 ti = null;
183 
184         try {
185             ti = DiscoverSingleton.find(null,
186                                    new SPInterface<TestInterface2>(TestInterface2.class),
187                                    null,
188                                    new DefaultClassHolder<TestInterface2>(TestImpl2_2.class.getName()));
189 
190             assertTrue(ti.getClass().getName() + "!=" + TestImpl2_1.class.getName(),
191                        ti.getClass().getName().equals(TestImpl2_1.class.getName()));
192         } finally {
193             DiscoverSingleton.release();
194         }
195     }
196 
197     @Test
198     public void lowLevelFind() {
199         ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false);
200         String name = "org.apache.commons.discovery.test.TestImpl2_1";
201 
202         DiscoverClasses<TestInterface2> discovery = new DiscoverClasses<TestInterface2>(loaders);
203         ResourceClassIterator<TestInterface2> iter = discovery.findResourceClasses(name);
204         while (iter.hasNext()) {
205             ResourceClass<TestInterface2> resource = iter.nextResourceClass();
206             try {
207                 Class<? extends TestInterface2> implClass = resource.loadClass();
208                 if ( implClass != null ) {
209                     assertEquals("org.apache.commons.discovery.test.TestImpl2_1", implClass.getName());
210                     return;
211                 }
212             } catch (Exception e) {
213                 fail("Could not load service: " + resource );
214             }
215         }
216         fail("failed to load class resource: " + name);
217     }
218 
219     @Test
220     public void findResources() {
221         ClassLoaders loaders = new ClassLoaders();
222 
223         /*
224          * To many class loaders when searching for multiple
225          * resources means that we can find the same (same URL)
226          * resource for each loader...
227          * let's keep this to a minimum.
228          */
229         ClassLoader cl = getClass().getClassLoader();
230         if (cl != null) {
231             loaders.put(getClass().getClassLoader(), true);
232         } else {
233             loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), true);
234         }
235 
236         String name = "testResource";
237 
238         String partialPaths[] = { "/test-classes/", "/testAlt1/", "/testAlt2/" };
239         int expected = partialPaths.length;
240 
241         DiscoverResources discovery = new DiscoverResources(loaders);
242         ResourceIterator iter = discovery.findResources(name);
243         int count = 0;
244 
245         while (iter.hasNext()) {
246             Resource resource = iter.nextResource();
247             URL url = resource.getResource();
248             if (url != null) {
249                 if (url.getFile().indexOf(partialPaths[count]) == -1) {
250                     fail(url + " does not contain " + partialPaths[count]);
251                 }
252                 count++;
253             }
254         }
255 
256         if (count != expected) {
257             fail("located " + count + " resources, failed to locate all " + expected + " resources: " + name);
258         }
259     }
260 
261     @Test
262     public void findViaDiscoverClass() {
263         ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false);
264 
265         DiscoverClass discover = new DiscoverClass(loaders);
266         Class<? extends TestInterface2> implClass = discover.find(TestInterface2.class);
267 
268         assertTrue("Failed to find an implementation class", implClass != null);
269         assertEquals("org.apache.commons.discovery.test.TestImpl2_1", implClass.getName());
270     }
271 
272     @Test
273     public void findInnerImplViaDiscoverClass() {
274         ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface3.class, getClass(), false);
275 
276         DiscoverClass discover = new DiscoverClass(loaders);
277         Class<? extends TestInterface3> implClass = discover.find(TestInterface3.class);
278 
279         assertTrue("Failed to find an implementation class", implClass != null);
280         assertEquals("org.apache.commons.discovery.test.TestImpl3$InnerTestImpl", implClass.getName());
281 
282     }
283 
284     @Test
285     public void instantiateViaDiscoverClass() throws Exception {
286         ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false);
287 
288         DiscoverClass discoverClass = new DiscoverClass(loaders);
289         TestInterface2 serviceImpl = discoverClass.newInstance(TestInterface2.class);
290 
291         assertNotNull(serviceImpl);
292         assertEquals(TestImpl2_1.class, serviceImpl.getClass());
293     }
294 
295     @Test
296     public void findImplementationsViaService() {
297         final int expectedLogImplementations = 2;
298         int actualLogImplementations = 0;
299 
300         Enumeration<? extends Log> logImplementations = providers(newSPInterface(Log.class,
301                 new Class<?>[]{ String.class },
302                 new Object[]{ getClass().getName() }),
303                 null);
304 
305         while (logImplementations.hasMoreElements()) {
306             Log log = logImplementations.nextElement();
307             assertNotNull(log);
308             actualLogImplementations++;
309         }
310 
311         assertEquals(expectedLogImplementations, actualLogImplementations);
312     }
313 
314 }