001package systems.dmx.core.osgi;
002
003import systems.dmx.core.service.CoreService;
004import systems.dmx.core.service.ModelFactory;
005import systems.dmx.core.impl.PluginImpl;
006
007import org.osgi.framework.Bundle;
008import org.osgi.framework.BundleActivator;
009import org.osgi.framework.BundleContext;
010
011import java.io.InputStream;
012import java.util.logging.Level;
013import java.util.logging.Logger;
014
015
016
017/**
018 * Base class for all DMX plugins.
019 * All DMX plugins are derived from this class, directly or indirectly.
020 * ### FIXDOC: subclassing is not required if the plugin has no server-side part.
021 */
022public class PluginActivator implements BundleActivator, PluginContext {
023
024    // ---------------------------------------------------------------------------------------------- Instance Variables
025
026    protected CoreService dmx;
027    protected ModelFactory mf;
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. "DMX 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, "An error occurred while starting " + this + ":", 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 + " SKIPPED -- 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, "An error occurred while stopping " + this + ":", 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 preInstall() {
092    }
093
094    @Override
095    public void init() {
096    }
097
098    @Override
099    public void shutdown() {
100    }
101
102    @Override
103    public void serviceArrived(Object service) {
104    }
105
106    @Override
107    public void serviceGone(Object 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(CoreService dmx) {
124        this.dmx = dmx;
125        this.mf = dmx != null ? dmx.getModelFactory() : null;
126    }
127
128
129
130    // === Java API ===
131
132    @Override
133    public String toString() {
134        return "plugin \"" + pluginName + "\"";
135    }
136
137
138
139    // ----------------------------------------------------------------------------------------------- Protected Methods
140
141    protected final String getUri() {
142        return plugin.getUri();
143    }
144
145    protected final InputStream getStaticResource(String name) {
146        return plugin.getStaticResource(name);
147    }
148
149    // ---
150
151    /**
152     * Publishes a directory of the server's file system.
153     *
154     * @param   path            An absolute path to a directory.
155     */
156    protected final void publishFileSystem(String uriNamespace, String path) {
157        plugin.publishFileSystem(uriNamespace, path);
158    }
159}