001    package de.deepamehta.core.osgi;
002    
003    import de.deepamehta.core.impl.EmbeddedService;
004    import de.deepamehta.core.impl.StorageDecorator;
005    import de.deepamehta.core.impl.WebPublishingService;
006    import de.deepamehta.core.service.DeepaMehtaService;
007    import de.deepamehta.core.storage.spi.DeepaMehtaStorage;
008    
009    import org.osgi.framework.BundleActivator;
010    import org.osgi.framework.BundleContext;
011    import org.osgi.framework.ServiceReference;
012    import org.osgi.service.http.HttpService;
013    import org.osgi.util.tracker.ServiceTracker;
014    
015    import java.util.logging.Level;
016    import java.util.logging.Logger;
017    
018    
019    
020    public class CoreActivator implements BundleActivator {
021    
022        // ------------------------------------------------------------------------------------------------------- Constants
023    
024        private static final String DATABASE_PATH    = System.getProperty("dm4.database.path");
025    
026        // ---------------------------------------------------------------------------------------------- Instance Variables
027    
028        private BundleContext bundleContext;
029    
030        // consumed services
031        private DeepaMehtaStorage storageService;
032        private HttpService httpService;
033    
034        private ServiceTracker storageServiceTracker;
035        private ServiceTracker httpServiceTracker;
036    
037        private Logger logger = Logger.getLogger(getClass().getName());
038    
039        // -------------------------------------------------------------------------------------------------- Public Methods
040    
041    
042    
043        // **************************************
044        // *** BundleActivator Implementation ***
045        // **************************************
046    
047    
048    
049        @Override
050        public void start(BundleContext bundleContext) {
051            try {
052                logger.info("========== Starting \"DeepaMehta 4 Core\" ==========");
053                this.bundleContext = bundleContext;
054                //
055                storageServiceTracker = createServiceTracker(DeepaMehtaStorage.class);
056                httpServiceTracker = createServiceTracker(HttpService.class);
057                //
058                storageServiceTracker.open();
059                httpServiceTracker.open();
060            } catch (Throwable e) {
061                logger.log(Level.SEVERE, "Starting \"DeepaMehta 4 Core\" failed", e);
062                // Note: here we catch anything, also errors (like NoClassDefFoundError).
063                // If thrown through the OSGi container it would not print out the stacktrace.
064                // File Install would retry to start the bundle endlessly.
065            }
066        }
067    
068        @Override
069        public void stop(BundleContext bundleContext) {
070            try {
071                logger.info("========== Stopping \"DeepaMehta 4 Core\" ==========");
072                storageServiceTracker.close();
073                httpServiceTracker.close();
074                //
075                // Note: we do not shutdown the DB here.
076                // The DB shuts down itself through the storage bundle's stop() method.
077            } catch (Throwable e) {
078                logger.log(Level.SEVERE, "Stopping \"DeepaMehta 4 Core\" failed", e);
079                // Note: here we catch anything, also errors (like NoClassDefFoundError).
080                // If thrown through the OSGi container it would not print out the stacktrace.
081            }
082        }
083    
084    
085    
086        // ------------------------------------------------------------------------------------------------- Private Methods
087    
088        private ServiceTracker createServiceTracker(final Class serviceInterface) {
089            //
090            return new ServiceTracker(bundleContext, serviceInterface.getName(), null) {
091    
092                @Override
093                public Object addingService(ServiceReference serviceRef) {
094                    Object service = null;
095                    try {
096                        service = super.addingService(serviceRef);
097                        addService(service);
098                    } catch (Throwable e) {
099                        logger.log(Level.SEVERE, "Adding service " + serviceInterface.getName() +
100                            " to \"DeepaMehta 4 Core\" failed", e);
101                        // Note: here we catch anything, also errors (like NoClassDefFoundError).
102                        // If thrown through the OSGi container it would not print out the stacktrace.
103                    }
104                    return service;
105                }
106    
107                @Override
108                public void removedService(ServiceReference ref, Object service) {
109                    try {
110                        removeService(service);
111                        super.removedService(ref, service);
112                    } catch (Throwable e) {
113                        logger.log(Level.SEVERE, "Removing service " + serviceInterface.getName() +
114                            " from \"DeepaMehta 4 Core\" failed", e);
115                        // Note: here we catch anything, also errors (like NoClassDefFoundError).
116                        // If thrown through the OSGi container it would not print out the stacktrace.
117                    }
118                }
119            };
120        }
121    
122        // ---
123    
124        private void addService(Object service) {
125            if (service instanceof DeepaMehtaStorage) {
126                logger.info("Adding storage service to DeepaMehta 4 Core");
127                storageService = (DeepaMehtaStorage) service;
128                checkRequirementsForActivation();
129            } else if (service instanceof HttpService) {
130                logger.info("Adding HTTP service to DeepaMehta 4 Core");
131                httpService = (HttpService) service;
132                checkRequirementsForActivation();
133            }
134        }
135    
136        private void removeService(Object service) {
137            if (service == storageService) {
138                logger.info("Removing storage service from DeepaMehta 4 Core");
139                storageService = null;
140            } else if (service == httpService) {
141                logger.info("Removing HTTP service from DeepaMehta 4 Core");
142                // ### TODO: unregister WebPublishingService
143                httpService = null;
144            }
145        }
146    
147        // ---
148    
149        private void checkRequirementsForActivation() {
150            if (storageService != null && httpService != null) {
151                EmbeddedService dms = new EmbeddedService(new StorageDecorator(storageService), bundleContext);
152                logger.info("Registering DeepaMehta 4 core service at OSGi framework");
153                bundleContext.registerService(DeepaMehtaService.class.getName(), dms, null);
154                //
155                WebPublishingService wpService = new WebPublishingService(dms, httpService);
156                logger.info("Registering Web Publishing service at OSGi framework");
157                bundleContext.registerService(WebPublishingService.class.getName(), wpService, null);
158            }
159        }
160    }