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