Source Code Cross Referenced for StandardPluginManager.java in  » Development » Java-Plugin-Framework » org » java » plugin » standard » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » Java Plugin Framework » org.java.plugin.standard 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.net.URL;
021:        import java.util.ArrayList;
022:        import java.util.Collections;
023:        import java.util.HashMap;
024:        import java.util.HashSet;
025:        import java.util.LinkedList;
026:        import java.util.List;
027:        import java.util.Map;
028:        import java.util.Set;
029:
030:        import org.apache.commons.logging.Log;
031:        import org.apache.commons.logging.LogFactory;
032:        import org.java.plugin.JpfException;
033:        import org.java.plugin.PathResolver;
034:        import org.java.plugin.Plugin;
035:        import org.java.plugin.PluginClassLoader;
036:        import org.java.plugin.PluginLifecycleException;
037:        import org.java.plugin.PluginManager;
038:        import org.java.plugin.registry.Identity;
039:        import org.java.plugin.registry.PluginDescriptor;
040:        import org.java.plugin.registry.PluginFragment;
041:        import org.java.plugin.registry.PluginPrerequisite;
042:        import org.java.plugin.registry.PluginRegistry;
043:        import org.java.plugin.registry.PluginRegistry.RegistryChangeData;
044:        import org.java.plugin.registry.PluginRegistry.RegistryChangeListener;
045:
046:        /**
047:         * Standard implementation of plug-in manager.
048:         * 
049:         * @version $Id: StandardPluginManager.java,v 1.8 2007/04/07 12:41:01 ddimon Exp $
050:         */
051:        public final class StandardPluginManager extends PluginManager {
052:            Log log = LogFactory.getLog(getClass());
053:            private final PathResolver pathResolver;
054:            private final PluginRegistry registry;
055:            private final PluginLifecycleHandler lifecycleHandler;
056:            private final Map<String, Plugin> activePlugins = new HashMap<String, Plugin>();
057:            private final Set<String> activatingPlugins = new HashSet<String>();
058:            private final Set<String> badPlugins = new HashSet<String>();
059:            private final List<String> activationLog = new LinkedList<String>();
060:            private final Map<String, PluginClassLoader> classLoaders = new HashMap<String, PluginClassLoader>();
061:            private final Set<String> disabledPlugins = new HashSet<String>();
062:            private final List<EventListener> listeners = Collections
063:                    .synchronizedList(new LinkedList<EventListener>());
064:            private RegistryChangeListener registryChangeListener;
065:            private Map<String, URL> notRegisteredPluginLocations = new HashMap<String, URL>();
066:
067:            /**
068:             * Creates instance of plug-in manager for given registry, path resolver and
069:             * life cycle handler.
070:             * 
071:             * @param aRegistry
072:             *            some implementation of plug-in registry interface
073:             * @param aPathResolver
074:             *            some implementation of path resolver interface
075:             * @param aLifecycleHandler
076:             *            an implementation of plug-in life cycle handler
077:             * 
078:             * @see StandardObjectFactory
079:             */
080:            protected StandardPluginManager(final PluginRegistry aRegistry,
081:                    final PathResolver aPathResolver,
082:                    final PluginLifecycleHandler aLifecycleHandler) {
083:                registry = aRegistry;
084:                pathResolver = aPathResolver;
085:                lifecycleHandler = aLifecycleHandler;
086:                lifecycleHandler.init(this );
087:                registryChangeListener = new RegistryChangeListener() {
088:                    public void registryChanged(final RegistryChangeData data) {
089:                        registryChangeHandler(data);
090:                    }
091:                };
092:                registry.registerListener(registryChangeListener);
093:            }
094:
095:            /**
096:             * @see org.java.plugin.PluginManager#getRegistry()
097:             */
098:            @Override
099:            public PluginRegistry getRegistry() {
100:                return registry;
101:            }
102:
103:            /**
104:             * @see org.java.plugin.PluginManager#getPathResolver()
105:             */
106:            @Override
107:            public PathResolver getPathResolver() {
108:                return pathResolver;
109:            }
110:
111:            /**
112:             * Method to handle plug-in registry change events.
113:             * 
114:             * @param data
115:             *            registry change data holder
116:             */
117:            synchronized void registryChangeHandler(
118:                    final RegistryChangeData data) {
119:                badPlugins.clear();
120:                for (String id : data.removedPlugins()) {
121:                    deactivatePlugin(id);
122:                    pathResolver.unregisterContext(id);
123:                }
124:                URL location;
125:                for (PluginDescriptor idt : registry.getPluginDescriptors()) {
126:                    location = notRegisteredPluginLocations.remove(idt
127:                            .getLocation().toExternalForm());
128:                    if (location != null) {
129:                        pathResolver.registerContext(idt, location);
130:                    }
131:                }
132:                for (PluginFragment idt : registry.getPluginFragments()) {
133:                    location = notRegisteredPluginLocations.remove(idt
134:                            .getLocation().toExternalForm());
135:                    if (location != null) {
136:                        pathResolver.registerContext(idt, location);
137:                    }
138:                }
139:                for (String id : data.modifiedPlugins()) {
140:                    if (activePlugins.containsKey(id)) {
141:                        deactivatePlugin(id);
142:                        try {
143:                            activatePlugin(id);
144:                        } catch (Exception e) {
145:                            log
146:                                    .error(
147:                                            "failed activating modified plug-in " + id, e); //$NON-NLS-1$
148:                        }
149:                    } else {
150:                        PluginClassLoader clsLoader = classLoaders.get(id);
151:                        if (clsLoader != null) {
152:                            notifyClassLoader(clsLoader);
153:                        }
154:                    }
155:                }
156:            }
157:
158:            /**
159:             * Registers plug-ins and their locations with this plug-in manager. You
160:             * should use this method to register new plug-ins to make them available
161:             * for activation with this manager instance (compare this to
162:             * {@link PluginRegistry#register(URL[])} method that just makes plug-in's
163:             * meta-data available for reading and doesn't "know" where are things
164:             * actually located).
165:             * 
166:             * @param locations
167:             *            plug-in locations data
168:             * @return map where keys are manifest URL's and values are registered
169:             *         plug-ins or plug-in fragments, URL's for unprocessed manifests
170:             *         are not included
171:             * @throws JpfException
172:             *             if given plug-ins can't be registered or published (optional
173:             *             behavior)
174:             */
175:            @Override
176:            public Map<String, Identity> publishPlugins(
177:                    final PluginLocation[] locations) throws JpfException {
178:                LinkedList<URL> manifests = new LinkedList<URL>();
179:                for (PluginLocation location : locations) {
180:                    URL manifest = location.getManifestLocation();
181:                    manifests.add(manifest);
182:                    notRegisteredPluginLocations.put(manifest.toExternalForm(),
183:                            location.getContextLocation());
184:                }
185:                return registry.register(manifests.toArray(new URL[manifests
186:                        .size()]));
187:            }
188:
189:            /**
190:             * Looks for plug-in with given ID and activates it if it is not activated
191:             * yet. Note that this method will never return <code>null</code>.
192:             * 
193:             * @param id
194:             *            plug-in ID
195:             * @return found plug-in
196:             * @throws PluginLifecycleException
197:             *             if plug-in can't be found or activated
198:             */
199:            @Override
200:            public Plugin getPlugin(final String id)
201:                    throws PluginLifecycleException {
202:                Plugin result = activePlugins.get(id);
203:                if (result != null) {
204:                    return result;
205:                }
206:                if (badPlugins.contains(id)) {
207:                    throw new IllegalArgumentException(
208:                            "plug-in " + id //$NON-NLS-1$
209:                                    + " disabled internally as it wasn't properly initialized"); //$NON-NLS-1$
210:                }
211:                if (disabledPlugins.contains(id)) {
212:                    throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
213:                            + " disabled externally"); //$NON-NLS-1$
214:                }
215:                PluginDescriptor descr = registry.getPluginDescriptor(id);
216:                if (descr == null) {
217:                    throw new IllegalArgumentException(
218:                            "unknown plug-in ID - " + id); //$NON-NLS-1$
219:                }
220:                return activatePlugin(descr);
221:            }
222:
223:            /**
224:             * Activates plug-in with given ID if it is not activated yet.
225:             * 
226:             * @param id
227:             *            plug-in ID
228:             * @throws PluginLifecycleException
229:             *             if plug-in can't be found or activated
230:             */
231:            @Override
232:            public void activatePlugin(final String id)
233:                    throws PluginLifecycleException {
234:                if (activePlugins.containsKey(id)) {
235:                    return;
236:                }
237:                if (badPlugins.contains(id)) {
238:                    throw new IllegalArgumentException(
239:                            "plug-in " + id //$NON-NLS-1$
240:                                    + " disabled internally as it wasn't properly initialized"); //$NON-NLS-1$
241:                }
242:                if (disabledPlugins.contains(id)) {
243:                    throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
244:                            + " disabled externally"); //$NON-NLS-1$
245:                }
246:                PluginDescriptor descr = registry.getPluginDescriptor(id);
247:                if (descr == null) {
248:                    throw new IllegalArgumentException(
249:                            "unknown plug-in ID - " + id); //$NON-NLS-1$
250:                }
251:                activatePlugin(descr);
252:            }
253:
254:            /**
255:             * Looks for plug-in, given object belongs to.
256:             * 
257:             * @param obj
258:             *            any object that maybe belongs to some plug-in
259:             * @return plug-in or <code>null</code> if given object doesn't belong to
260:             *         any plug-in (possibly it is part of "host" application) and thus
261:             *         doesn't managed by the Framework directly or indirectly
262:             */
263:            @Override
264:            public Plugin getPluginFor(final Object obj) {
265:                if (obj == null) {
266:                    return null;
267:                }
268:                ClassLoader clsLoader;
269:                if (obj instanceof  Class) {
270:                    clsLoader = ((Class) obj).getClassLoader();
271:                } else if (obj instanceof  ClassLoader) {
272:                    clsLoader = (ClassLoader) obj;
273:                } else {
274:                    clsLoader = obj.getClass().getClassLoader();
275:                }
276:                if (!(clsLoader instanceof  PluginClassLoader)) {
277:                    return null;
278:                }
279:                PluginDescriptor descr = ((PluginClassLoader) clsLoader)
280:                        .getPluginDescriptor();
281:                Plugin result = activePlugins.get(descr.getId());
282:                if (result != null) {
283:                    return result;
284:                }
285:                throw new IllegalStateException("can't get plug-in " + descr); //$NON-NLS-1$
286:            }
287:
288:            /**
289:             * @param descr
290:             *            plug-in descriptor
291:             * @return <code>true</code> if plug-in with given descriptor is activated
292:             */
293:            @Override
294:            public boolean isPluginActivated(final PluginDescriptor descr) {
295:                return activePlugins.containsKey(descr.getId());
296:            }
297:
298:            /**
299:             * @param descr
300:             *            plug-in descriptor
301:             * @return <code>true</code> if plug-in disabled as it's activation fails
302:             */
303:            @Override
304:            public boolean isBadPlugin(final PluginDescriptor descr) {
305:                return badPlugins.contains(descr.getId());
306:            }
307:
308:            /**
309:             * @param descr
310:             *            plug-in descriptor
311:             * @return <code>true</code> if plug-in is currently activating
312:             */
313:            @Override
314:            public boolean isPluginActivating(final PluginDescriptor descr) {
315:                return activatingPlugins.contains(descr.getId());
316:            }
317:
318:            /**
319:             * Returns instance of plug-in's class loader and not tries to activate
320:             * plug-in. Use this method if you need to get access to plug-in resources
321:             * and don't want to cause plug-in activation.
322:             * 
323:             * @param descr
324:             *            plug-in descriptor
325:             * @return class loader instance for plug-in with given descriptor
326:             */
327:            @Override
328:            public PluginClassLoader getPluginClassLoader(
329:                    final PluginDescriptor descr) {
330:                if (badPlugins.contains(descr.getId())) {
331:                    throw new IllegalArgumentException(
332:                            "plug-in " + descr.getId() //$NON-NLS-1$
333:                                    + " disabled internally as it wasn't properly initialized"); //$NON-NLS-1$
334:                }
335:                if (disabledPlugins.contains(descr.getId())) {
336:                    throw new IllegalArgumentException(
337:                            "plug-in " + descr.getId() //$NON-NLS-1$
338:                                    + " disabled externally"); //$NON-NLS-1$
339:                }
340:                PluginClassLoader result = classLoaders.get(descr.getId());
341:                if (result != null) {
342:                    return result;
343:                }
344:                synchronized (this ) {
345:                    result = classLoaders.get(descr.getId());
346:                    if (result != null) {
347:                        return result;
348:                    }
349:                    result = lifecycleHandler.createPluginClassLoader(descr);
350:                    classLoaders.put(descr.getId(), result);
351:                }
352:                return result;
353:            }
354:
355:            /**
356:             * Shuts down the framework. <br>
357:             * Calling this method will deactivate all active plug-ins in order, reverse
358:             * to the order they was activated. It also releases all resources allocated
359:             * by this manager (class loaders, plug-in descriptors etc.). All disabled
360:             * plug-ins will be marked as "enabled", all registered event listeners will
361:             * be unregistered.
362:             */
363:            @Override
364:            public synchronized void shutdown() {
365:                log.debug("shutting down..."); //$NON-NLS-1$
366:                dump();
367:                registry.unregisterListener(registryChangeListener);
368:                final List<String> reversedLog = new ArrayList<String>(
369:                        activationLog);
370:                Collections.reverse(reversedLog);
371:                for (String id : reversedLog) {
372:                    PluginDescriptor descr = registry.getPluginDescriptor(id);
373:                    if (descr == null) {
374:                        log.warn("can't find descriptor for plug-in " + id //$NON-NLS-1$
375:                                + " to deactivate plug-in", new Exception( //$NON-NLS-1$
376:                                "fake exception to view stack trace")); //$NON-NLS-1$
377:                        continue;
378:                    }
379:                    deactivatePlugin(descr);
380:                }
381:                dump();
382:                classLoaders.clear();
383:                disabledPlugins.clear();
384:                listeners.clear();
385:                lifecycleHandler.dispose();
386:                log.info("shutdown done"); //$NON-NLS-1$
387:            }
388:
389:            private synchronized Plugin activatePlugin(
390:                    final PluginDescriptor descr)
391:                    throws PluginLifecycleException {
392:                Plugin result = activePlugins.get(descr.getId());
393:                if (result != null) {
394:                    return result;
395:                }
396:                if (badPlugins.contains(descr.getId())) {
397:                    throw new IllegalArgumentException(
398:                            "plug-in " + descr.getId() //$NON-NLS-1$
399:                                    + " disabled as it wasn't properly initialized"); //$NON-NLS-1$
400:                }
401:                if (activatingPlugins.contains(descr.getId())) {
402:                    throw new PluginLifecycleException(
403:                            StandardObjectFactory.PACKAGE_NAME,
404:                            "pluginActivating", descr.getId()); //$NON-NLS-1$
405:                }
406:                activatingPlugins.add(descr.getId());
407:                try {
408:                    try {
409:                        checkPrerequisites(descr);
410:                        String pluginClassName = descr.getPluginClassName();
411:                        if ((pluginClassName == null)
412:                                || (pluginClassName.trim().length() == 0)) {
413:                            result = new EmptyPlugin();
414:                        } else {
415:                            result = lifecycleHandler
416:                                    .createPluginInstance(descr);
417:                        }
418:                        initPlugin(result, descr);
419:                        lifecycleHandler.beforePluginStart(result);
420:                        startPlugin(result);
421:                    } catch (PluginLifecycleException ple) {
422:                        badPlugins.add(descr.getId());
423:                        classLoaders.remove(descr.getId());
424:                        throw ple;
425:                    } catch (Exception e) {
426:                        badPlugins.add(descr.getId());
427:                        classLoaders.remove(descr.getId());
428:                        throw new PluginLifecycleException(
429:                                StandardObjectFactory.PACKAGE_NAME,
430:                                "pluginStartFailed", descr.getUniqueId(), e); //$NON-NLS-1$
431:                    }
432:                    activePlugins.put(descr.getId(), result);
433:                    activationLog.add(descr.getId());
434:                    log.info("plug-in started - " + descr.getUniqueId() //$NON-NLS-1$
435:                            + " (active/total: " + activePlugins.size() //$NON-NLS-1$
436:                            + " of " //$NON-NLS-1$
437:                            + registry.getPluginDescriptors().size() + ")"); //$NON-NLS-1$
438:                    fireEvent(result, true);
439:                    return result;
440:                } finally {
441:                    activatingPlugins.remove(descr.getId());
442:                }
443:            }
444:
445:            private void checkPrerequisites(final PluginDescriptor descr)
446:                    throws PluginLifecycleException {
447:                for (PluginPrerequisite pre : descr.getPrerequisites()) {
448:                    if (activatingPlugins.contains(pre.getPluginId())) {
449:                        log
450:                                .warn(
451:                                        "dependencies loop detected during " //$NON-NLS-1$
452:                                                + "activation of plug-in " + descr, new Exception( //$NON-NLS-1$
453:                                                "fake exception to view stack trace")); //$NON-NLS-1$
454:                        continue;
455:                    }
456:                    if (badPlugins.contains(pre.getPluginId())) {
457:                        if (pre.isOptional()) {
458:                            continue;
459:                        }
460:                        throw new PluginLifecycleException(
461:                                StandardObjectFactory.PACKAGE_NAME,
462:                                "pluginPrerequisiteBad", //$NON-NLS-1$
463:                                new Object[] { descr.getId(), pre.getPluginId() });
464:                    }
465:                    if (disabledPlugins.contains(pre.getPluginId())) {
466:                        if (pre.isOptional()) {
467:                            continue;
468:                        }
469:                        throw new PluginLifecycleException(
470:                                StandardObjectFactory.PACKAGE_NAME,
471:                                "pluginPrerequisiteDisabled", //$NON-NLS-1$
472:                                new Object[] { descr.getId(), pre.getPluginId() });
473:                    }
474:                    if (!pre.matches()) {
475:                        if (pre.isOptional()) {
476:                            continue;
477:                        }
478:                        throw new PluginLifecycleException(
479:                                StandardObjectFactory.PACKAGE_NAME,
480:                                "pluginPrerequisiteNotMatches", //$NON-NLS-1$
481:                                new Object[] { descr.getId(), pre.getPluginId() });
482:                    }
483:                    try {
484:                        activatePlugin(registry.getPluginDescriptor(pre
485:                                .getPluginId()));
486:                    } catch (PluginLifecycleException ple) {
487:                        if (pre.isOptional()) {
488:                            log.warn("failed activating optional plug-in from" //$NON-NLS-1$
489:                                    + " prerequisite " + pre, ple); //$NON-NLS-1$
490:                            continue;
491:                        }
492:                        throw ple;
493:                    }
494:                }
495:            }
496:
497:            /**
498:             * Deactivates plug-in with given ID if it has been successfully activated
499:             * before. Note that this method will effectively deactivate all plug-ins
500:             * that depend on the given plug-in.
501:             * 
502:             * @param id
503:             *            plug-in ID
504:             */
505:            @Override
506:            public void deactivatePlugin(final String id) {
507:                if (!activePlugins.containsKey(id)) {
508:                    return;
509:                }
510:                PluginDescriptor descr = registry.getPluginDescriptor(id);
511:                if (descr == null) {
512:                    throw new IllegalArgumentException(
513:                            "unknown plug-in ID - " + id); //$NON-NLS-1$
514:                }
515:                // Collect depending plug-ins
516:                final Map<String, PluginDescriptor> dependingPluginsMap = new HashMap<String, PluginDescriptor>();
517:                for (PluginDescriptor dependingPlugin : registry
518:                        .getDependingPlugins(descr)) {
519:                    dependingPluginsMap.put(dependingPlugin.getId(),
520:                            dependingPlugin);
521:                }
522:                // Prepare list of plug-ins to be deactivated in correct order
523:                final List<PluginDescriptor> tobeDeactivated = new LinkedList<PluginDescriptor>();
524:                final List<String> reversedLog = new ArrayList<String>(
525:                        activationLog);
526:                Collections.reverse(reversedLog);
527:                for (String pluginId : reversedLog) {
528:                    if (pluginId.equals(descr.getId())) {
529:                        tobeDeactivated.add(descr);
530:                    } else if (dependingPluginsMap.containsKey(pluginId)) {
531:                        tobeDeactivated.add(dependingPluginsMap.get(pluginId));
532:                    }
533:                }
534:                // Deactivate plug-ins
535:                for (PluginDescriptor descriptor : tobeDeactivated) {
536:                    deactivatePlugin(descriptor);
537:                }
538:                dump();
539:            }
540:
541:            private synchronized void deactivatePlugin(
542:                    final PluginDescriptor descr) {
543:                Plugin plugin = activePlugins.remove(descr.getId());
544:                if (plugin != null) {
545:                    try {
546:                        if (plugin.isActive()) {
547:                            fireEvent(plugin, false);
548:                            stopPlugin(plugin);
549:                            lifecycleHandler.afterPluginStop(plugin);
550:                            log.info("plug-in stopped - " + descr.getUniqueId() //$NON-NLS-1$
551:                                    + " (active/total: " + activePlugins.size() //$NON-NLS-1$
552:                                    + " of " //$NON-NLS-1$
553:                                    + registry.getPluginDescriptors().size()
554:                                    + ")"); //$NON-NLS-1$
555:                        } else {
556:                            log
557:                                    .warn(
558:                                            "plug-in " + descr.getUniqueId() //$NON-NLS-1$
559:                                                    + " is not active although present in active " //$NON-NLS-1$
560:                                                    + "plug-ins list", new Exception( //$NON-NLS-1$
561:                                                    "fake exception to view stack trace")); //$NON-NLS-1$
562:                        }
563:                    } catch (Exception e) {
564:                        log.error("error while stopping plug-in " //$NON-NLS-1$
565:                                + descr.getUniqueId(), e);
566:                    }
567:                }
568:                PluginClassLoader clsLoader = classLoaders
569:                        .remove(descr.getId());
570:                if (clsLoader != null) {
571:                    disposeClassLoader(clsLoader);
572:                }
573:                badPlugins.remove(descr.getId());
574:                activationLog.remove(descr.getId());
575:            }
576:
577:            private void dump() {
578:                if (!log.isDebugEnabled()) {
579:                    return;
580:                }
581:                StringBuilder buf = new StringBuilder(
582:                        "PLUGIN MANAGER DUMP:\r\n"); //$NON-NLS-1$
583:                buf.append("-------------- DUMP BEGIN -----------------\r\n"); //$NON-NLS-1$
584:                buf.append("\tActive plug-ins: " + activePlugins.size()) //$NON-NLS-1$
585:                        .append("\r\n"); //$NON-NLS-1$
586:                for (Plugin plugin : activePlugins.values()) {
587:                    buf.append("\t\t") //$NON-NLS-1$
588:                            .append(plugin).append("\r\n"); //$NON-NLS-1$
589:                }
590:                buf.append("\tActivating plug-ins: " //$NON-NLS-1$
591:                        + activatingPlugins.size()).append("\r\n"); //$NON-NLS-1$
592:                for (String s : activatingPlugins) {
593:                    buf.append("\t\t") //$NON-NLS-1$
594:                            .append(s).append("\r\n"); //$NON-NLS-1$
595:                }
596:                buf.append("\tPlug-ins with instantiated class loaders: " //$NON-NLS-1$
597:                        + classLoaders.size()).append("\r\n"); //$NON-NLS-1$
598:                for (String s : classLoaders.keySet()) {
599:                    buf.append("\t\t") //$NON-NLS-1$
600:                            .append(s).append("\r\n"); //$NON-NLS-1$
601:                }
602:                buf.append("\tDisabled plug-ins: " + disabledPlugins.size()) //$NON-NLS-1$
603:                        .append("\r\n"); //$NON-NLS-1$
604:                for (String s : disabledPlugins) {
605:                    buf.append("\t\t") //$NON-NLS-1$
606:                            .append(s).append("\r\n"); //$NON-NLS-1$
607:                }
608:                buf.append("\tBad plug-ins: " + badPlugins.size()) //$NON-NLS-1$
609:                        .append("\r\n"); //$NON-NLS-1$
610:                for (String s : badPlugins) {
611:                    buf.append("\t\t") //$NON-NLS-1$
612:                            .append(s).append("\r\n"); //$NON-NLS-1$
613:                }
614:                buf.append("\tActivation log: " + activationLog.size()) //$NON-NLS-1$
615:                        .append("\r\n"); //$NON-NLS-1$
616:                for (String s : activationLog) {
617:                    buf.append("\t\t") //$NON-NLS-1$
618:                            .append(s).append("\r\n"); //$NON-NLS-1$
619:                }
620:                buf.append("Memory TOTAL/FREE/MAX: ") //$NON-NLS-1$
621:                        .append(Runtime.getRuntime().totalMemory()).append("/") //$NON-NLS-1$
622:                        .append(Runtime.getRuntime().freeMemory()).append("/") //$NON-NLS-1$
623:                        .append(Runtime.getRuntime().maxMemory())
624:                        .append("\r\n"); //$NON-NLS-1$
625:                buf.append("-------------- DUMP END -----------------"); //$NON-NLS-1$
626:                log.debug(buf.toString());
627:            }
628:
629:            /**
630:             * Disables plug-in (with dependencies) in this manager instance. Disabled
631:             * plug-in can't be activated although it may be valid and successfully
632:             * registered with plug-in registry. Before disabling, plug-in will be
633:             * deactivated if it was successfully activated. <br>
634:             * Be careful with this method as it can effectively disable large set of
635:             * inter-depending plug-ins and your application may become unstable or even
636:             * disabled as whole.
637:             * 
638:             * @param descr
639:             *            descriptor of plug-in to be disabled
640:             * @return descriptors of plug-ins that was actually disabled
641:             */
642:            @Override
643:            public PluginDescriptor[] disablePlugin(final PluginDescriptor descr) {
644:                final List<PluginDescriptor> result = new LinkedList<PluginDescriptor>();
645:                if (!disabledPlugins.contains(descr.getId())) {
646:                    deactivatePlugin(descr);
647:                    fireEvent(descr, false);
648:                    disabledPlugins.add(descr.getId());
649:                    result.add(descr);
650:                }
651:
652:                for (PluginDescriptor dependedPlugin : registry
653:                        .getDependingPlugins(descr)) {
654:                    if (!disabledPlugins.contains(dependedPlugin.getId())) {
655:                        deactivatePlugin(dependedPlugin);
656:                        fireEvent(dependedPlugin, false);
657:                        disabledPlugins.add(dependedPlugin.getId());
658:                        result.add(dependedPlugin);
659:                    }
660:                }
661:                return result.toArray(new PluginDescriptor[result.size()]);
662:            }
663:
664:            /**
665:             * Enables plug-in (or plug-ins) in this manager instance.
666:             * 
667:             * @param descr
668:             *            descriptor of plug-in to be enabled
669:             * @param includeDependings
670:             *            if <code>true</code>, depending plug-ins will be also
671:             *            enabled
672:             * @return descriptors of plug-ins that was actually enabled
673:             * @see #disablePlugin(PluginDescriptor)
674:             */
675:            @Override
676:            public PluginDescriptor[] enablePlugin(
677:                    final PluginDescriptor descr,
678:                    final boolean includeDependings) {
679:                final List<PluginDescriptor> result = new LinkedList<PluginDescriptor>();
680:                if (disabledPlugins.contains(descr.getId())) {
681:                    disabledPlugins.remove(descr.getId());
682:                    fireEvent(descr, true);
683:                    result.add(descr);
684:                }
685:                if (includeDependings) {
686:                    for (PluginDescriptor dependedPlugin : registry
687:                            .getDependingPlugins(descr)) {
688:                        if (disabledPlugins.contains(dependedPlugin.getId())) {
689:                            disabledPlugins.remove(dependedPlugin.getId());
690:                            fireEvent(dependedPlugin, true);
691:                            result.add(dependedPlugin);
692:                        }
693:                    }
694:                }
695:                return result.toArray(new PluginDescriptor[result.size()]);
696:            }
697:
698:            /**
699:             * @param descr
700:             *            plug-in descriptor
701:             * @return <code>true</code> if given plug-in is disabled in this manager
702:             */
703:            @Override
704:            public boolean isPluginEnabled(final PluginDescriptor descr) {
705:                return !disabledPlugins.contains(descr.getId());
706:            }
707:
708:            /**
709:             * Registers plug-in manager event listener. If given listener has been
710:             * registered before, this method will throw an
711:             * {@link IllegalArgumentException}.
712:             * 
713:             * @param listener
714:             *            new manager event listener
715:             */
716:            @Override
717:            public void registerListener(final EventListener listener) {
718:                if (listeners.contains(listener)) {
719:                    throw new IllegalArgumentException("listener " + listener //$NON-NLS-1$
720:                            + " already registered"); //$NON-NLS-1$
721:                }
722:                listeners.add(listener);
723:            }
724:
725:            /**
726:             * Unregisters manager event listener. If given listener hasn't been
727:             * registered before, this method will throw an
728:             * {@link IllegalArgumentException}.
729:             * 
730:             * @param listener
731:             *            registered listener
732:             */
733:            @Override
734:            public void unregisterListener(final EventListener listener) {
735:                if (!listeners.remove(listener)) {
736:                    log.warn("unknown listener " + listener); //$NON-NLS-1$
737:                }
738:            }
739:
740:            private void fireEvent(final Object data, final boolean on) {
741:                if (listeners.isEmpty()) {
742:                    return;
743:                }
744:                // make local copy
745:                EventListener[] arr = listeners
746:                        .toArray(new EventListener[listeners.size()]);
747:                // propagate event basing on given data type and on/off flag
748:                // NB: revise this logic if EventListener members are changed
749:                if (data instanceof  PluginDescriptor) {
750:                    PluginDescriptor descr = (PluginDescriptor) data;
751:                    if (on) {
752:                        if (log.isDebugEnabled()) {
753:                            log
754:                                    .debug("propagating \"pluginEnabled\" event for " //$NON-NLS-1$
755:                                            + descr);
756:                        }
757:                        for (EventListener element : arr) {
758:                            element.pluginEnabled(descr);
759:                        }
760:                    } else {
761:                        if (log.isDebugEnabled()) {
762:                            log
763:                                    .debug("propagating \"pluginDisabled\" event for " //$NON-NLS-1$
764:                                            + descr);
765:                        }
766:                        for (EventListener element : arr) {
767:                            element.pluginDisabled(descr);
768:                        }
769:                    }
770:                } else {
771:                    Plugin plugin = (Plugin) data;
772:                    if (on) {
773:                        if (log.isDebugEnabled()) {
774:                            log
775:                                    .debug("propagating \"pluginActivated\" event for " //$NON-NLS-1$
776:                                            + plugin);
777:                        }
778:                        for (EventListener element : arr) {
779:                            element.pluginActivated(plugin);
780:                        }
781:                    } else {
782:                        if (log.isDebugEnabled()) {
783:                            log
784:                                    .debug("propagating \"pluginDeactivated\" event for " //$NON-NLS-1$
785:                                            + plugin);
786:                        }
787:                        for (EventListener element : arr) {
788:                            element.pluginDeactivated(plugin);
789:                        }
790:                    }
791:                }
792:            }
793:
794:            static final class EmptyPlugin extends Plugin {
795:                /**
796:                 * @see org.java.plugin.Plugin#doStart()
797:                 */
798:                @Override
799:                protected void doStart() throws Exception {
800:                    // no-op
801:                }
802:
803:                /**
804:                 * @see org.java.plugin.Plugin#doStop()
805:                 */
806:                @Override
807:                protected void doStop() throws Exception {
808:                    // no-op
809:                }
810:            }
811:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.