001    package de.deepamehta.core.osgi;
002    
003    import de.deepamehta.core.service.DeepaMehtaService;
004    import de.deepamehta.core.service.PluginService;
005    import de.deepamehta.core.service.SecurityHandler;
006    import de.deepamehta.core.impl.PluginImpl;
007    
008    import org.osgi.framework.Bundle;
009    import org.osgi.framework.BundleActivator;
010    import org.osgi.framework.BundleContext;
011    
012    import java.io.InputStream;
013    import java.util.logging.Level;
014    import java.util.logging.Logger;
015    
016    
017    
018    /**
019     * Base class for all DeepaMehta plugins.
020     * All DeepaMehta plugins are derived from this class, directly or indirectly.
021     * ### FIXDOC: subclassing is not required if the plugin has no server-side part.
022     */
023    public class PluginActivator implements BundleActivator, PluginContext {
024    
025        // ---------------------------------------------------------------------------------------------- Instance Variables
026    
027        protected DeepaMehtaService dms;
028        protected Bundle bundle;
029    
030        private BundleContext bundleContext;
031        private PluginImpl plugin;
032        private String pluginName;  // This bundle's name = POM project name, e.g. "DeepaMehta 4 Webclient"
033    
034        private Logger logger = Logger.getLogger(getClass().getName());
035    
036        // -------------------------------------------------------------------------------------------------- Public Methods
037    
038    
039    
040        // **************************************
041        // *** BundleActivator Implementation ***
042        // **************************************
043    
044    
045    
046        @Override
047        public void start(BundleContext context) {
048            try {
049                // Note: logging "this" requires "pluginName" to be initialzed already
050                this.bundleContext = context;
051                this.bundle = context.getBundle();
052                this.pluginName = (String) bundle.getHeaders().get("Bundle-Name");
053                //
054                logger.info("========== Starting " + this + " ==========");
055                plugin = new PluginImpl(this);
056                plugin.start();
057            } catch (Throwable e) {
058                logger.log(Level.SEVERE, "Starting " + this + " failed", e);
059                // Note: here we catch anything, also errors (like NoClassDefFoundError).
060                // If thrown through the OSGi container it would not print out the stacktrace.
061                // File Install would retry to start the bundle endlessly.
062            }
063        }
064    
065        @Override
066        public void stop(BundleContext context) {
067            try {
068                if (plugin == null) {
069                    logger.info("Stopping " + this + " ABORTED -- it was not successfully started");
070                    return;
071                }
072                //
073                logger.info("========== Stopping " + this + " ==========");
074                plugin.stop();
075            } catch (Throwable e) {
076                logger.log(Level.SEVERE, "Stopping " + this + " failed", e);
077                // Note: here we catch anything, also errors (like NoClassDefFoundError).
078                // If thrown through the OSGi container it would not print out the stacktrace.
079            }
080        }
081    
082    
083    
084        // ************************************
085        // *** PluginContext Implementation ***
086        // ************************************
087    
088    
089    
090        @Override
091        public void init() {
092        }
093    
094        @Override
095        public void shutdown() {
096        }
097    
098        @Override
099        public void serviceArrived(PluginService service) {
100        }
101    
102        @Override
103        public void serviceGone(PluginService service) {
104        }
105    
106        // ---
107    
108        @Override
109        public final String getPluginName() {
110            return pluginName;
111        }
112    
113        @Override
114        public final BundleContext getBundleContext() {
115            return bundleContext;
116        }
117    
118        @Override
119        public final void setCoreService(DeepaMehtaService dms) {
120            this.dms = dms;
121        }
122    
123    
124    
125        // ===
126    
127        @Override
128        public String toString() {
129            return "plugin \"" + pluginName + "\"";
130        }
131    
132    
133    
134        // ----------------------------------------------------------------------------------------------- Protected Methods
135    
136        protected final String getUri() {
137            return plugin.getUri();
138        }
139    
140        protected final InputStream getStaticResource(String name) {
141            return plugin.getStaticResource(name);
142        }
143    
144        // ---
145    
146        /**
147         * @param   securityHandler     Optional. If null no security is provided.
148         */
149        protected final void publishDirectory(String directoryPath, String uriNamespace, SecurityHandler securityHandler) {
150            plugin.publishDirectory(directoryPath, uriNamespace, securityHandler);
151        }
152    }