/** * */ package org.eclipse.papyrus.infra.core.services.internal; import org.eclipse.core.runtime.Platform; import org.eclipse.papyrus.infra.core.services.BadStateException; import org.eclipse.papyrus.infra.core.services.ServiceDescriptor; import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.services.ServiceState; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.osgi.framework.Bundle; /** * Base class for the different types of service entries (PoJo, Service, * ServiceFactory, ...). * * @author cedric dumoulin */ public abstract class ServiceTypeEntry { /** * Current state of the service. */ protected ServiceState state = ServiceState.registered; /** * Descriptor of the service associated to this entry. */ protected ServiceDescriptor serviceDescriptor; /** * * Constructor. * */ public ServiceTypeEntry(ServiceDescriptor serviceDescriptor) { this.serviceDescriptor = serviceDescriptor; } /** * Change the state of the service. * * @param newState */ protected void setState(ServiceState newState) { state = newState; } /** * @return the state */ public ServiceState getState() { return state; } /** * Check if the current state is the proposed state. Throws an exception if * the state is different. * * @param expectedState * @throws BadStateException */ protected void checkState(ServiceState expectedState) throws BadStateException { if(expectedState != state) { throw new BadStateException(expectedState, state, serviceDescriptor); } } /** * Get the descriptor of the service associated to this entry. * * @return */ public ServiceDescriptor getDescriptor() { return serviceDescriptor; } /** * Instanciate the service as specified in serviceClassname. * * @return the created service. * @throws ServiceException */ protected Object instanciateService() throws ServiceException { // Load the Class of the service String serviceClassname = serviceDescriptor.getServiceClassname(); Class<?> classname = loadClass(); // Try to get the one arg constructor. // This require the ServiceRegistry. Old stuff, not more used. // try { // Constructor<?> constructor = // classname.getConstructor(ServicesRegistry.class); // return constructor.newInstance(registry); // } catch (SecurityException e) { // // Do nothing, try next constructor // } catch (NoSuchMethodException e) { // // Do nothing, try next constructor // } catch (IllegalArgumentException e) { // throw new ServiceException("Can't instanciate '" + serviceClassname + // "' with args ServicesRegistry.", e); // } catch (InstantiationException e) { // throw new ServiceException("Can't instanciate '" + serviceClassname + // "' with args ServicesRegistry.", e); // } catch (IllegalAccessException e) { // throw new ServiceException("Can't instanciate '" + serviceClassname + // "' with args ServicesRegistry.", e); // } catch (InvocationTargetException e) { // throw new ServiceException("Can't instanciate '" + serviceClassname + // "' with args ServicesRegistry.", e); // } // Try with zero arg constructor. try { return classname.newInstance(); } catch (SecurityException e) { throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e); } catch (IllegalArgumentException e) { throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e); } catch (InstantiationException e) { throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e); } catch (IllegalAccessException e) { throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e); } } /** * Load the Class object. Try from current ClassLoader, then try using the * plugin referenced in the serviceDescriptor.PluginId * * @return * @throws ServiceException */ private Class<?> loadClass() throws ServiceException { String serviceClassname = serviceDescriptor.getServiceClassname(); Class<?> serviceClass; try { serviceClass = Class.forName(serviceClassname); } catch (ClassNotFoundException e1) { // Try using bundle try { String bundleID = serviceDescriptor.getClassBundleID(); Bundle bundle = Platform.getBundle(bundleID); serviceClass = bundle.loadClass(serviceClassname); } catch (ClassNotFoundException e2) { throw new ServiceException("Can't find class for the name '" + serviceClassname + "'.", e2); } } return serviceClass; } /** * Return true if the service is started. Return false otherwise. * * @return */ public boolean isStarted() { return state == ServiceState.started; } /** * Get the service instance. * * @return * @throws ServiceException */ abstract public Object getServiceInstance() throws ServiceException; /** * Create the associated service if not a Lazy Service. * * @throws ServiceException */ abstract public void createService() throws ServiceException; /** * Start the associated service if not a Lazy Service. * * @param servicesRegistry * The servicesRegistry containing this service. * * @throws ServiceException */ abstract public void initService(ServicesRegistry servicesRegistry) throws ServiceException; /** * Start the associated service if not a Lazy Service. * * @throws ServiceException */ abstract public void startService() throws ServiceException; /** * Dispose associated service. */ abstract public void disposeService() throws ServiceException; }