KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > java > plugin > boot > DefaultApplicationInitializer


1 /*****************************************************************************
2  * Java Plug-in Framework (JPF)
3  * Copyright (C) 2004-2005 Dmitry Olshansky
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *****************************************************************************/

19 package org.java.plugin.boot;
20
21 import java.io.BufferedReader JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.LinkedList JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.java.plugin.ObjectFactory;
37 import org.java.plugin.Plugin;
38 import org.java.plugin.PluginManager;
39 import org.java.plugin.PluginManager.PluginLocation;
40 import org.java.plugin.registry.IntegrityCheckReport;
41 import org.java.plugin.registry.ManifestProcessingException;
42 import org.java.plugin.registry.PluginRegistry;
43 import org.java.plugin.registry.PluginRegistry.ManifestInfo;
44 import org.java.plugin.util.ExtendedProperties;
45 import org.java.plugin.util.IoUtil;
46 import org.java.plugin.util.ResourceManager;
47
48 /**
49  * Default implementation of the application initializer interface.
50  * <p>
51  * Supported configuration parameters:
52  * <dl>
53  * <dt>org.java.plugin.boot.applicationPlugin</dt>
54  * <dd>ID of plug-in to start. There is no default value for this parameter.
55  * In common scenario, this is the only parameter that you must provide.</dd>
56  * <dt>org.java.plugin.boot.integrityCheckMode</dt>
57  * <dd>Regulates how to check plug-ins integrity when running JPF. Possible
58  * values: <code>full</code>, <code>light</code>, <code>off</code>. The
59  * default value is <code>full</code>.</dd>
60  * <dt>org.java.plugin.boot.pluginsCollector</dt>
61  * <dd>Plug-ins location collector class, for details see
62  * {@link org.java.plugin.boot.PluginsCollector}. Default is
63  * {@link org.java.plugin.boot.DefaultPluginsCollector}.</dd>
64  * <dt>org.java.plugin.boot.pluginsWhiteList</dt>
65  * <dd>Location of the file with plug-in identifiers that should be only
66  * accepted by this application initializer. This is optional parameter.</dd>
67  * <dt>org.java.plugin.boot.pluginsBlackList</dt>
68  * <dd>Location of the file with plug-in identifiers that should not be
69  * accepted by this application initializer. This is optional parameter.</dd>
70  * </dl>
71  * Note that all given configuration parameters are passed to
72  * {@link org.java.plugin.ObjectFactory#newInstance(ExtendedProperties)}
73  * when running JPF (see bellow). This allows you to configure JPF precisely.
74  * </p>
75  * <p><i>Black and white lists of plug-ins</i></p>
76  * <p>
77  * In some situations you may want to temporary exclude some of your plug-ins
78  * from the application scope. This may be achieved with help of while and black
79  * lists - simple plain text files that contain lists of plug-in identifiers to
80  * be included/excluded from the application. Each identifies should be in
81  * separate line. You may provide unique plug-in ID also.
82  * </p>
83  * <p><i>What is application plug-in?</i></p>
84  * <p>
85  * When application starts, the
86  * {@link org.java.plugin.boot.Boot#main(String[])} method executed calling
87  * {@link #initApplication(BootErrorHandler, String[])} to get initialized
88  * instance of {@link org.java.plugin.boot.Application}
89  * (or {@link org.java.plugin.boot.ServiceApplication}) class. The method
90  * {@link #initApplication(BootErrorHandler, String[])} in this implementation
91  * scans plug-in repositories to collect all available plug-in files and folders
92  * (using special class that can be customized),
93  * instantiates JPF and publishes all discovered plug-ins. After that it asks
94  * {@link org.java.plugin.PluginManager} for an <b>Application Plug-in</b> with
95  * ID provided as configuration parameter. Returned class instance is expected
96  * to be of type {@link org.java.plugin.boot.ApplicationPlugin} and it's method
97  * {@link org.java.plugin.boot.ApplicationPlugin#initApplication(ExtendedProperties, String[])}
98  * called.
99  * </p>
100  * <p>
101  * To the mentioned <code>initApplication</code> method passed a subset of
102  * configuration properties whose names start with application plug-in ID
103  * followed with dot character <code>'.'</code> (see
104  * {@link org.java.plugin.util.ExtendedProperties#getSubset(String)} for
105  * details).
106  * </p>
107  * <p>
108  * As a result of the described procedure, the <code>Boot</code> get instance of
109  * {@link org.java.plugin.boot.Application} interface, so it can start
110  * application calling
111  * {@link org.java.plugin.boot.Application#startApplication()} method.
112  * </p>
113  *
114  * @version $Id: DefaultApplicationInitializer.java,v 1.11 2006/10/10 17:55:50 ddimon Exp $
115  */

116 public class DefaultApplicationInitializer implements ApplicationInitializer {
117     protected static final String JavaDoc PARAM_APPLICATION_PLUGIN =
118         "org.java.plugin.boot.applicationPlugin"; //$NON-NLS-1$
119
protected static final String JavaDoc PARAM_INTEGRITY_CHECK_MODE =
120         "org.java.plugin.boot.integrityCheckMode"; //$NON-NLS-1$
121
protected static final String JavaDoc PARAM_PLUGINS_COLLECTOR =
122         "org.java.plugin.boot.pluginsCollector"; //$NON-NLS-1$
123
protected static final String JavaDoc PARAM_PLUGINS_WHITE_LIST =
124         "org.java.plugin.boot.pluginsWhiteList"; //$NON-NLS-1$
125
protected static final String JavaDoc PARAM_PLUGINS_BLACK_LIST =
126         "org.java.plugin.boot.pluginsBlackList"; //$NON-NLS-1$
127

128     private Log log;
129     private ExtendedProperties config;
130     private String JavaDoc integrityCheckMode;
131     private PluginsCollector collector;
132     private Set JavaDoc whiteList;
133     private Set JavaDoc blackList;
134
135     /**
136      * Configures this instance and application environment. The sequence is:
137      * <ul>
138      * <li>Configure logging system. There is special code for supporting
139      * <code>Log4j</code> logging system only. All other systems support
140      * come from <code>commons-logging</code> package.</li>
141      * <li>Instantiate and configure {@link PluginsCollector} using
142      * configuration data.</li>
143      * </ul>
144      * @see org.java.plugin.boot.ApplicationInitializer#configure(
145      * org.java.plugin.util.ExtendedProperties)
146      */

147     public void configure(final ExtendedProperties configuration)
148             throws Exception JavaDoc {
149         // Initializing logging system.
150
String JavaDoc log4jConfigKey = "log4j.configuration"; //$NON-NLS-1$
151
if (System.getProperty(log4jConfigKey) == null) {
152             // Trying to find log4j configuration.
153
if (configuration.containsKey(log4jConfigKey)) {
154                 System.setProperty(log4jConfigKey,
155                         configuration.getProperty(log4jConfigKey));
156             } else {
157                 File JavaDoc log4jConfig = new File JavaDoc(
158                         configuration.getProperty("applicationRoot") //$NON-NLS-1$
159
+ File.separator + "log4j.properties"); //$NON-NLS-1$
160
if (!log4jConfig.isFile()) {
161                     log4jConfig = new File JavaDoc(
162                             configuration.getProperty("applicationRoot") //$NON-NLS-1$
163
+ File.separator + "log4j.xml"); //$NON-NLS-1$
164
}
165                 if (log4jConfig.isFile()) {
166                     try {
167                         System.setProperty(log4jConfigKey,
168                                 IoUtil.file2url(log4jConfig).toExternalForm());
169                     } catch (MalformedURLException JavaDoc e) {
170                         // ignore
171
}
172                 }
173             }
174         }
175         log = LogFactory.getLog(getClass());
176         log.info("logging system initialized"); //$NON-NLS-1$
177
log.info("application root is " //$NON-NLS-1$
178
+ configuration.getProperty("applicationRoot")); //$NON-NLS-1$
179
config = configuration;
180         integrityCheckMode =
181             configuration.getProperty(PARAM_INTEGRITY_CHECK_MODE, "full"); //$NON-NLS-1$
182
collector = getCollectorInstance(
183                 configuration.getProperty(PARAM_PLUGINS_COLLECTOR));
184         collector.configure(configuration);
185         log.debug("plug-ins collector is " + collector); //$NON-NLS-1$
186
try {
187             whiteList = loadList(
188                     configuration.getProperty(PARAM_PLUGINS_WHITE_LIST, null));
189         } catch (IOException JavaDoc ioe) {
190             log.warn("failed loading white list", ioe); //$NON-NLS-1$
191
}
192         if (whiteList != null) {
193             log.debug("white list loaded"); //$NON-NLS-1$
194
}
195         try {
196             blackList = loadList(
197                     configuration.getProperty(PARAM_PLUGINS_BLACK_LIST, null));
198         } catch (IOException JavaDoc ioe) {
199             log.warn("failed loading black list", ioe); //$NON-NLS-1$
200
}
201         if (blackList != null) {
202             log.debug("black list loaded"); //$NON-NLS-1$
203
}
204     }
205     
206     private Set JavaDoc loadList(final String JavaDoc location) throws IOException JavaDoc {
207         if (location == null) {
208             return null;
209         }
210         Set JavaDoc result = new HashSet JavaDoc();
211         BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(
212                 new FileInputStream JavaDoc(location), "UTF-8")); //$NON-NLS-1$
213
try {
214             String JavaDoc line;
215             while ((line = reader.readLine()) != null) {
216                 line = line.trim();
217                 if (line.length() > 0) {
218                     result.add(line);
219                 }
220             }
221         } finally {
222             reader.close();
223         }
224         log.debug("read " + result.size() //$NON-NLS-1$
225
+ " list items from " + location); //$NON-NLS-1$
226
return result;
227     }
228     
229     private PluginsCollector getCollectorInstance(
230             final String JavaDoc className) {
231         if (className != null) {
232             try {
233                 return (PluginsCollector) Class.forName(className)
234                     .newInstance();
235             } catch (InstantiationException JavaDoc ie) {
236                 log.warn("failed instantiating plug-ins collector " //$NON-NLS-1$
237
+ className, ie);
238             } catch (IllegalAccessException JavaDoc iae) {
239                 log.warn("failed instantiating plug-ins collector " //$NON-NLS-1$
240
+ className, iae);
241             } catch (ClassNotFoundException JavaDoc cnfe) {
242                 log.warn("failed instantiating plug-ins collector " //$NON-NLS-1$
243
+ className, cnfe);
244             }
245         }
246         return new DefaultPluginsCollector();
247     }
248     
249     /**
250      * Initializes application. The sequence is:
251      * <ul>
252      * <li>Collect plug-ins locations using configured
253      * {@link PluginsCollector}.</li>
254      * <li>Get {@link PluginManager} instance from {@link ObjectFactory}
255      * using code
256      * <code>ObjectFactory.newInstance(config).createManager()</code>.</li>
257      * <li>Publish collected plug-ins using
258      * {@link PluginManager#publishPlugins(org.java.plugin.PluginManager.PluginLocation[])}.</li>
259      * <li>Check integrity if that's configured.</li>
260      * <li>Get application plug-in and call it
261      * <code>JpfApplication initApplication(Properties)</code> method.</li>
262      * <li>Return received instance of {@link Application} interface.</li>
263      * </ul>
264      *
265      * @see org.java.plugin.boot.ApplicationInitializer#initApplication(
266      * BootErrorHandler, String[])
267      */

268     public Application initApplication(final BootErrorHandler errorHandler,
269             final String JavaDoc[] args) throws Exception JavaDoc {
270         // Prepare parameters to start plug-in manager.
271
log.debug("collecting plug-in locations"); //$NON-NLS-1$
272
Collection JavaDoc pluginLocations = collector.collectPluginLocations();
273         log.debug("collected " + pluginLocations.size() //$NON-NLS-1$
274
+ " plug-in locations, instantiating plug-in manager"); //$NON-NLS-1$
275
// Create instance of plug-in manager.
276
PluginManager pluginManager =
277             ObjectFactory.newInstance(config).createManager();
278         pluginLocations = filterPluginLocations(pluginManager.getRegistry(),
279                 pluginLocations);
280         log.debug(pluginLocations.size() + " plug-in locations remain after " //$NON-NLS-1$
281
+ "applying filters, publishing plug-ins"); //$NON-NLS-1$
282
// Publish discovered plug-in manifests and corresponding plug-in folders.
283
pluginManager.publishPlugins(
284                 (PluginLocation[]) pluginLocations.toArray(
285                         new PluginLocation[pluginLocations.size()]));
286         if (!"off".equalsIgnoreCase(integrityCheckMode)) { //$NON-NLS-1$
287
// Check plug-in's integrity.
288
log.debug("checking plug-ins set integrity"); //$NON-NLS-1$
289
IntegrityCheckReport integrityCheckReport =
290                 pluginManager.getRegistry().checkIntegrity(
291                         "light".equalsIgnoreCase(integrityCheckMode) ? null //$NON-NLS-1$
292
: pluginManager.getPathResolver());
293             log.info("integrity check done: errors - " //$NON-NLS-1$
294
+ integrityCheckReport.countErrors() + ", warnings - " //$NON-NLS-1$
295
+ integrityCheckReport.countWarnings());
296             if (integrityCheckReport.countErrors() != 0) {
297                 // Something wrong in plug-ins set.
298
log.info(integrityCheckReport2str(integrityCheckReport));
299                 if (!errorHandler.handleError(ResourceManager.getMessage(
300                         Boot.PACKAGE_NAME, "integrityCheckFailed"), //$NON-NLS-1$
301
integrityCheckReport)) {
302                     return null;
303                 }
304             } else if (log.isDebugEnabled()
305                     && ((integrityCheckReport.countErrors() > 0)
306                     || (integrityCheckReport.countWarnings() > 0))) {
307                 log.debug(integrityCheckReport2str(integrityCheckReport));
308             }
309         }
310         // application plug-in ID
311
String JavaDoc appPluginId = config.getProperty(PARAM_APPLICATION_PLUGIN);
312         log.info("application plug-in is " + appPluginId); //$NON-NLS-1$
313
// get the start-up application plug-in
314
Plugin appPlugin = pluginManager.getPlugin(appPluginId);
315         log.debug("got application plug-in " + appPlugin //$NON-NLS-1$
316
+ ", initializing application"); //$NON-NLS-1$
317
if (!(appPlugin instanceof ApplicationPlugin)) {
318             log.error("application plug-in class " //$NON-NLS-1$
319
+ appPlugin.getClass().getName()
320                     + " doesn't assignable with " //$NON-NLS-1$
321
+ ApplicationPlugin.class.getName());
322             throw new ClassCastException JavaDoc(appPlugin.getClass().getName());
323         }
324         return ((ApplicationPlugin) appPlugin).initApplication(
325                 config.getSubset(appPluginId + "."), args); //$NON-NLS-1$
326
}
327     
328     protected String JavaDoc integrityCheckReport2str(final IntegrityCheckReport report) {
329         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
330         buf.append("integrity check report:\r\n"); //$NON-NLS-1$
331
buf.append("-------------- REPORT BEGIN -----------------\r\n"); //$NON-NLS-1$
332
for (Iterator JavaDoc it = report.getItems().iterator(); it.hasNext();) {
333             IntegrityCheckReport.ReportItem item =
334                 (IntegrityCheckReport.ReportItem) it.next();
335             buf.append("\tseverity=").append(item.getSeverity()) //$NON-NLS-1$
336
.append("; code=").append(item.getCode()) //$NON-NLS-1$
337
.append("; message=").append(item.getMessage()) //$NON-NLS-1$
338
.append("; source=").append(item.getSource()) //$NON-NLS-1$
339
.append("\r\n"); //$NON-NLS-1$
340
}
341         buf.append("-------------- REPORT END -----------------"); //$NON-NLS-1$
342
return buf.toString();
343     }
344
345     /**
346      * This method may remove unwanted plug-in locations from the given list.
347      * Standard implementation applies black/white lists logic.
348      * @param registry plug-in registry to process manifests
349      * @param pluginLocations collected plug-in locations to be filtered
350      * @throws ManifestProcessingException
351      */

352     protected Collection JavaDoc filterPluginLocations(final PluginRegistry registry,
353             final Collection JavaDoc pluginLocations)
354             throws ManifestProcessingException {
355         if ((whiteList == null) && (blackList == null)) {
356             return pluginLocations;
357         }
358         List JavaDoc result = new LinkedList JavaDoc();
359         for (Iterator JavaDoc ir = pluginLocations.iterator(); ir.hasNext();) {
360             PluginLocation pluginLocation = (PluginLocation) ir.next();
361             ManifestInfo manifestInfo = registry.readManifestInfo(
362                     pluginLocation.getManifestLocation());
363             if (whiteList != null) {
364                 if (isPluginInList(registry, manifestInfo, whiteList)) {
365                     result.add(pluginLocation);
366                     continue;
367                 }
368             }
369             if ((blackList != null)
370                     && isPluginInList(registry, manifestInfo, blackList)) {
371                 continue;
372             }
373             result.add(pluginLocation);
374         }
375         return result;
376     }
377     
378     private boolean isPluginInList(final PluginRegistry registry,
379             final ManifestInfo manifestInfo, final Set JavaDoc list) {
380         if (list.contains(manifestInfo.getId())) {
381             return true;
382         }
383         return list.contains(registry.makeUniqueId(manifestInfo.getId(),
384                 manifestInfo.getVersion()));
385     }
386 }
387
Popular Tags