/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.pentaho.di.ui.spoon; import org.pentaho.di.core.exception.KettlePluginException; import org.pentaho.di.core.plugins.PluginInterface; import org.pentaho.di.core.plugins.PluginRegistry; import org.pentaho.di.core.plugins.PluginTypeListener; import org.pentaho.ui.xul.XulDomContainer; import org.pentaho.ui.xul.XulException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * SpoonPluginManager is a singleton class which loads all SpoonPlugins from the SPOON_HOME/plugins/spoon directory. * <p/> * Spoon Plugins are able to listen for SpoonLifeCycleEvents and can register categorized XUL Overlays to be retrieved * later. * <p/> * Spoon Plugins are deployed as directories under the SPOON_HOME/plugins/spoon directory. Each plugin must provide a * build.xml as the root of it's directory and have any required jars under a "lib" directory. * <p/> * The plugin.xml format is Spring-based e.g. <beans xmlns="http://www.springframework.org/schema/beans" * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= * "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> * <p/> * <bean id="PLUGIN_ID" class="org.foo.SpoonPluginClassName"></bean> </beans> * * @author nbaker */ public class SpoonPluginManager implements PluginTypeListener { private static SpoonPluginManager instance = new SpoonPluginManager(); private Map<Object, SpoonPluginInterface> plugins = new HashMap<>(); private Map<String, List<SpoonPluginInterface>> pluginCategoryMap = new HashMap<>(); @Override public void pluginAdded( final Object serviceObject ) { try { SpoonPluginInterface spoonPluginInterface = (SpoonPluginInterface) getPluginRegistry().loadClass( (PluginInterface) serviceObject ); if ( plugins.get( serviceObject ) != null ) { return; } SpoonPluginCategories categories = spoonPluginInterface.getClass().getAnnotation( SpoonPluginCategories.class ); if ( categories != null ) { for ( String cat : categories.value() ) { List<SpoonPluginInterface> categoryList = pluginCategoryMap.get( cat ); if ( categoryList == null ) { categoryList = new ArrayList<>(); pluginCategoryMap.put( cat, categoryList ); } categoryList.add( spoonPluginInterface ); } } if ( spoonPluginInterface.getPerspective() != null ) { getSpoonPerspectiveManager().addPerspective( spoonPluginInterface.getPerspective() ); } plugins.put( serviceObject, spoonPluginInterface ); } catch ( KettlePluginException e ) { e.printStackTrace(); } } @Override public void pluginRemoved( Object serviceObject ) { SpoonPluginInterface spoonPluginInterface = plugins.get( serviceObject ); if ( spoonPluginInterface == null ) { return; } SpoonPluginCategories categories = spoonPluginInterface.getClass().getAnnotation( SpoonPluginCategories.class ); if ( categories != null ) { for ( String cat : categories.value() ) { List<SpoonPluginInterface> categoryList = pluginCategoryMap.get( cat ); categoryList.remove( spoonPluginInterface ); } } if ( spoonPluginInterface.getPerspective() != null ) { getSpoonPerspectiveManager().removePerspective( spoonPluginInterface.getPerspective() ); } plugins.remove( serviceObject ); } @Override public void pluginChanged( Object serviceObject ) { // Not implemented yet } /** * Return the single instance of this class * * @return SpoonPerspectiveManager */ public static SpoonPluginManager getInstance() { return instance; } public void applyPluginsForContainer( final String category, final XulDomContainer container ) throws XulException { List<SpoonPluginInterface> plugins = pluginCategoryMap.get( category ); if ( plugins != null ) { for ( SpoonPluginInterface sp : plugins ) { sp.applyToContainer( category, container ); } } } /** * Returns an unmodifiable list of all Spoon Plugins. * * @return list of plugins */ public List<SpoonPluginInterface> getPlugins() { return Collections.unmodifiableList( Arrays.asList( plugins.values().toArray( new SpoonPluginInterface[] {} ) ) ); } /** * Notifies all registered SpoonLifecycleListeners of the given SpoonLifeCycleEvent. * * @param evt event to notify listeners about */ public void notifyLifecycleListeners( SpoonLifecycleListener.SpoonLifeCycleEvent evt ) { for ( SpoonPluginInterface p : plugins.values() ) { SpoonLifecycleListener listener = p.getLifecycleListener(); if ( listener != null ) { listener.onEvent( evt ); } } } PluginRegistry getPluginRegistry() { return PluginRegistry.getInstance(); } SpoonPerspectiveManager getSpoonPerspectiveManager() { return SpoonPerspectiveManager.getInstance(); } private SpoonPluginManager() { PluginRegistry pluginRegistry = getPluginRegistry(); pluginRegistry.addPluginListener( SpoonPluginType.class, this ); List<PluginInterface> plugins = pluginRegistry.getPlugins( SpoonPluginType.class ); for ( PluginInterface plug : plugins ) { pluginAdded( plug ); } } }