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