1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jmonit.features;
17
18 import java.io.InputStream;
19 import java.lang.reflect.Field;
20 import java.net.URL;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.Iterator;
25 import java.util.LinkedList;
26 import java.util.Map;
27 import java.util.Properties;
28 import java.util.Set;
29 import java.util.concurrent.ConcurrentHashMap;
30
31 import org.jmonit.log.Log;
32 import org.jmonit.spi.Factory;
33 import org.jmonit.spi.PluginManager;
34
35
36
37
38
39
40 public class DefaultPluginManager
41 implements PluginManager
42 {
43
44
45
46
47 private static final String CONFIG = "jmonit.properties";
48
49
50
51
52 private static final String DEFAULT = "META-INF/jmonit/default.properties";
53
54
55
56
57 private static final String PLUGINS = "META-INF/jmonit/plugins.properties";
58
59
60 private static Log log = Log.getLog( DefaultPluginManager.class );
61
62 Map<Class, Factory> features = new ConcurrentHashMap<Class, Factory>();
63
64 Map<String, Collection<Class>> featuresForGroup =
65 new ConcurrentHashMap<String, Collection<Class>>();
66
67
68
69
70 public DefaultPluginManager()
71 {
72 super();
73 try
74 {
75 readConfiguration();
76 }
77 catch ( Exception e )
78 {
79 log.error( "Failed to load jMonit configuration " + e );
80 System.err
81 .println( "WARNING : Failed to load jMonit configuration : " + e.getMessage() );
82 }
83 }
84
85 private ClassLoader getClassLoader()
86 {
87 ClassLoader cl = Thread.currentThread().getContextClassLoader();
88 if ( cl == null )
89 {
90 cl = getClass().getClassLoader();
91 }
92 return cl;
93 }
94
95 protected void readFeatureGroupsConfiguration( Properties config )
96 {
97 for ( Map.Entry entry : config.entrySet() )
98 {
99 String key = (String) entry.getKey();
100 String value = (String) entry.getValue();
101 Collection<Class> features = featuresForGroup.get( key );
102 if ( features == null )
103 {
104 features = new LinkedList<Class>();
105 featuresForGroup.put( key, features );
106 }
107 String[] plugins = value.split( "," );
108 for ( String plugin : plugins )
109 {
110 Class feature = getFeature( plugin );
111 if ( feature == null )
112 {
113 log.error( "Unknown feature " + value + " requested for tag " + key );
114 continue;
115 }
116 features.add( feature );
117 log.info( value + " registered as a feature for monitor group " + key );
118 }
119 }
120 }
121
122 protected void readConfiguration()
123 throws Exception
124 {
125 Properties props = new Properties();
126 Enumeration<URL> modules = getClassLoader().getResources( PLUGINS );
127 while ( modules.hasMoreElements() )
128 {
129 URL url = (URL) modules.nextElement();
130 props.load( url.openStream() );
131 }
132 registerFeatures( props );
133
134 props.clear();
135
136 InputStream config = getClassLoader().getResourceAsStream( DEFAULT );
137 if ( config != null )
138 {
139 props.load( config );
140 }
141 config = getClassLoader().getResourceAsStream( CONFIG );
142 if ( config != null )
143 {
144 props.load( config );
145 }
146 readFeatureGroupsConfiguration( props );
147 }
148
149 protected void registerFeatures( Properties config )
150 throws Exception
151 {
152 Set keys = config.keySet();
153 for ( Iterator iterator = keys.iterator(); iterator.hasNext(); )
154 {
155 String key = (String) iterator.next();
156 try
157 {
158 Class feature = Class.forName( key );
159 Factory factory = null;
160 String property = config.getProperty( key );
161 int dash = property.indexOf( "#" );
162 String field = null;
163 if ( dash > 0 )
164 {
165 field = property.substring( dash + 1 ).trim();
166 property = property.substring( 0, dash );
167 }
168 Class factoryClass = Class.forName( property );
169 if ( field != null )
170 {
171 Field f = factoryClass.getField( field );
172 if ( !Factory.class.isAssignableFrom( f.getType() ) )
173 {
174 log.error( property + " in class " + factoryClass
175 + " is not a plugin Factory" );
176 log.error( key + " feature will be disabled" );
177 continue;
178 }
179 factory = (Factory) f.get( factoryClass );
180 }
181 else
182 {
183 if ( !Factory.class.isAssignableFrom( factoryClass ) )
184 {
185 log.error( factoryClass + " is not a plugin Factory" );
186 log.error( key + " feature will be disabled" );
187 continue;
188 }
189 factory = (Factory) factoryClass.newInstance();
190 }
191 registerPlugin( factory, feature );
192 }
193 catch ( Exception e )
194 {
195 log.error( "Fail to register " + key + " : " + e );
196 }
197 }
198 }
199
200
201
202
203
204
205
206 public void registerPlugin( Factory factory, Class role )
207 {
208 if ( log.isDebugEnabled() )
209 {
210 String name = factory.getClass().getName();
211 log.info( "register plugin factory " + name + " for feature " + role );
212 }
213 features.put( role, factory );
214 }
215
216
217
218
219
220
221 public <T> Factory<T> getFactory( Class<T> feature )
222 {
223 return features.get( feature );
224 }
225
226
227
228
229
230
231 public Collection<Class> getFeatures( String tag )
232 {
233 if ( tag == null )
234 {
235 return Collections.<Class> emptySet();
236 }
237 Collection<Class> features = featuresForGroup.get( tag );
238 return features != null ? features : Collections.<Class> emptySet();
239 }
240
241
242
243
244
245
246 public Class getFeature( String name )
247 {
248 if ( name != null )
249 {
250
251 try
252 {
253 return Class.forName( "org.jmonit.features." + name );
254 }
255 catch ( ClassNotFoundException e )
256 {
257
258 try
259 {
260 return Class.forName( name );
261 }
262 catch ( ClassNotFoundException ex )
263 {
264 log.error( "Unknown feature requested " + name );
265
266 }
267 }
268 }
269 return null;
270 }
271 }