001: /*****************************************************************************
002: * Java Plug-in Framework (JPF)
003: * Copyright (C) 2004-2007 Dmitry Olshansky
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *****************************************************************************/package org.java.plugin.standard;
019:
020: import java.security.AccessController;
021: import java.security.PrivilegedAction;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.java.plugin.Plugin;
026: import org.java.plugin.PluginLifecycleException;
027: import org.java.plugin.PluginManager;
028: import org.java.plugin.registry.PluginDescriptor;
029: import org.java.plugin.util.ExtendedProperties;
030:
031: /**
032: * Standard implementation of plug-in life cycle handler.
033: * <p>
034: * <b>Configuration parameters</b>
035: * </p>
036: * <p>
037: * This life cycle handler implementation supports following configuration
038: * parameters:
039: * <dl>
040: * <dt>probeParentLoaderLast</dt>
041: * <dd>If <code>true</code>, plug-in classloader will try loading classes from
042: * system (boot) classpath <b>after</b> trying to load them from plug-in
043: * classpath. Otherwise system classpath will be used <b>first</b>. Default
044: * value is <code>false</code> that corresponds to standard delegation model
045: * for classloaders hierarchy that corresponds to JLS.</dd>
046: * <dt>stickySynchronizing</dt>
047: * <dd>Allows advanced configuring of classloaders synchronization in
048: * multy-threaded environment. If <code>true</code> then class loading will
049: * be synchronized with initial plug-in classloader instance. Otherwise
050: * <code>this</code> instance will be used as synchronizing monitor. Default
051: * value is <code>false</code>.</dd>
052: * <dt>localClassLoadingOptimization</dt>
053: * <dd>If <code>true</code> then plug-in classloader will collect local
054: * packages statistics to predict class location. This allow to optimize
055: * class look-up procedure for classes that belong to the requested plug-in.
056: * Default value is <code>true</code>.</dd>
057: * <dt>foreignClassLoadingOptimization</dt>
058: * <dd>If <code>true</code> then plug-in classloader will collect statistics
059: * for "foreign" classes - those which belong to depending plug-ins. This
060: * allow to optimize class look-up procedure when enumerating depending
061: * plug-ins. Default value is <code>true</code>.</dd>
062: * </dl>
063: * </p>
064: * @version $Id: StandardPluginLifecycleHandler.java,v 1.5 2007/04/07 12:39:50 ddimon Exp $
065: */
066: public class StandardPluginLifecycleHandler extends
067: PluginLifecycleHandler {
068: private final Log log = LogFactory.getLog(getClass());
069: private boolean probeParentLoaderLast;
070: private boolean stickySynchronizing;
071: private boolean localClassLoadingOptimization;
072: private boolean foreignClassLoadingOptimization;
073:
074: /**
075: * Creates standard implementation of plug-in class loader.
076: * @see org.java.plugin.standard.PluginLifecycleHandler#createPluginClassLoader(
077: * org.java.plugin.registry.PluginDescriptor)
078: */
079: @Override
080: protected org.java.plugin.PluginClassLoader createPluginClassLoader(
081: final PluginDescriptor descr) {
082: /*StandardPluginClassLoader result = new StandardPluginClassLoader(
083: getPluginManager(), descr, getClass().getClassLoader());*/
084: StandardPluginClassLoader result = AccessController
085: .doPrivileged(new PrivilegedAction<StandardPluginClassLoader>() {
086: public StandardPluginClassLoader run() {
087: return new StandardPluginClassLoader(
088: getPluginManager(), descr,
089: StandardPluginLifecycleHandler.this
090: .getClass().getClassLoader());
091: }
092: });
093: result.setProbeParentLoaderLast(probeParentLoaderLast);
094: result.setStickySynchronizing(stickySynchronizing);
095: result
096: .setLocalClassLoadingOptimization(localClassLoadingOptimization);
097: result
098: .setForeignClassLoadingOptimization(foreignClassLoadingOptimization);
099: return result;
100: }
101:
102: /**
103: * Creates instance of plug-in class calling it's default (no-arguments)
104: * constructor. Class look-up is done with
105: * {@link PluginManager#getPluginClassLoader(PluginDescriptor) plug-in's class loader}.
106: * @see org.java.plugin.standard.PluginLifecycleHandler#createPluginInstance(
107: * org.java.plugin.registry.PluginDescriptor)
108: */
109: @Override
110: protected Plugin createPluginInstance(final PluginDescriptor descr)
111: throws PluginLifecycleException {
112: String className = descr.getPluginClassName();
113: Class<?> pluginClass;
114: try {
115: pluginClass = getPluginManager()
116: .getPluginClassLoader(descr).loadClass(className);
117: } catch (ClassNotFoundException cnfe) {
118: throw new PluginLifecycleException(
119: StandardObjectFactory.PACKAGE_NAME,
120: "pluginClassNotFound", className, cnfe); //$NON-NLS-1$
121: }
122: try {
123: return (Plugin) pluginClass.newInstance();
124: } catch (InstantiationException ie) {
125: throw new PluginLifecycleException(
126: StandardObjectFactory.PACKAGE_NAME,
127: "pluginClassInstantiationFailed", descr.getId(), ie); //$NON-NLS-1$
128: } catch (IllegalAccessException iae) {
129: throw new PluginLifecycleException(
130: StandardObjectFactory.PACKAGE_NAME,
131: "pluginClassInstantiationFailed", descr.getId(), iae); //$NON-NLS-1$
132: }
133: }
134:
135: /**
136: * This method does nothing in this implementation.
137: * @see org.java.plugin.standard.PluginLifecycleHandler#beforePluginStart(
138: * org.java.plugin.Plugin)
139: */
140: @Override
141: protected void beforePluginStart(final Plugin plugin) {
142: // no-op
143: }
144:
145: /**
146: * This method does nothing in this implementation.
147: * @see org.java.plugin.standard.PluginLifecycleHandler#afterPluginStop(
148: * org.java.plugin.Plugin)
149: */
150: @Override
151: protected void afterPluginStop(final Plugin plugin) {
152: // no-op
153: }
154:
155: /**
156: * This method does nothing in this implementation.
157: * @see org.java.plugin.standard.PluginLifecycleHandler#dispose()
158: */
159: @Override
160: protected void dispose() {
161: // no-op
162: }
163:
164: /**
165: * @see org.java.plugin.standard.PluginLifecycleHandler#configure(
166: * ExtendedProperties)
167: */
168: @Override
169: public void configure(ExtendedProperties config) {
170: probeParentLoaderLast = "true".equalsIgnoreCase( //$NON-NLS-1$
171: config.getProperty("probeParentLoaderLast", "false")); //$NON-NLS-1$ //$NON-NLS-2$
172: log.debug("probeParentLoaderLast parameter value is " //$NON-NLS-1$
173: + probeParentLoaderLast);
174: stickySynchronizing = "true".equalsIgnoreCase( //$NON-NLS-1$
175: config.getProperty("stickySynchronizing", "false")); //$NON-NLS-1$ //$NON-NLS-2$
176: log.debug("stickySynchronizing parameter value is " //$NON-NLS-1$
177: + stickySynchronizing);
178: localClassLoadingOptimization = !"false".equalsIgnoreCase( //$NON-NLS-1$
179: config.getProperty("localClassLoadingOptimization", //$NON-NLS-1$
180: "true")); //$NON-NLS-1$
181: log.debug("localLoadingClassOptimization parameter value is " //$NON-NLS-1$
182: + localClassLoadingOptimization);
183: foreignClassLoadingOptimization = !"false".equalsIgnoreCase( //$NON-NLS-1$
184: config.getProperty("foreignClassLoadingOptimization", //$NON-NLS-1$
185: "true")); //$NON-NLS-1$
186: log.debug("foreignClassLoadingOptimization parameter value is " //$NON-NLS-1$
187: + foreignClassLoadingOptimization);
188: }
189: }
|