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 postInstall() {
100        }
101    
102        @Override
103        public void serviceArrived(PluginService service) {
104        }
105    
106        @Override
107        public void serviceGone(PluginService service) {
108        }
109    
110        // ---
111    
112        @Override
113        public final String getPluginName() {
114            return pluginName;
115        }
116    
117        @Override
118        public final BundleContext getBundleContext() {
119            return bundleContext;
120        }
121    
122        @Override
123        public final void setCoreService(DeepaMehtaService dms) {
124            this.dms = dms;
125        }
126    
127    
128    
129        // ===
130    
131        @Override
132        public String toString() {
133            return "plugin \"" + pluginName + "\"";
134        }
135    
136    
137    
138        // ----------------------------------------------------------------------------------------------- Protected Methods
139    
140        protected final String getUri() {
141            return plugin.getUri();
142        }
143    
144        protected final InputStream getStaticResource(String name) {
145            return plugin.getStaticResource(name);
146        }
147    
148        // ---
149    
150        /**
151         * @param   securityHandler     Optional. If null no security is provided.
152         */
153        protected final void publishDirectory(String directoryPath, String uriNamespace, SecurityHandler securityHandler) {
154            plugin.publishDirectory(directoryPath, uriNamespace, securityHandler);
155        }
156    }