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