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