001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.discovery.test;
018    
019    import static junit.framework.Assert.assertEquals;
020    import static junit.framework.Assert.assertNotNull;
021    import static junit.framework.Assert.assertTrue;
022    import static junit.framework.Assert.fail;
023    import static org.apache.commons.discovery.tools.SPInterface.newSPInterface;
024    import static org.apache.commons.discovery.tools.Service.providers;
025    
026    import java.net.URL;
027    import java.util.Enumeration;
028    import java.util.Properties;
029    
030    import org.apache.commons.discovery.Resource;
031    import org.apache.commons.discovery.ResourceClass;
032    import org.apache.commons.discovery.ResourceClassIterator;
033    import org.apache.commons.discovery.ResourceIterator;
034    import org.apache.commons.discovery.jdk.JDKHooks;
035    import org.apache.commons.discovery.resource.ClassLoaders;
036    import org.apache.commons.discovery.resource.DiscoverResources;
037    import org.apache.commons.discovery.resource.classes.DiscoverClasses;
038    import org.apache.commons.discovery.tools.DefaultClassHolder;
039    import org.apache.commons.discovery.tools.DiscoverClass;
040    import org.apache.commons.discovery.tools.DiscoverSingleton;
041    import org.apache.commons.discovery.tools.ManagedProperties;
042    import org.apache.commons.discovery.tools.PropertiesHolder;
043    import org.apache.commons.discovery.tools.SPInterface;
044    import org.apache.commons.logging.Log;
045    import org.junit.Test;
046    
047    /**
048     * @version $Revision: 1090705 $
049     */
050    public class TestAll {
051    
052        @Test
053        public void findDefaultImpl_1() {
054            TestInterface1 ti = null;
055    
056            try {
057                ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName());
058    
059                assertTrue(ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
060                           ti.getClass().getName().equals(TestImpl1_1.class.getName()));
061            } finally {
062                DiscoverSingleton.release();
063            }
064        }
065    
066        @Test
067        public void findDefaultImpl_2() {
068            TestInterface1 ti = null;
069    
070            try {
071                ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName());
072    
073                assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
074                           ti.getClass().getName().equals(TestImpl1_2.class.getName()));
075            } finally {
076                DiscoverSingleton.release();
077            }
078        }
079    
080        @Test
081        public void cacheAssertions() {
082            TestInterface1 ti = null;
083    
084            try {
085                ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName());
086    
087                assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
088                           ti.getClass().getName().equals(TestImpl1_1.class.getName()));
089    
090                // no release, should get cached value..
091    
092                ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName());
093    
094                // factory should be cached
095                assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
096                           ti.getClass().getName().equals(TestImpl1_1.class.getName()));
097            } finally {
098                DiscoverSingleton.release();
099            }
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    }