1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
package org.apache.commons.classscan.builtin; |
15 | |
|
16 | |
import java.io.IOException; |
17 | |
import java.io.InputStream; |
18 | |
import java.net.URL; |
19 | |
import java.util.Map; |
20 | |
import java.util.ServiceConfigurationError; |
21 | |
|
22 | |
import org.apache.commons.classscan.ClassPathElement; |
23 | |
import org.apache.commons.classscan.MetaClassLoader; |
24 | |
import org.apache.commons.classscan.MetaClassPathElement; |
25 | |
import org.apache.commons.classscan.spi.ClassDigesterFactory; |
26 | |
import org.apache.commons.classscan.spi.ClassPathElementFactory; |
27 | |
import org.apache.commons.classscan.spi.ClassPathFactory; |
28 | |
import org.apache.commons.classscan.spi.model.SpiClassDigester; |
29 | |
import org.apache.commons.classscan.spi.model.SpiClassPath; |
30 | |
import org.apache.commons.classscan.spi.model.SpiClassPathElement; |
31 | |
import org.apache.commons.classscan.spi.model.SpiMetaClass; |
32 | |
import org.apache.commons.classscan.spi.model.SpiMetaClassPathElement; |
33 | |
import org.apache.commons.classscan.spi.model.SpiMetaRegistry; |
34 | |
import org.apache.commons.classscan.util.FactoryCache; |
35 | |
import org.apache.commons.classscan.util.ReapingHashMap; |
36 | |
import org.apache.commons.classscan.util.ServiceVisitor; |
37 | |
import org.slf4j.Logger; |
38 | |
import org.slf4j.LoggerFactory; |
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | 0 | public class DefaultMetaRegistry implements SpiMetaRegistry { |
46 | |
|
47 | 0 | private static final Logger logger = LoggerFactory.getLogger(DefaultMetaRegistry.class); |
48 | |
|
49 | |
private final Map<ClassLoader, MetaClassLoader> metaClassLoaders; |
50 | |
private final FactoryCache<ClassPathFactory> classPathFactories; |
51 | |
private final FactoryCache<ClassPathElementFactory> classPathElementFactories; |
52 | |
private SpiClassDigester classDigester; |
53 | |
|
54 | 0 | public DefaultMetaRegistry() { |
55 | 0 | metaClassLoaders = new ReapingHashMap<ClassLoader, MetaClassLoader>(); |
56 | 0 | ClassLoader classLoader = getClass().getClassLoader(); |
57 | 0 | classPathFactories = new FactoryCache<ClassPathFactory>(ClassPathFactory.class, classLoader); |
58 | 0 | classPathElementFactories = new FactoryCache<ClassPathElementFactory>(ClassPathElementFactory.class, classLoader); |
59 | |
|
60 | 0 | findClassDigester(classLoader); |
61 | 0 | } |
62 | |
|
63 | |
private void findClassDigester(ClassLoader classLoader) { |
64 | 0 | new ServiceVisitor<ClassDigesterFactory>() { |
65 | |
@Override |
66 | |
protected boolean visit(ClassDigesterFactory factory) { |
67 | |
try { |
68 | 0 | classDigester= factory.createDigester(DefaultMetaRegistry.this); |
69 | 0 | return false; |
70 | |
} |
71 | 0 | catch(Throwable error) { |
72 | 0 | logger.warn("Ignoring configuration error", error); |
73 | 0 | return true; |
74 | |
} |
75 | |
} |
76 | |
}.visitProviders(ClassDigesterFactory.class, classLoader); |
77 | |
|
78 | 0 | if(classDigester==null) { |
79 | 0 | throw new ServiceConfigurationError("Could not load a ClassDigester"); |
80 | |
} |
81 | 0 | } |
82 | |
|
83 | |
@Override |
84 | |
public MetaClassLoader getMetaClassLoader(ClassLoader classLoader) { |
85 | 0 | synchronized(metaClassLoaders) { |
86 | 0 | MetaClassLoader mcl = metaClassLoaders.get(classLoader); |
87 | 0 | if (mcl == null) { |
88 | 0 | mcl = createMetaClassLoader(classLoader); |
89 | 0 | metaClassLoaders.put(classLoader, mcl); |
90 | |
} |
91 | 0 | return mcl; |
92 | 0 | } |
93 | |
} |
94 | |
|
95 | |
public MetaClassLoader createMetaClassLoader(ClassLoader classLoader) { |
96 | 0 | SpiClassPath cp= getClassPath(classLoader); |
97 | 0 | return cp.createMetaClassLoader(this, classLoader); |
98 | |
} |
99 | |
|
100 | |
@Override |
101 | |
public SpiClassPath getClassPath(ClassLoader classLoader) { |
102 | |
|
103 | 0 | for(ClassPathFactory factory : classPathFactories) { |
104 | 0 | SpiClassPath cp= factory.getClassPath(this, classLoader); |
105 | 0 | if(cp!=null) { |
106 | 0 | return cp; |
107 | |
} |
108 | 0 | } |
109 | |
|
110 | 0 | throw new IllegalArgumentException("No ClassPathFactory found for ClassLoader "+classLoader); |
111 | |
} |
112 | |
|
113 | |
@Override |
114 | |
public SpiClassPathElement createClassPathElement(URL url) throws IOException { |
115 | |
|
116 | 0 | for(ClassPathElementFactory factory : classPathElementFactories) { |
117 | 0 | SpiClassPathElement cp= factory.getClassPathElement(this, url); |
118 | 0 | if(cp!=null) { |
119 | 0 | return cp; |
120 | |
} |
121 | 0 | } |
122 | |
|
123 | 0 | return null; |
124 | |
} |
125 | |
|
126 | |
@Override |
127 | |
public SpiMetaClassPathElement createMetaClassPathElement(ClassPathElement pathElement) { |
128 | 0 | return new DefaultMetaClassPathElement(this, pathElement); |
129 | |
} |
130 | |
|
131 | |
@Override |
132 | |
public SpiMetaClass createMetaClass(MetaClassPathElement location, String className, InputStream byteStream) throws IOException { |
133 | |
try { |
134 | 0 | SpiMetaClass smc = classDigester.createMetaClass(location, className, byteStream); |
135 | 0 | if (!className.equals(smc.getName())) { |
136 | 0 | throw new IllegalArgumentException("Expecting classname " + className + " but found " + smc.getName()); |
137 | |
} |
138 | 0 | return smc; |
139 | |
} |
140 | |
finally { |
141 | 0 | byteStream.close(); |
142 | |
} |
143 | |
} |
144 | |
} |