diff options
Diffstat (limited to 'plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core')
16 files changed, 3897 insertions, 3783 deletions
diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/BadStateException.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/BadStateException.java index a7651c864c8..a9885e6f3e0 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/BadStateException.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/BadStateException.java @@ -1,49 +1,60 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * @author cedric dumoulin
- *
- */
-public class BadStateException extends ServiceException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- */
- public BadStateException(ServiceState expectedState, ServiceState state, ServiceDescriptor descriptor) {
- super("Bad state for service '" + descriptor.getKey() + "'. Expected '" + expectedState + "' found '" + state + "'.");
- }
-
- /**
- *
- * Constructor.
- *
- * @param text
- * @param state
- * @param serviceDescriptor
- */
- public BadStateException(String text, ServiceState state, ServiceDescriptor descriptor) {
- super(text + " (Service= '" + (descriptor!=null?descriptor.getKey():"unknown") + ", state= " + state + ")");
- }
-
- /**
- *
- * Constructor.
- *
- * @param text
- * @param state
- * @param serviceDescriptor
- */
- public BadStateException(String text, ServiceState state, ServiceDescriptor descriptor, Throwable cause) {
- super(text + " (Service= '" + descriptor.getKey() + ", state= " + state + ")", cause);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * @author cedric dumoulin + * + */ +public class BadStateException extends ServiceException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public BadStateException(ServiceState expectedState, ServiceState state, ServiceDescriptor descriptor) { + super("Bad state for service '" + descriptor.getKey() + "'. Expected '" + expectedState + "' found '" + state + "'."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + /** + * + * Constructor. + * + * @param text + * @param state + * @param serviceDescriptor + */ + public BadStateException(String text, ServiceState state, ServiceDescriptor descriptor) { + super(text + " (Service= '" + (descriptor!=null?descriptor.getKey():"unknown") + ", state= " + state + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + /** + * + * Constructor. + * + * @param text + * @param state + * @param serviceDescriptor + */ + public BadStateException(String text, ServiceState state, ServiceDescriptor descriptor, Throwable cause) { + super(text + " (Service= '" + descriptor.getKey() + ", state= " + state + ")", cause); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/DescriptorsCache.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/DescriptorsCache.java index 751010a0b18..c7e897c3a5d 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/DescriptorsCache.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/DescriptorsCache.java @@ -1,358 +1,358 @@ -/*****************************************************************************
- * Copyright (c) 2012 Cedric Dumoulin.
- *
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.List;
-
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AliasDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.Descriptors;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.RegistryDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceFactoryDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceSetDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServicedescriptorsFactory;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.StartupKind;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceFactoryIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc;
-
-
-/**
- * A cache used to query the {@link IServiceDescriptorsWithIdProvider}. The cache return resolved descriptors,
- * in the form of instance of the ServiceDescriptors model.
- *
- * @author cedric dumoulin
- *
- */
-public class DescriptorsCache {
-
- /**
- * The cache of descriptors.
- */
- protected Descriptors descriptorsCache;
-
- /**
- * The provider used to query declarations.
- */
- protected ServiceDescriptorsWithIdProviderCollection declaredDescriptorProvider;
-
-
-
- /**
- *
- * Constructor.
- *
- */
- public DescriptorsCache() {
- declaredDescriptorProvider = new ServiceDescriptorsWithIdProviderCollection();
- descriptorsCache = ServicedescriptorsFactory.eINSTANCE.createDescriptors();
- }
-
- /**
- * Add all the provided {@link IServiceDescriptorsWithIdProvider} to the list of providers to use.
- *
- * @param declaredDescriptorProviders
- */
- public void addAll(IServiceDescriptorsWithIdProvider... declaredDescriptorProviders) {
-
- declaredDescriptorProvider.addAll(declaredDescriptorProviders);
- descriptorsCache = ServicedescriptorsFactory.eINSTANCE.createDescriptors();
-
- }
-
- /**
- * Get the descriptor for the specified registry.
- * The descriptor is built from the declarations found in {@link #declaredDescriptorProvider}.
- * The descriptor is cached. This mean that subsequent calls for the same name will return the same
- * result. <br/>
- * If the registry is not found, throws an exception.
- *
- * @param registryName
- * The name of the registry for which the descriptor is required.
- *
- * @return The registry descriptor
- * @throws DeclarationException
- * If an error occur while reading declarations.
- *
- */
- public RegistryDesc getRegistryDesc(String registryName) throws DeclarationException {
-
- // Try from cache
- RegistryDesc desc = descriptorsCache.getRegistryDesc(registryName);
-
- if(desc != null) {
- return desc;
- }
-
- // Load from providers
- // this can throw exception
- RegistryIdDesc idDesc = declaredDescriptorProvider.getRegistryIdDesc(registryName);
-
- // Create a RegistryDesc from a RegistryIdDesc, and set minimal data
- desc = ServicedescriptorsFactory.eINSTANCE.createRegistryDesc();
- desc.setName(idDesc.getName());
- desc.setIsUnique(idDesc.isUnique());
- desc.setDescription(idDesc.getDescription());
-
- // Add it to the cache, so it can be found by other requests
- descriptorsCache.getRegistries().add(desc);
-
- // Set the references
- // serviceSet
- for(String serviceSetId : idDesc.getSets()) {
- desc.getServiceSets().add(getServiceSetDesc(serviceSetId));
- }
-
- // extends
- for(String extendsId : idDesc.getExtends()) {
- desc.getExtends().add(getRegistryDesc(extendsId));
- }
-
- // parents
- for(String extendsId : idDesc.getParents()) {
- desc.getParents().add(getRegistryDesc(extendsId));
- }
-
-
- // Resolve inheritances
- // need to compute services available for this registry
- // Available services are those from all sets, and from extends.
- computeRegistryServices(desc);
-
-
- return desc;
- }
-
- /**
- * Get the {@link ServiceSetDesc} for the specified name.
- * The descriptor is built from the declarations found in {@link #declaredDescriptorProvider}.
- * The descriptor is cached. This mean that subsequent calls for the same name will return the same
- * result. <br/>
- * If the descriptor is not found, throws an exception.
- *
- * @param serviceSetId
- * @return
- * @throws DeclarationException
- */
- public ServiceSetDesc getServiceSetDesc(String serviceSetId) throws DeclarationException {
- // Try from cache
- ServiceSetDesc desc = descriptorsCache.getServiceSetDesc(serviceSetId);
-
- if(desc != null) {
- return desc;
- }
-
- // Load from providers
- // this can throw exception
- ServiceSetIdDesc idDesc = declaredDescriptorProvider.getServiceSet(serviceSetId);
-
- // Create a RegistryDesc from a RegistryIdDesc, and set minimal data
- desc = ServicedescriptorsFactory.eINSTANCE.createServiceSetDesc();
- desc.setName(idDesc.getName());
- desc.setDescription(idDesc.getDescription());
-
- // Add it to the cache, so it can be found by other requests
- descriptorsCache.getServiceSets().add(desc);
-
- // Set the references
- // serviceSet
- for(AbstractServiceIdDesc serviceIdDesc : idDesc.getServiceDescriptors()) {
- desc.getOwnedServices().add(transformAbstractServiceIdDescToRef(serviceIdDesc));
- }
-
- // extends
- for(String extendsId : idDesc.getExtends()) {
- desc.getExtends().add(getServiceSetDesc(extendsId));
- }
-
- // Resolve inheritances
- // need to compute services available for this set
- // Available services are those from all extends.
- computeServiceSetServices(desc);
-
- return desc;
- }
-
- /**
- * Transform {@link AncestorEvent} {@link AbstractServiceIdDesc} to an {@link AbstractServiceDesc}.
- *
- * @param serviceIdDesc
- * @return
- */
- private AbstractServiceDesc transformAbstractServiceIdDescToRef(AbstractServiceIdDesc serviceIdDesc) {
- if(serviceIdDesc instanceof ServiceFactoryIdDesc) {
- return transformServiceFactoryIdDescToRef((ServiceFactoryIdDesc)serviceIdDesc);
- } else if(serviceIdDesc instanceof ServiceIdDesc) {
- return transformServiceIdDescToRef((ServiceIdDesc)serviceIdDesc);
- } else if(serviceIdDesc instanceof AliasIdDesc) {
- return transformAliasIdDescToRef((AliasIdDesc)serviceIdDesc);
- } else {
- // Should never happen
- throw new UnsupportedOperationException("Don't no how to transform '" + serviceIdDesc + "' to AbstractServiceDesc.");
- }
- }
-
- /**
- *
- * @param serviceIdDesc
- * @return
- */
- private AbstractServiceDesc transformServiceIdDescToRef(ServiceIdDesc serviceIdDesc) {
-
- ServiceDesc desc = ServicedescriptorsFactory.eINSTANCE.createServiceDesc();
- desc.setBundleID(serviceIdDesc.getBundleID());
- desc.setClassname(serviceIdDesc.getClassname());
- desc.setDescription(serviceIdDesc.getDescription());
- desc.setName(serviceIdDesc.getName());
- desc.setPriority(serviceIdDesc.getPriority());
- desc.setStartKind(transformStartKind(serviceIdDesc.getStartKind()));
- // dependsOn
- desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn());
-
- return desc;
- }
-
- /**
- *
- * @param startKind
- * @return
- */
- private StartupKind transformStartKind(org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind startKind) {
-
- switch(startKind) {
- case STARTUP:
- return StartupKind.STARTUP;
- case LAZY:
- return StartupKind.LAZY;
- default:
- return StartupKind.STARTUP;
- }
- }
-
- /**
- *
- * @param serviceIdDesc
- * @return
- */
- private AbstractServiceDesc transformAliasIdDescToRef(AliasIdDesc serviceIdDesc) {
- AliasDesc desc = ServicedescriptorsFactory.eINSTANCE.createAliasDesc();
- desc.setBundleID(serviceIdDesc.getBundleID());
- desc.setDescription(serviceIdDesc.getDescription());
- desc.setName(serviceIdDesc.getName());
- desc.setPriority(serviceIdDesc.getPriority());
- // dependsOn
- desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn());
-
- return desc;
-
- }
-
- /**
- *
- * @param serviceIdDesc
- * @return
- */
- private AbstractServiceDesc transformServiceFactoryIdDescToRef(ServiceFactoryIdDesc serviceIdDesc) {
- ServiceFactoryDesc desc = ServicedescriptorsFactory.eINSTANCE.createServiceFactoryDesc();
- desc.setBundleID(serviceIdDesc.getBundleID());
- desc.setClassname(serviceIdDesc.getClassname());
- desc.setDescription(serviceIdDesc.getDescription());
- desc.setName(serviceIdDesc.getName());
- desc.setPriority(serviceIdDesc.getPriority());
- desc.setStartKind(transformStartKind(serviceIdDesc.getStartKind()));
- // dependsOn
- desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn());
-
- return desc;
- }
-
- /**
- * Compute the services available from this registry. This implies
- * resolving inheritances from extends.
- *
- * @param registryDesc
- * The descriptor for which services should be computed.
- *
- *
- */
- private void computeRegistryServices(RegistryDesc registryDesc) {
-
- // Reset the services
- List<AbstractServiceDesc> services = registryDesc.getServices();
- services.clear();
-
- // do the union of all services from sets
- // Do not check for double names (this is done in the Registry).
- for(ServiceSetDesc setDesc : registryDesc.getServiceSets()) {
-
- services.addAll(setDesc.getServices());
- }
-
- // Add services from extends
- // Add a services from a parent only if there is not a service with the same name
- // in the child
- for(RegistryDesc extendsDesc : registryDesc.getExtends()) {
-
- // Walk each service of the parent
- for(AbstractServiceDesc serviceDesc : extendsDesc.getServices()) {
-
- // Check if the service is already in the child
- if(!registryDesc.servicesContains(serviceDesc.getName())) {
- services.add(serviceDesc);
- }
- }
- }
-
- }
-
- /**
- * Compute the services available from the specified {@link ServiceSetDesc}. This reset and compute
- * the {@link ServiceSetDesc#getServices()} property.
- *
- * @param serviceSetDesc
- */
- private void computeServiceSetServices(ServiceSetDesc serviceSetDesc) {
-
- // Reset the services
- List<AbstractServiceDesc> services = serviceSetDesc.getServices();
- services.clear();
-
- // Add its own services
- services.addAll(serviceSetDesc.getOwnedServices());
-
- // Add services from extends
- // Add a services from an extends only if there is not a service with the same name
- // in the child
- for(ServiceSetDesc extendsDesc : serviceSetDesc.getExtends()) {
-
- // Walk each service of the parent
- for(AbstractServiceDesc serviceDesc : extendsDesc.getServices()) {
-
- // Check if the service is already in the child
- if(!serviceSetDesc.servicesContains(serviceDesc.getName())) {
- services.add(serviceDesc);
- }
- }
- }
-
- }
-
-
-
-}
+/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.List; + +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AliasDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.Descriptors; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.RegistryDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceFactoryDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceSetDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServicedescriptorsFactory; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.StartupKind; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceFactoryIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc; + + +/** + * A cache used to query the {@link IServiceDescriptorsWithIdProvider}. The cache return resolved descriptors, + * in the form of instance of the ServiceDescriptors model. + * + * @author cedric dumoulin + * + */ +public class DescriptorsCache { + + /** + * The cache of descriptors. + */ + protected Descriptors descriptorsCache; + + /** + * The provider used to query declarations. + */ + protected ServiceDescriptorsWithIdProviderCollection declaredDescriptorProvider; + + + + /** + * + * Constructor. + * + */ + public DescriptorsCache() { + declaredDescriptorProvider = new ServiceDescriptorsWithIdProviderCollection(); + descriptorsCache = ServicedescriptorsFactory.eINSTANCE.createDescriptors(); + } + + /** + * Add all the provided {@link IServiceDescriptorsWithIdProvider} to the list of providers to use. + * + * @param declaredDescriptorProviders + */ + public void addAll(IServiceDescriptorsWithIdProvider... declaredDescriptorProviders) { + + declaredDescriptorProvider.addAll(declaredDescriptorProviders); + descriptorsCache = ServicedescriptorsFactory.eINSTANCE.createDescriptors(); + + } + + /** + * Get the descriptor for the specified registry. + * The descriptor is built from the declarations found in {@link #declaredDescriptorProvider}. + * The descriptor is cached. This mean that subsequent calls for the same name will return the same + * result. <br/> + * If the registry is not found, throws an exception. + * + * @param registryName + * The name of the registry for which the descriptor is required. + * + * @return The registry descriptor + * @throws DeclarationException + * If an error occur while reading declarations. + * + */ + public RegistryDesc getRegistryDesc(String registryName) throws DeclarationException { + + // Try from cache + RegistryDesc desc = descriptorsCache.getRegistryDesc(registryName); + + if(desc != null) { + return desc; + } + + // Load from providers + // this can throw exception + RegistryIdDesc idDesc = declaredDescriptorProvider.getRegistryIdDesc(registryName); + + // Create a RegistryDesc from a RegistryIdDesc, and set minimal data + desc = ServicedescriptorsFactory.eINSTANCE.createRegistryDesc(); + desc.setName(idDesc.getName()); + desc.setIsUnique(idDesc.isUnique()); + desc.setDescription(idDesc.getDescription()); + + // Add it to the cache, so it can be found by other requests + descriptorsCache.getRegistries().add(desc); + + // Set the references + // serviceSet + for(String serviceSetId : idDesc.getSets()) { + desc.getServiceSets().add(getServiceSetDesc(serviceSetId)); + } + + // extends + for(String extendsId : idDesc.getExtends()) { + desc.getExtends().add(getRegistryDesc(extendsId)); + } + + // parents + for(String extendsId : idDesc.getParents()) { + desc.getParents().add(getRegistryDesc(extendsId)); + } + + + // Resolve inheritances + // need to compute services available for this registry + // Available services are those from all sets, and from extends. + computeRegistryServices(desc); + + + return desc; + } + + /** + * Get the {@link ServiceSetDesc} for the specified name. + * The descriptor is built from the declarations found in {@link #declaredDescriptorProvider}. + * The descriptor is cached. This mean that subsequent calls for the same name will return the same + * result. <br/> + * If the descriptor is not found, throws an exception. + * + * @param serviceSetId + * @return + * @throws DeclarationException + */ + public ServiceSetDesc getServiceSetDesc(String serviceSetId) throws DeclarationException { + // Try from cache + ServiceSetDesc desc = descriptorsCache.getServiceSetDesc(serviceSetId); + + if(desc != null) { + return desc; + } + + // Load from providers + // this can throw exception + ServiceSetIdDesc idDesc = declaredDescriptorProvider.getServiceSet(serviceSetId); + + // Create a RegistryDesc from a RegistryIdDesc, and set minimal data + desc = ServicedescriptorsFactory.eINSTANCE.createServiceSetDesc(); + desc.setName(idDesc.getName()); + desc.setDescription(idDesc.getDescription()); + + // Add it to the cache, so it can be found by other requests + descriptorsCache.getServiceSets().add(desc); + + // Set the references + // serviceSet + for(AbstractServiceIdDesc serviceIdDesc : idDesc.getServiceDescriptors()) { + desc.getOwnedServices().add(transformAbstractServiceIdDescToRef(serviceIdDesc)); + } + + // extends + for(String extendsId : idDesc.getExtends()) { + desc.getExtends().add(getServiceSetDesc(extendsId)); + } + + // Resolve inheritances + // need to compute services available for this set + // Available services are those from all extends. + computeServiceSetServices(desc); + + return desc; + } + + /** + * Transform {@link AncestorEvent} {@link AbstractServiceIdDesc} to an {@link AbstractServiceDesc}. + * + * @param serviceIdDesc + * @return + */ + private AbstractServiceDesc transformAbstractServiceIdDescToRef(AbstractServiceIdDesc serviceIdDesc) { + if(serviceIdDesc instanceof ServiceFactoryIdDesc) { + return transformServiceFactoryIdDescToRef((ServiceFactoryIdDesc)serviceIdDesc); + } else if(serviceIdDesc instanceof ServiceIdDesc) { + return transformServiceIdDescToRef((ServiceIdDesc)serviceIdDesc); + } else if(serviceIdDesc instanceof AliasIdDesc) { + return transformAliasIdDescToRef((AliasIdDesc)serviceIdDesc); + } else { + // Should never happen + throw new UnsupportedOperationException("Don't no how to transform '" + serviceIdDesc + "' to AbstractServiceDesc."); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * + * @param serviceIdDesc + * @return + */ + private AbstractServiceDesc transformServiceIdDescToRef(ServiceIdDesc serviceIdDesc) { + + ServiceDesc desc = ServicedescriptorsFactory.eINSTANCE.createServiceDesc(); + desc.setBundleID(serviceIdDesc.getBundleID()); + desc.setClassname(serviceIdDesc.getClassname()); + desc.setDescription(serviceIdDesc.getDescription()); + desc.setName(serviceIdDesc.getName()); + desc.setPriority(serviceIdDesc.getPriority()); + desc.setStartKind(transformStartKind(serviceIdDesc.getStartKind())); + // dependsOn + desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn()); + + return desc; + } + + /** + * + * @param startKind + * @return + */ + private StartupKind transformStartKind(org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind startKind) { + + switch(startKind) { + case STARTUP: + return StartupKind.STARTUP; + case LAZY: + return StartupKind.LAZY; + default: + return StartupKind.STARTUP; + } + } + + /** + * + * @param serviceIdDesc + * @return + */ + private AbstractServiceDesc transformAliasIdDescToRef(AliasIdDesc serviceIdDesc) { + AliasDesc desc = ServicedescriptorsFactory.eINSTANCE.createAliasDesc(); + desc.setBundleID(serviceIdDesc.getBundleID()); + desc.setDescription(serviceIdDesc.getDescription()); + desc.setName(serviceIdDesc.getName()); + desc.setPriority(serviceIdDesc.getPriority()); + // dependsOn + desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn()); + + return desc; + + } + + /** + * + * @param serviceIdDesc + * @return + */ + private AbstractServiceDesc transformServiceFactoryIdDescToRef(ServiceFactoryIdDesc serviceIdDesc) { + ServiceFactoryDesc desc = ServicedescriptorsFactory.eINSTANCE.createServiceFactoryDesc(); + desc.setBundleID(serviceIdDesc.getBundleID()); + desc.setClassname(serviceIdDesc.getClassname()); + desc.setDescription(serviceIdDesc.getDescription()); + desc.setName(serviceIdDesc.getName()); + desc.setPriority(serviceIdDesc.getPriority()); + desc.setStartKind(transformStartKind(serviceIdDesc.getStartKind())); + // dependsOn + desc.getDependsOnIds().addAll(serviceIdDesc.getDependsOn()); + + return desc; + } + + /** + * Compute the services available from this registry. This implies + * resolving inheritances from extends. + * + * @param registryDesc + * The descriptor for which services should be computed. + * + * + */ + private void computeRegistryServices(RegistryDesc registryDesc) { + + // Reset the services + List<AbstractServiceDesc> services = registryDesc.getServices(); + services.clear(); + + // do the union of all services from sets + // Do not check for double names (this is done in the Registry). + for(ServiceSetDesc setDesc : registryDesc.getServiceSets()) { + + services.addAll(setDesc.getServices()); + } + + // Add services from extends + // Add a services from a parent only if there is not a service with the same name + // in the child + for(RegistryDesc extendsDesc : registryDesc.getExtends()) { + + // Walk each service of the parent + for(AbstractServiceDesc serviceDesc : extendsDesc.getServices()) { + + // Check if the service is already in the child + if(!registryDesc.servicesContains(serviceDesc.getName())) { + services.add(serviceDesc); + } + } + } + + } + + /** + * Compute the services available from the specified {@link ServiceSetDesc}. This reset and compute + * the {@link ServiceSetDesc#getServices()} property. + * + * @param serviceSetDesc + */ + private void computeServiceSetServices(ServiceSetDesc serviceSetDesc) { + + // Reset the services + List<AbstractServiceDesc> services = serviceSetDesc.getServices(); + services.clear(); + + // Add its own services + services.addAll(serviceSetDesc.getOwnedServices()); + + // Add services from extends + // Add a services from an extends only if there is not a service with the same name + // in the child + for(ServiceSetDesc extendsDesc : serviceSetDesc.getExtends()) { + + // Walk each service of the parent + for(AbstractServiceDesc serviceDesc : extendsDesc.getServices()) { + + // Check if the service is already in the child + if(!serviceSetDesc.servicesContains(serviceDesc.getName())) { + services.add(serviceDesc); + } + } + } + + } + + + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServiceDescriptorsWithIdProvider.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServiceDescriptorsWithIdProvider.java index f5a34543a5d..d0d424c83c3 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServiceDescriptorsWithIdProvider.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServiceDescriptorsWithIdProvider.java @@ -1,534 +1,534 @@ -/*****************************************************************************
- * Copyright (c) 2012 Cedric Dumoulin.
- *
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.BadDeclarationException;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServicedescriptorswithidFactory;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind;
-
-
-/**
- * A declared service provider reading declaration from eclipse extensions (plugin.xml).
- *
- * @author cedric dumoulin
- *
- */
-public class ExtensionServiceDescriptorsWithIdProvider implements IServiceDescriptorsWithIdProvider {
-
- /** Namespace where to look for the extension points. */
- public static String extensionPointNamespace = "org.eclipse.papyrus.infra.core.serviceregistry";
-
- /** ID of the extension (schema filename) */
- public static final String SERVICE_EXTENSION_ID = "service";
-
- /** Extension point name inside the extension description **/
- public final static String REGISTRY_ELEMENT_NAME = "registry";
-
- /** Extension point name inside the extension description **/
- public final static String REGISTRY_EXTENDS_ELEMENT = "extendedRegistry";
-
- /** Extension point name inside the extension description **/
- public final static String REGISTRY_PARENT_ELEMENT = "parentRegistry";
-
- /** Extension point name inside the extension description **/
- public final static String REGISTRY_SERVICE_SETS_ELEMENT = "serviceSets";
-
- /** Extension point name inside the extension description **/
- public final static String SERVICE_ELEMENT_NAME = "service";
-
- /** servicesSet name **/
- public final static String SERVICE_SET_ELEMENT_NAME = "servicesSet";
-
- /** ServiceFactory Extension point **/
- public final static String SERVICE_FACTORY_ELEMENT_NAME = "serviceFactory";
-
- /** ServiceFactory Extension point **/
- public final static String ALIAS_ELEMENT_NAME = "alias";
-
- /** ServiceFactory Extension point **/
- public final static String ALIASED_SERVICE_ID_ATTRIBUTE = "aliasedServiceId";
-
- /** id attribute */
- private static final String ID_ATTRIBUTE = "id";
-
- /** constant for the attribute factoryClass **/
- public final static String CONTEXTCLASS_ATTRIBUTE = "contextClass";
-
- /** extension point propertyname */
- private final static String STARTKIND_PROPERTY = "startKind";
-
- /** name of the dependsOn element */
- private static final String DEPENDSON_ELEMENT_NAME = "dependsOn";
-
- /** */
- private static final String SERVICE_ID_ATTRIBUTE_NAME = "serviceId";
-
- /** */
- private static final String SERVICE_SET_EXTENDS_ELEMENT = "extendedServiceSet";
-
- /** */
- private static final String DESCRIPTION_ATTRIBUTE = "description";
-
- /** */
- private static final String IS_UNIQUE_ATTRIBUTE = "isUnique";
-
- /** */
- private static final String REGISTRY_ID_ATTRIBUTE = "registryId";
-
- /** */
- private static final String SERVICE_SET_ID_ATTRIBUTE = "serviceSetId";
-
- /**
- * Get the descriptor for the specified registry.
- * Return null if not found.
- * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getRegistryDescriptor(java.lang.String)
- *
- * @param registryName
- * @return The specified descriptor, or null if not found
- * @throws DeclarationException If there is more than one registry declared under the name.
- *
- */
- public RegistryIdDesc getRegistryDescriptor(String registryName) throws DeclarationException {
-
- // Reading data from plugins
- IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID);
-
- RegistryIdDesc registryIdDesc = null;
- boolean isRegistryFound = false;
- List<Throwable> warnings = new ArrayList<Throwable>();
-
- for( IConfigurationElement ele : configElements) {
-
- // SEarch for "registry"
- if(REGISTRY_ELEMENT_NAME.equals(ele.getName()) && registryName.equals(ele.getAttribute(ID_ATTRIBUTE))) {
- if(isRegistryFound) {
- // Already found: exception
- throw new DeclarationException("More than one registry declared under name '" + registryName + "'. "
- + " Declaration from '" + ele.getContributor().getName() + "' is disguarded.");
- }
- isRegistryFound = true;
- // read the set
- registryIdDesc = parseRegistryDescriptor( ele, warnings);
- }
-
- }
-
- if( warnings.size()>0) {
- throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings);
- }
- return registryIdDesc;
- }
-
- /**
- * Parse the RegistryDescriptor from the provided {@link IConfigurationElement}.
- *
- * @param ele The {@link IConfigurationElement} representing a RegistryDescriptor.
- * @param warnings A list used to record encountered warnings.
- * @return A registry descriptor.
- */
- private RegistryIdDesc parseRegistryDescriptor(IConfigurationElement ele, List<Throwable> warnings) {
- RegistryIdDesc registryIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createRegistryIdDesc();
-
- registryIdDesc.setName(ele.getAttribute(ID_ATTRIBUTE));
- registryIdDesc.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE));
- registryIdDesc.setIsUnique(Boolean.parseBoolean(ele.getAttribute(IS_UNIQUE_ATTRIBUTE)));
- parseRegistryExtends(ele, registryIdDesc, warnings);
- parseRegistryParent(ele, registryIdDesc, warnings);
- parseRegistryServiceSetId(ele, registryIdDesc, warnings);
-
- return registryIdDesc;
- }
-
- /**
- * Parse the declared sets of a Registry.
- *
- * @param ele
- * @param registryIdDesc
- * @param warnings
- */
- private void parseRegistryServiceSetId(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) {
- // Get all extends declarations
- IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_SERVICE_SETS_ELEMENT);
-
- // Process extends
- for(IConfigurationElement ele : extendDeclarations) {
-
- String extendedRegistry = ele.getAttribute(SERVICE_SET_ID_ATTRIBUTE);
- if(extendedRegistry == null || extendedRegistry.length() == 0) {
- warnings.add( new BadDeclarationException( ele.getName() + "/" + SERVICE_SET_ID_ATTRIBUTE + " should be set.") );
- }
- else {
- registryIdDesc.getSets().add(extendedRegistry);
- }
- }
- }
-
- /**
- * Parse the parent declaration of a Registry.
- * @param ele
- * @param registryIdDesc
- * @param warnings
- */
- private void parseRegistryParent(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) {
- // Get all extends declarations
- IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_PARENT_ELEMENT);
-
- // Process extends
- for(IConfigurationElement ele : extendDeclarations) {
-
- String extendedRegistry = ele.getAttribute(REGISTRY_ID_ATTRIBUTE);
- if(extendedRegistry == null || extendedRegistry.length() == 0) {
- warnings.add( new BadDeclarationException( ele.getName() + "/" + REGISTRY_ID_ATTRIBUTE + " should be set.") );
- }
- else {
- registryIdDesc.getParents().add(extendedRegistry);
- }
- }
- }
-
- /**
- * Parse the extends declaration of a Registry.
- * @param parentElement The element to parse. This element must represent a Registry.
- * @param registryIdDesc The registry into which the result is stored
- * @param warnings A list used to record encountered warnings.
- */
- private void parseRegistryExtends(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) {
- // Get all extends declarations
- IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_EXTENDS_ELEMENT);
-
- // Process extends
- for(IConfigurationElement ele : extendDeclarations) {
-
- String extendedRegistry = ele.getAttribute(REGISTRY_ID_ATTRIBUTE);
- if(extendedRegistry == null || extendedRegistry.length() == 0) {
- warnings.add( new BadDeclarationException( ele.getName() + "/" + REGISTRY_ID_ATTRIBUTE + " should be set.") );
- }
- else {
- registryIdDesc.getExtends().add(extendedRegistry);
- }
- }
- }
-
- /**
- * Get all fragments contributing to the declaration of the specified ServiceSetIdDesc.
- *
- * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getServiceSetFragments(java.lang.String)
- *
- * @param serviceSetName
- * @return
- * @throws DeclarationMultiException
- */
- public List<ServiceSetIdDesc> getServiceSetFragments(String serviceSetName) throws DeclarationException {
- // Reading data from plugins
- IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID);
-
- List<ServiceSetIdDesc> fragments = new ArrayList<ServiceSetIdDesc>();
- List<Throwable> warnings = new ArrayList<Throwable>();
-
- for( IConfigurationElement ele : configElements) {
-
- // SEarch for "registry"
- if(SERVICE_SET_ELEMENT_NAME.equals(ele.getName()) && serviceSetName.equals(ele.getAttribute(ID_ATTRIBUTE))) {
- ServiceSetIdDesc serviceSet = parseServiceSetDescriptor( ele, warnings);
- fragments.add(serviceSet);
- }
-
- }
-
- if( warnings.size()>0) {
- throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings);
- }
- return fragments;
- }
-
- /**
- * Get the requested ServiceSetIdDesc. If several fragmants are used to declare the ServiceSetIdDesc,
- * this fragments are concatenated in one ServiceSetIdDesc.
- *
- * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getServiceSetFragments(java.lang.String)
- *
- * @param serviceSetName
- * @return
- * @throws DeclarationMultiException
- */
- public ServiceSetIdDesc getServiceSet(String serviceSetName) throws DeclarationException {
- // Reading data from plugins
- IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID);
-
- ServiceSetIdDesc serviceSet = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc();
- List<Throwable> warnings = new ArrayList<Throwable>();
-
- for( IConfigurationElement ele : configElements) {
-
- // SEarch for "registry"
- if(SERVICE_SET_ELEMENT_NAME.equals(ele.getName()) && serviceSetName.equals(ele.getAttribute(ID_ATTRIBUTE))) {
- parseServiceSetDescriptor( ele, serviceSet, warnings);
- }
-
- }
-
- if( warnings.size()>0) {
- throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings);
- }
- return serviceSet;
- }
-
-
- /**
- * Add the ServiceSetIdDesc declarations found in the provided {@link IConfigurationElement}, and add
- * it to the provided {@link ServiceSetIdDesc}.
- * @param ele
- * @param warnings
- */
- private void parseServiceSetDescriptor(IConfigurationElement ele, ServiceSetIdDesc serviceSet, List<Throwable> warnings) {
-
- serviceSet.setName(ele.getAttribute(ID_ATTRIBUTE));
-// serviceSet.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE));
- parseServiceSetExtends(ele, serviceSet, warnings);
- parseServiceSetServices(ele, serviceSet.getServiceDescriptors(), warnings);
- }
-
- /**
- * Parse a {@link ServiceSetIdDesc}
- * @param ele
- * @param warnings
- * @return A newly created ServiceSetIdDesc initialized with the declaration found in ele.
- */
- private ServiceSetIdDesc parseServiceSetDescriptor(IConfigurationElement ele, List<Throwable> warnings) {
-
- ServiceSetIdDesc serviceSet = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc();
-
- parseServiceSetDescriptor(ele, serviceSet, warnings);
- return serviceSet;
- }
-
- /**
- * Parse the extended attribute of a ServiceSetIdDesc declaration.
- * @param parentElement
- * @param serviceSet
- * @param warnings
- */
- private void parseServiceSetExtends(IConfigurationElement parentElement, ServiceSetIdDesc serviceSet, List<Throwable> warnings) {
- // Get all extends declarations
- IConfigurationElement[] extendDeclarations = parentElement.getChildren(SERVICE_SET_EXTENDS_ELEMENT);
-
- // Process extends
- for(IConfigurationElement ele : extendDeclarations) {
-
- String extendedServiceSet = ele.getAttribute(SERVICE_SET_ID_ATTRIBUTE);
- if(extendedServiceSet == null || extendedServiceSet.length() == 0) {
- warnings.add( new BadDeclarationException( ele.getName() + "/" + SERVICE_SET_ID_ATTRIBUTE + " should be set.") );
- }
- else {
- serviceSet.getExtends().add(extendedServiceSet);
- }
- }
- }
-
- /**
- * Read services descriptors from the specified element configuration.
- * The element configuration should contains service elements declarations.
- * IdDescriptors are added to the specified list
- *
- * @param descriptors The list into which descriptors are added
- * @param parentElement The configuration element containing some service declarations.
- * @param serviceSet
- * @param exceptions List used to add encountered exceptions.
- */
- private void parseServiceSetServices( IConfigurationElement parentElement, List<AbstractServiceIdDesc> descriptors, List<Throwable> exceptions) {
-
- // Get all children
- IConfigurationElement[] configElements = parentElement.getChildren();
-
- // Process services
- for(IConfigurationElement ele : configElements) {
- AbstractServiceIdDesc desc;
- if(SERVICE_ELEMENT_NAME.equals(ele.getName())) {
- // Read a Service
- try {
- desc = parseServiceDescriptor(ele);
- // Add created desc
- descriptors.add(desc);
- } catch (DeclarationException e) {
- // record exceptions
- exceptions.add(e);
- }
- } else if(SERVICE_FACTORY_ELEMENT_NAME.equals(ele.getName())) {
- // Read a Service Factory
- try {
- desc = parseServiceDescriptor(ele);
- // Add created desc
- descriptors.add(desc);
- } catch (DeclarationException e) {
- // record exceptions
- exceptions.add(e);
- }
- } else if(ALIAS_ELEMENT_NAME.equals(ele.getName())) {
- try {
- desc = parseAliasDescriptor(ele);
- // Add created desc
- descriptors.add(desc);
- } catch (DeclarationException e) {
- // record exceptions
- exceptions.add(e);
- }
-
- }
-
- }
-
- }
-
- /**
- * Read an alias descriptor.
- * @param ele
- * @return
- */
- private AliasIdDesc parseAliasDescriptor(IConfigurationElement ele) throws DeclarationException {
-
- AliasIdDesc aliasIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createAliasIdDesc();
-
- // key
- String key = ele.getAttribute(ID_ATTRIBUTE);
- if(key == null || key.length() == 0) {
- throw new BadDeclarationException( ele.getName() + "/" + ID_ATTRIBUTE + " should be set for an alias.");
- }
- aliasIdDesc.setName(key);
-
- // key
- String aliasedService = ele.getAttribute(ALIASED_SERVICE_ID_ATTRIBUTE);
- if(key == null || key.length() == 0) {
- throw new BadDeclarationException( ele.getName() + "/" + ALIASED_SERVICE_ID_ATTRIBUTE + " should be set for an alias.");
- }
- aliasIdDesc.setAliasedService(aliasedService);
-
- aliasIdDesc.setPriority(parsePriorityAttribute(ele));
-
- aliasIdDesc.setBundleID(ele.getContributor().getName());
- aliasIdDesc.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE));
- parseServiceDependsOn( ele, aliasIdDesc.getDependsOn());
-
-
- return aliasIdDesc;
- }
-
- /**
- * Read descriptor values from provided element.
- *
- * @param ele
- * @return
- * @throws ServiceException
- */
- private ServiceIdDesc parseServiceDescriptor(IConfigurationElement ele) throws DeclarationException {
-
- ServiceIdDesc serviceIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createServiceIdDesc();
-
- // classname
- String serviceClassname = ele.getAttribute("classname");
- serviceIdDesc.setClassname(serviceClassname);
-
- // key
- String key = ele.getAttribute(ID_ATTRIBUTE);
- if(key == null || key.length() == 0) {
- key = serviceClassname;
- }
- serviceIdDesc.setName(key);
-
- serviceIdDesc.setStartKind(parseStartKindAttribute(ele));
- serviceIdDesc.setPriority(parsePriorityAttribute(ele));
- serviceIdDesc.setBundleID(ele.getContributor().getName());
- parseServiceDependsOn( ele, serviceIdDesc.getDependsOn());
-
- return serviceIdDesc;
- }
-
- /**
- * Parse the StartupKind attribute.
- * @param ele
- * @return
- * @throws DeclarationException
- */
- private StartupKind parseStartKindAttribute(IConfigurationElement ele) throws DeclarationException {
- // Service start kind
- StartupKind serviceStartKind = StartupKind.LAZY;
- String serviceStartKindStr = ele.getAttribute(STARTKIND_PROPERTY);
- if(serviceStartKindStr != null && serviceStartKindStr.length() > 0) {
- try {
- serviceStartKind = StartupKind.valueOf(serviceStartKindStr.toUpperCase());
- } catch (IllegalArgumentException e) {
- // Can't convert property
- throw new DeclarationException("Can't convert property " + STARTKIND_PROPERTY + "(plugin=" + ele.getContributor() + "declaringExtension=" + ele.getDeclaringExtension() + ")", e);
- }
- }
- return serviceStartKind;
- }
-
- /**
- * @param ele
- * @return
- */
- private int parsePriorityAttribute(IConfigurationElement ele) {
- // priority
- int priority = 1;
- String priorityStr = ele.getAttribute("priority");
- if(priorityStr != null && priorityStr.length() > 0) {
- try {
- priority = Integer.parseInt(priorityStr);
- } catch (NumberFormatException e) {
- }
- }
- return priority;
- }
-
- /**
- * Parse the dependsOn attribute of a service.
- * @param parentElement The {@link IConfigurationElement} containing a dependsOn attribute.
- * @param dependsOnServices Parsed value are added in this list.
- */
- private void parseServiceDependsOn(IConfigurationElement parentElement, List<String> dependsOnServices) {
- // Get children
- IConfigurationElement[] configElements = parentElement.getChildren(DEPENDSON_ELEMENT_NAME);
-
- for(IConfigurationElement ele : configElements) {
- String key = ele.getAttribute(SERVICE_ID_ATTRIBUTE_NAME);
- if(key != null && key.length() > 0) {
- dependsOnServices.add(key.trim());
- }
- }
- }
-
- /**
- * Get the Eclipse extensionRegistry.
- * This method can be overloaded by subclasses. This is useful for tests.
- *
- * @return
- */
- protected IExtensionRegistry getExtensionRegistry() {
- return Platform.getExtensionRegistry();
- }
-
-
-}
+/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.BadDeclarationException; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServicedescriptorswithidFactory; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind; + + +/** + * A declared service provider reading declaration from eclipse extensions (plugin.xml). + * + * @author cedric dumoulin + * + */ +public class ExtensionServiceDescriptorsWithIdProvider implements IServiceDescriptorsWithIdProvider { + + /** Namespace where to look for the extension points. */ + public static String extensionPointNamespace = "org.eclipse.papyrus.infra.core.serviceregistry"; + + /** ID of the extension (schema filename) */ + public static final String SERVICE_EXTENSION_ID = "service"; + + /** Extension point name inside the extension description **/ + public final static String REGISTRY_ELEMENT_NAME = "registry"; + + /** Extension point name inside the extension description **/ + public final static String REGISTRY_EXTENDS_ELEMENT = "extendedRegistry"; + + /** Extension point name inside the extension description **/ + public final static String REGISTRY_PARENT_ELEMENT = "parentRegistry"; + + /** Extension point name inside the extension description **/ + public final static String REGISTRY_SERVICE_SETS_ELEMENT = "serviceSets"; + + /** Extension point name inside the extension description **/ + public final static String SERVICE_ELEMENT_NAME = "service"; + + /** servicesSet name **/ + public final static String SERVICE_SET_ELEMENT_NAME = "servicesSet"; + + /** ServiceFactory Extension point **/ + public final static String SERVICE_FACTORY_ELEMENT_NAME = "serviceFactory"; + + /** ServiceFactory Extension point **/ + public final static String ALIAS_ELEMENT_NAME = "alias"; + + /** ServiceFactory Extension point **/ + public final static String ALIASED_SERVICE_ID_ATTRIBUTE = "aliasedServiceId"; + + /** id attribute */ + private static final String ID_ATTRIBUTE = "id"; + + /** constant for the attribute factoryClass **/ + public final static String CONTEXTCLASS_ATTRIBUTE = "contextClass"; + + /** extension point propertyname */ + private final static String STARTKIND_PROPERTY = "startKind"; + + /** name of the dependsOn element */ + private static final String DEPENDSON_ELEMENT_NAME = "dependsOn"; + + /** */ + private static final String SERVICE_ID_ATTRIBUTE_NAME = "serviceId"; + + /** */ + private static final String SERVICE_SET_EXTENDS_ELEMENT = "extendedServiceSet"; + + /** */ + private static final String DESCRIPTION_ATTRIBUTE = "description"; + + /** */ + private static final String IS_UNIQUE_ATTRIBUTE = "isUnique"; + + /** */ + private static final String REGISTRY_ID_ATTRIBUTE = "registryId"; + + /** */ + private static final String SERVICE_SET_ID_ATTRIBUTE = "serviceSetId"; + + /** + * Get the descriptor for the specified registry. + * Return null if not found. + * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getRegistryDescriptor(java.lang.String) + * + * @param registryName + * @return The specified descriptor, or null if not found + * @throws DeclarationException If there is more than one registry declared under the name. + * + */ + public RegistryIdDesc getRegistryDescriptor(String registryName) throws DeclarationException { + + // Reading data from plugins + IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID); + + RegistryIdDesc registryIdDesc = null; + boolean isRegistryFound = false; + List<Throwable> warnings = new ArrayList<Throwable>(); + + for( IConfigurationElement ele : configElements) { + + // SEarch for "registry" + if(REGISTRY_ELEMENT_NAME.equals(ele.getName()) && registryName.equals(ele.getAttribute(ID_ATTRIBUTE))) { + if(isRegistryFound) { + // Already found: exception + throw new DeclarationException("More than one registry declared under name '" + registryName + "'. " //$NON-NLS-1$ //$NON-NLS-2$ + + " Declaration from '" + ele.getContributor().getName() + "' is disguarded."); //$NON-NLS-1$ //$NON-NLS-2$ + } + isRegistryFound = true; + // read the set + registryIdDesc = parseRegistryDescriptor( ele, warnings); + } + + } + + if( warnings.size()>0) { + throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings); //$NON-NLS-1$ + } + return registryIdDesc; + } + + /** + * Parse the RegistryDescriptor from the provided {@link IConfigurationElement}. + * + * @param ele The {@link IConfigurationElement} representing a RegistryDescriptor. + * @param warnings A list used to record encountered warnings. + * @return A registry descriptor. + */ + private RegistryIdDesc parseRegistryDescriptor(IConfigurationElement ele, List<Throwable> warnings) { + RegistryIdDesc registryIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createRegistryIdDesc(); + + registryIdDesc.setName(ele.getAttribute(ID_ATTRIBUTE)); + registryIdDesc.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE)); + registryIdDesc.setIsUnique(Boolean.parseBoolean(ele.getAttribute(IS_UNIQUE_ATTRIBUTE))); + parseRegistryExtends(ele, registryIdDesc, warnings); + parseRegistryParent(ele, registryIdDesc, warnings); + parseRegistryServiceSetId(ele, registryIdDesc, warnings); + + return registryIdDesc; + } + + /** + * Parse the declared sets of a Registry. + * + * @param ele + * @param registryIdDesc + * @param warnings + */ + private void parseRegistryServiceSetId(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) { + // Get all extends declarations + IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_SERVICE_SETS_ELEMENT); + + // Process extends + for(IConfigurationElement ele : extendDeclarations) { + + String extendedRegistry = ele.getAttribute(SERVICE_SET_ID_ATTRIBUTE); + if(extendedRegistry == null || extendedRegistry.length() == 0) { + warnings.add( new BadDeclarationException( ele.getName() + "/" + SERVICE_SET_ID_ATTRIBUTE + " should be set.") ); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + registryIdDesc.getSets().add(extendedRegistry); + } + } + } + + /** + * Parse the parent declaration of a Registry. + * @param ele + * @param registryIdDesc + * @param warnings + */ + private void parseRegistryParent(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) { + // Get all extends declarations + IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_PARENT_ELEMENT); + + // Process extends + for(IConfigurationElement ele : extendDeclarations) { + + String extendedRegistry = ele.getAttribute(REGISTRY_ID_ATTRIBUTE); + if(extendedRegistry == null || extendedRegistry.length() == 0) { + warnings.add( new BadDeclarationException( ele.getName() + "/" + REGISTRY_ID_ATTRIBUTE + " should be set.") ); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + registryIdDesc.getParents().add(extendedRegistry); + } + } + } + + /** + * Parse the extends declaration of a Registry. + * @param parentElement The element to parse. This element must represent a Registry. + * @param registryIdDesc The registry into which the result is stored + * @param warnings A list used to record encountered warnings. + */ + private void parseRegistryExtends(IConfigurationElement parentElement, RegistryIdDesc registryIdDesc, List<Throwable> warnings) { + // Get all extends declarations + IConfigurationElement[] extendDeclarations = parentElement.getChildren(REGISTRY_EXTENDS_ELEMENT); + + // Process extends + for(IConfigurationElement ele : extendDeclarations) { + + String extendedRegistry = ele.getAttribute(REGISTRY_ID_ATTRIBUTE); + if(extendedRegistry == null || extendedRegistry.length() == 0) { + warnings.add( new BadDeclarationException( ele.getName() + "/" + REGISTRY_ID_ATTRIBUTE + " should be set.") ); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + registryIdDesc.getExtends().add(extendedRegistry); + } + } + } + + /** + * Get all fragments contributing to the declaration of the specified ServiceSetIdDesc. + * + * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getServiceSetFragments(java.lang.String) + * + * @param serviceSetName + * @return + * @throws DeclarationMultiException + */ + public List<ServiceSetIdDesc> getServiceSetFragments(String serviceSetName) throws DeclarationException { + // Reading data from plugins + IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID); + + List<ServiceSetIdDesc> fragments = new ArrayList<ServiceSetIdDesc>(); + List<Throwable> warnings = new ArrayList<Throwable>(); + + for( IConfigurationElement ele : configElements) { + + // SEarch for "registry" + if(SERVICE_SET_ELEMENT_NAME.equals(ele.getName()) && serviceSetName.equals(ele.getAttribute(ID_ATTRIBUTE))) { + ServiceSetIdDesc serviceSet = parseServiceSetDescriptor( ele, warnings); + fragments.add(serviceSet); + } + + } + + if( warnings.size()>0) { + throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings); //$NON-NLS-1$ + } + return fragments; + } + + /** + * Get the requested ServiceSetIdDesc. If several fragmants are used to declare the ServiceSetIdDesc, + * this fragments are concatenated in one ServiceSetIdDesc. + * + * @see org.eclipse.papyrus.infra.core.serviceregistry.IServiceDescriptorsWithIdProvider#getServiceSetFragments(java.lang.String) + * + * @param serviceSetName + * @return + * @throws DeclarationMultiException + */ + public ServiceSetIdDesc getServiceSet(String serviceSetName) throws DeclarationException { + // Reading data from plugins + IConfigurationElement[] configElements = getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID); + + ServiceSetIdDesc serviceSet = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc(); + List<Throwable> warnings = new ArrayList<Throwable>(); + + for( IConfigurationElement ele : configElements) { + + // SEarch for "registry" + if(SERVICE_SET_ELEMENT_NAME.equals(ele.getName()) && serviceSetName.equals(ele.getAttribute(ID_ATTRIBUTE))) { + parseServiceSetDescriptor( ele, serviceSet, warnings); + } + + } + + if( warnings.size()>0) { + throw new DeclarationMultiException("Problems encountered during extensions processing.", warnings); //$NON-NLS-1$ + } + return serviceSet; + } + + + /** + * Add the ServiceSetIdDesc declarations found in the provided {@link IConfigurationElement}, and add + * it to the provided {@link ServiceSetIdDesc}. + * @param ele + * @param warnings + */ + private void parseServiceSetDescriptor(IConfigurationElement ele, ServiceSetIdDesc serviceSet, List<Throwable> warnings) { + + serviceSet.setName(ele.getAttribute(ID_ATTRIBUTE)); +// serviceSet.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE)); + parseServiceSetExtends(ele, serviceSet, warnings); + parseServiceSetServices(ele, serviceSet.getServiceDescriptors(), warnings); + } + + /** + * Parse a {@link ServiceSetIdDesc} + * @param ele + * @param warnings + * @return A newly created ServiceSetIdDesc initialized with the declaration found in ele. + */ + private ServiceSetIdDesc parseServiceSetDescriptor(IConfigurationElement ele, List<Throwable> warnings) { + + ServiceSetIdDesc serviceSet = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc(); + + parseServiceSetDescriptor(ele, serviceSet, warnings); + return serviceSet; + } + + /** + * Parse the extended attribute of a ServiceSetIdDesc declaration. + * @param parentElement + * @param serviceSet + * @param warnings + */ + private void parseServiceSetExtends(IConfigurationElement parentElement, ServiceSetIdDesc serviceSet, List<Throwable> warnings) { + // Get all extends declarations + IConfigurationElement[] extendDeclarations = parentElement.getChildren(SERVICE_SET_EXTENDS_ELEMENT); + + // Process extends + for(IConfigurationElement ele : extendDeclarations) { + + String extendedServiceSet = ele.getAttribute(SERVICE_SET_ID_ATTRIBUTE); + if(extendedServiceSet == null || extendedServiceSet.length() == 0) { + warnings.add( new BadDeclarationException( ele.getName() + "/" + SERVICE_SET_ID_ATTRIBUTE + " should be set.") ); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + serviceSet.getExtends().add(extendedServiceSet); + } + } + } + + /** + * Read services descriptors from the specified element configuration. + * The element configuration should contains service elements declarations. + * IdDescriptors are added to the specified list + * + * @param descriptors The list into which descriptors are added + * @param parentElement The configuration element containing some service declarations. + * @param serviceSet + * @param exceptions List used to add encountered exceptions. + */ + private void parseServiceSetServices( IConfigurationElement parentElement, List<AbstractServiceIdDesc> descriptors, List<Throwable> exceptions) { + + // Get all children + IConfigurationElement[] configElements = parentElement.getChildren(); + + // Process services + for(IConfigurationElement ele : configElements) { + AbstractServiceIdDesc desc; + if(SERVICE_ELEMENT_NAME.equals(ele.getName())) { + // Read a Service + try { + desc = parseServiceDescriptor(ele); + // Add created desc + descriptors.add(desc); + } catch (DeclarationException e) { + // record exceptions + exceptions.add(e); + } + } else if(SERVICE_FACTORY_ELEMENT_NAME.equals(ele.getName())) { + // Read a Service Factory + try { + desc = parseServiceDescriptor(ele); + // Add created desc + descriptors.add(desc); + } catch (DeclarationException e) { + // record exceptions + exceptions.add(e); + } + } else if(ALIAS_ELEMENT_NAME.equals(ele.getName())) { + try { + desc = parseAliasDescriptor(ele); + // Add created desc + descriptors.add(desc); + } catch (DeclarationException e) { + // record exceptions + exceptions.add(e); + } + + } + + } + + } + + /** + * Read an alias descriptor. + * @param ele + * @return + */ + private AliasIdDesc parseAliasDescriptor(IConfigurationElement ele) throws DeclarationException { + + AliasIdDesc aliasIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createAliasIdDesc(); + + // key + String key = ele.getAttribute(ID_ATTRIBUTE); + if(key == null || key.length() == 0) { + throw new BadDeclarationException( ele.getName() + "/" + ID_ATTRIBUTE + " should be set for an alias."); //$NON-NLS-1$ //$NON-NLS-2$ + } + aliasIdDesc.setName(key); + + // key + String aliasedService = ele.getAttribute(ALIASED_SERVICE_ID_ATTRIBUTE); + if(key == null || key.length() == 0) { + throw new BadDeclarationException( ele.getName() + "/" + ALIASED_SERVICE_ID_ATTRIBUTE + " should be set for an alias."); //$NON-NLS-1$ //$NON-NLS-2$ + } + aliasIdDesc.setAliasedService(aliasedService); + + aliasIdDesc.setPriority(parsePriorityAttribute(ele)); + + aliasIdDesc.setBundleID(ele.getContributor().getName()); + aliasIdDesc.setDescription(ele.getAttribute(DESCRIPTION_ATTRIBUTE)); + parseServiceDependsOn( ele, aliasIdDesc.getDependsOn()); + + + return aliasIdDesc; + } + + /** + * Read descriptor values from provided element. + * + * @param ele + * @return + * @throws ServiceException + */ + private ServiceIdDesc parseServiceDescriptor(IConfigurationElement ele) throws DeclarationException { + + ServiceIdDesc serviceIdDesc = ServicedescriptorswithidFactory.eINSTANCE.createServiceIdDesc(); + + // classname + String serviceClassname = ele.getAttribute("classname"); + serviceIdDesc.setClassname(serviceClassname); + + // key + String key = ele.getAttribute(ID_ATTRIBUTE); + if(key == null || key.length() == 0) { + key = serviceClassname; + } + serviceIdDesc.setName(key); + + serviceIdDesc.setStartKind(parseStartKindAttribute(ele)); + serviceIdDesc.setPriority(parsePriorityAttribute(ele)); + serviceIdDesc.setBundleID(ele.getContributor().getName()); + parseServiceDependsOn( ele, serviceIdDesc.getDependsOn()); + + return serviceIdDesc; + } + + /** + * Parse the StartupKind attribute. + * @param ele + * @return + * @throws DeclarationException + */ + private StartupKind parseStartKindAttribute(IConfigurationElement ele) throws DeclarationException { + // Service start kind + StartupKind serviceStartKind = StartupKind.LAZY; + String serviceStartKindStr = ele.getAttribute(STARTKIND_PROPERTY); + if(serviceStartKindStr != null && serviceStartKindStr.length() > 0) { + try { + serviceStartKind = StartupKind.valueOf(serviceStartKindStr.toUpperCase()); + } catch (IllegalArgumentException e) { + // Can't convert property + throw new DeclarationException("Can't convert property " + STARTKIND_PROPERTY + "(plugin=" + ele.getContributor() + "declaringExtension=" + ele.getDeclaringExtension() + ")", e); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + } + return serviceStartKind; + } + + /** + * @param ele + * @return + */ + private int parsePriorityAttribute(IConfigurationElement ele) { + // priority + int priority = 1; + String priorityStr = ele.getAttribute("priority"); + if(priorityStr != null && priorityStr.length() > 0) { + try { + priority = Integer.parseInt(priorityStr); + } catch (NumberFormatException e) { + } + } + return priority; + } + + /** + * Parse the dependsOn attribute of a service. + * @param parentElement The {@link IConfigurationElement} containing a dependsOn attribute. + * @param dependsOnServices Parsed value are added in this list. + */ + private void parseServiceDependsOn(IConfigurationElement parentElement, List<String> dependsOnServices) { + // Get children + IConfigurationElement[] configElements = parentElement.getChildren(DEPENDSON_ELEMENT_NAME); + + for(IConfigurationElement ele : configElements) { + String key = ele.getAttribute(SERVICE_ID_ATTRIBUTE_NAME); + if(key != null && key.length() > 0) { + dependsOnServices.add(key.trim()); + } + } + } + + /** + * Get the Eclipse extensionRegistry. + * This method can be overloaded by subclasses. This is useful for tests. + * + * @return + */ + protected IExtensionRegistry getExtensionRegistry() { + return Platform.getExtensionRegistry(); + } + + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServicesRegistry.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServicesRegistry.java index 791b2f10406..905ca5e8b9a 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServicesRegistry.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ExtensionServicesRegistry.java @@ -1,196 +1,206 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.papyrus.infra.core.serviceregistry.ServiceDescriptor.ServiceTypeKind;
-
-/**
- * ServiceRegistry reading and registering services declared in Eclipse
- * Extensions.
- *
- * @author dumoulin
- *
- */
-public class ExtensionServicesRegistry extends ServicesRegistry {
-
- /** ID of the extension (schema filename) */
- public static final String SERVICE_EXTENSION_ID = "service";
-
- /** Namespace where to look for the extension points. */
- protected String extensionPointNamespace;
-
- /** Extension point name inside the extension description **/
- public final static String SERVICE_EXTENSIONPOINT = "service";
-
- /** ServiceFactory Extension point **/
- public final static String SERVICE_FACTORY_ELEMENT_NAME = "serviceFactory";
-
- /** constant for the attribute factoryClass **/
- public final static String CONTEXTCLASS_ATTRIBUTE = "contextClass";
-
- /** extension point propertyname */
- private final static String STARTKIND_PROPERTY = "startKind";
-
- /** name of the dependsOn element */
- private static final String DEPENDSON_ELEMENT_NAME = "dependsOn";
-
- /** name of the key attribute inside the DEPENDSON element */
- private static final String DEPENDSON_KEY_ATTRIBUTE_NAME = "serviceKeyRef";
-
- /**
- * Constructor.
- *
- * @throws Exception
- */
- public ExtensionServicesRegistry(String extensionPointNamespace) throws ServiceException {
- this.extensionPointNamespace = extensionPointNamespace;
- registerDeclaredExtensions();
- }
-
- /**
- * Register the services declared in Eclipse Extension.
- *
- * @throws Exception
- */
- private void registerDeclaredExtensions() throws ServiceException {
-
- List<ServiceDescriptor> descriptors = new ArrayList<ServiceDescriptor>();
- List<ServiceException> exceptions = null;
-
- // Reading data from plugins
- IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID);
-
- for(IConfigurationElement ele : configElements) {
- ServiceDescriptor desc;
- if(SERVICE_EXTENSIONPOINT.equals(ele.getName())) {
- // Read a Service
- try {
- desc = readServiceDescriptor(ele);
- desc.setServiceTypeKind(ServiceTypeKind.service);
- // Add created desc
- descriptors.add(desc);
- } catch (ServiceException e) {
- // record exceptions
- if(exceptions == null)
- exceptions = new ArrayList<ServiceException>();
- exceptions.add(e);
- }
- } else if(SERVICE_FACTORY_ELEMENT_NAME.equals(ele.getName())) {
- // Read a Service Factory
- try {
- desc = readServiceDescriptor(ele);
- desc.setServiceTypeKind(ServiceTypeKind.serviceFactory);
- // Add created desc
- descriptors.add(desc);
- } catch (ServiceException e) {
- // record exceptions
- if(exceptions == null)
- exceptions = new ArrayList<ServiceException>();
- exceptions.add(e);
- }
- }
- }
-
- // Add found descriptors
- for(ServiceDescriptor desc : descriptors) {
- add(desc);
- }
-
- // Throw exceptions if pb encountered
- if(exceptions != null) {
- if(exceptions.size() == 1)
- throw exceptions.get(0);
- else
- throw new ServiceException("Somme services are not started (first is shown)", exceptions.get(0));
-
- }
-
- }
-
- /**
- * Read descriptor values from provided element.
- *
- * @param ele
- * @return
- * @throws ServiceException
- */
- private ServiceDescriptor readServiceDescriptor(IConfigurationElement ele) throws ServiceException {
-
- // classname
- String serviceClassname = ele.getAttribute("classname");
-
- // key
- String key = ele.getAttribute("id");
- if(key == null || key.length() == 0) {
- key = serviceClassname;
- }
-
- // Service start kind
- ServiceStartKind serviceStartKind = ServiceStartKind.LAZY;
- String serviceStartKindStr = ele.getAttribute(STARTKIND_PROPERTY);
- if(serviceStartKindStr != null && serviceStartKindStr.length() > 0) {
- try {
- serviceStartKind = ServiceStartKind.valueOf(serviceStartKindStr.toUpperCase());
- } catch (IllegalArgumentException e) {
- // Can't convert property
- throw new ServiceException("Can't convert property " + STARTKIND_PROPERTY + "(plugin=" + ele.getContributor() + "declaringExtension=" + ele.getDeclaringExtension() + ")", e);
- }
- }
-
- // priority
- int priority = 1;
- String priorityStr = ele.getAttribute("priority");
- if(priorityStr != null && priorityStr.length() > 0) {
- try {
- priority = Integer.parseInt(priorityStr);
- } catch (NumberFormatException e) {
- }
- }
-
- // Read dependsOn keys
- List<String> keys = getDependsOn(ele);
-
- // Create descriptor
- ServiceDescriptor desc = new ServiceDescriptor(key, serviceClassname, serviceStartKind, priority);
- desc.setClassBundleID(ele.getContributor().getName());
-
- if(keys.size() > 0)
- desc.setRequiredServiceKeys(keys);
-
- return desc;
- }
-
- /**
- * Add dependsOn keys.
- *
- * @param parentElement
- * @param model
- */
- private List<String> getDependsOn(IConfigurationElement parentElement) {
-
- List<String> keys = new ArrayList<String>();
-
- // Get children
- IConfigurationElement[] configElements = parentElement.getChildren(DEPENDSON_ELEMENT_NAME);
-
- for(IConfigurationElement ele : configElements) {
- String key = ele.getAttribute(DEPENDSON_KEY_ATTRIBUTE_NAME);
- if(key != null && key.length() > 0) {
- keys.add(key.trim());
- }
- }
-
- if(keys.size() == 0)
- return Collections.emptyList();
-
- return keys;
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.papyrus.infra.core.serviceregistry.ServiceDescriptor.ServiceTypeKind; + +/** + * ServiceRegistry reading and registering services declared in Eclipse + * Extensions. + * + * @author dumoulin + * + */ +public class ExtensionServicesRegistry extends ServicesRegistry { + + /** ID of the extension (schema filename) */ + public static final String SERVICE_EXTENSION_ID = "service"; + + /** Namespace where to look for the extension points. */ + protected String extensionPointNamespace; + + /** Extension point name inside the extension description **/ + public final static String SERVICE_EXTENSIONPOINT = "service"; + + /** ServiceFactory Extension point **/ + public final static String SERVICE_FACTORY_ELEMENT_NAME = "serviceFactory"; + + /** constant for the attribute factoryClass **/ + public final static String CONTEXTCLASS_ATTRIBUTE = "contextClass"; + + /** extension point propertyname */ + private final static String STARTKIND_PROPERTY = "startKind"; + + /** name of the dependsOn element */ + private static final String DEPENDSON_ELEMENT_NAME = "dependsOn"; + + /** name of the key attribute inside the DEPENDSON element */ + private static final String DEPENDSON_KEY_ATTRIBUTE_NAME = "serviceKeyRef"; + + /** + * Constructor. + * + * @throws Exception + */ + public ExtensionServicesRegistry(String extensionPointNamespace) throws ServiceException { + this.extensionPointNamespace = extensionPointNamespace; + registerDeclaredExtensions(); + } + + /** + * Register the services declared in Eclipse Extension. + * + * @throws Exception + */ + private void registerDeclaredExtensions() throws ServiceException { + + List<ServiceDescriptor> descriptors = new ArrayList<ServiceDescriptor>(); + List<ServiceException> exceptions = null; + + // Reading data from plugins + IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID); + + for(IConfigurationElement ele : configElements) { + ServiceDescriptor desc; + if(SERVICE_EXTENSIONPOINT.equals(ele.getName())) { + // Read a Service + try { + desc = readServiceDescriptor(ele); + desc.setServiceTypeKind(ServiceTypeKind.service); + // Add created desc + descriptors.add(desc); + } catch (ServiceException e) { + // record exceptions + if(exceptions == null) + exceptions = new ArrayList<ServiceException>(); + exceptions.add(e); + } + } else if(SERVICE_FACTORY_ELEMENT_NAME.equals(ele.getName())) { + // Read a Service Factory + try { + desc = readServiceDescriptor(ele); + desc.setServiceTypeKind(ServiceTypeKind.serviceFactory); + // Add created desc + descriptors.add(desc); + } catch (ServiceException e) { + // record exceptions + if(exceptions == null) + exceptions = new ArrayList<ServiceException>(); + exceptions.add(e); + } + } + } + + // Add found descriptors + for(ServiceDescriptor desc : descriptors) { + add(desc); + } + + // Throw exceptions if pb encountered + if(exceptions != null) { + if(exceptions.size() == 1) + throw exceptions.get(0); + else + throw new ServiceException("Somme services are not started (first is shown)", exceptions.get(0)); //$NON-NLS-1$ + + } + + } + + /** + * Read descriptor values from provided element. + * + * @param ele + * @return + * @throws ServiceException + */ + private ServiceDescriptor readServiceDescriptor(IConfigurationElement ele) throws ServiceException { + + // classname + String serviceClassname = ele.getAttribute("classname"); + + // key + String key = ele.getAttribute("id"); + if(key == null || key.length() == 0) { + key = serviceClassname; + } + + // Service start kind + ServiceStartKind serviceStartKind = ServiceStartKind.LAZY; + String serviceStartKindStr = ele.getAttribute(STARTKIND_PROPERTY); + if(serviceStartKindStr != null && serviceStartKindStr.length() > 0) { + try { + serviceStartKind = ServiceStartKind.valueOf(serviceStartKindStr.toUpperCase()); + } catch (IllegalArgumentException e) { + // Can't convert property + throw new ServiceException("Can't convert property " + STARTKIND_PROPERTY + "(plugin=" + ele.getContributor() + "declaringExtension=" + ele.getDeclaringExtension() + ")", e); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + // priority + int priority = 1; + String priorityStr = ele.getAttribute("priority"); + if(priorityStr != null && priorityStr.length() > 0) { + try { + priority = Integer.parseInt(priorityStr); + } catch (NumberFormatException e) { + } + } + + // Read dependsOn keys + List<String> keys = getDependsOn(ele); + + // Create descriptor + ServiceDescriptor desc = new ServiceDescriptor(key, serviceClassname, serviceStartKind, priority); + desc.setClassBundleID(ele.getContributor().getName()); + + if(keys.size() > 0) + desc.setRequiredServiceKeys(keys); + + return desc; + } + + /** + * Add dependsOn keys. + * + * @param parentElement + * @param model + */ + private List<String> getDependsOn(IConfigurationElement parentElement) { + + List<String> keys = new ArrayList<String>(); + + // Get children + IConfigurationElement[] configElements = parentElement.getChildren(DEPENDSON_ELEMENT_NAME); + + for(IConfigurationElement ele : configElements) { + String key = ele.getAttribute(DEPENDSON_KEY_ATTRIBUTE_NAME); + if(key != null && key.length() > 0) { + keys.add(key.trim()); + } + } + + if(keys.size() == 0) + return Collections.emptyList(); + + return keys; + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IService.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IService.java index b9a37356be2..ac10425a7e2 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IService.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IService.java @@ -1,42 +1,52 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * An Service that can be registered in the {@link ServicesRegistry}. A service
- * is a singleton available throw the registry. A service can be shared across
- * editors. <br>
- * The life cycle is as follow:
- * <ul>
- * <li>service creation</li>
- * <li>{@link #init(ServicesRegistry)} - Other service can be retrieved from the registry, but are not started yet.</li>
- * <li>{@link #startService()} - service is started.</li>
- * <li>Service can be used</li>
- * <li>{@link #disposeService()} - service is disposed and should not be used anymore.</li>
- * </ul>
- *
- * @author cedric dumoulin
- *
- */
-public interface IService {
-
- /**
- * Init the service and set its associated Registry. The registry can be
- * used to retrieve other services.
- *
- * @param servicesRegistry
- */
- public void init(ServicesRegistry servicesRegistry) throws ServiceException;
-
- /**
- * Start the service. This method is called when the service is started.
- */
- public void startService() throws ServiceException;
-
- /**
- * Dispose the service.
- */
- public void disposeService() throws ServiceException;
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * An Service that can be registered in the {@link ServicesRegistry}. A service + * is a singleton available throw the registry. A service can be shared across + * editors. <br> + * The life cycle is as follow: + * <ul> + * <li>service creation</li> + * <li>{@link #init(ServicesRegistry)} - Other service can be retrieved from the registry, but are not started yet.</li> + * <li>{@link #startService()} - service is started.</li> + * <li>Service can be used</li> + * <li>{@link #disposeService()} - service is disposed and should not be used anymore.</li> + * </ul> + * + * @author cedric dumoulin + * + */ +public interface IService { + + /** + * Init the service and set its associated Registry. The registry can be + * used to retrieve other services. + * + * @param servicesRegistry + */ + public void init(ServicesRegistry servicesRegistry) throws ServiceException; + + /** + * Start the service. This method is called when the service is started. + */ + public void startService() throws ServiceException; + + /** + * Dispose the service. + */ + public void disposeService() throws ServiceException; + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IServiceFactory.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IServiceFactory.java index 37e52896273..a666b85b9f5 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IServiceFactory.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/IServiceFactory.java @@ -1,28 +1,38 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * A factory creating a Service that can be registered in the {@link ServicesRegistry}.
- *
- * A service is a singleton available throw the registry. A service can be
- * shared across editors. The service lifecycle events (init, start and dispose)
- * are sent to the factory. The factory is responsible to forward them to the
- * real service.
- *
- * @author dumoulin
- *
- */
-public interface IServiceFactory extends IService {
-
- /**
- * Create the instance of the service that will be returned by {@link ServicesRegistry#getService(Class)}.
- *
- * @return The instance of the service.
- * @throws ServiceException
- * If an error occurs during the operation.
- */
- public Object createServiceInstance() throws ServiceException;
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * A factory creating a Service that can be registered in the {@link ServicesRegistry}. + * + * A service is a singleton available throw the registry. A service can be + * shared across editors. The service lifecycle events (init, start and dispose) + * are sent to the factory. The factory is responsible to forward them to the + * real service. + * + * @author dumoulin + * + */ +public interface IServiceFactory extends IService { + + /** + * Create the instance of the service that will be returned by {@link ServicesRegistry#getService(Class)}. + * + * @return The instance of the service. + * @throws ServiceException + * If an error occurs during the operation. + */ + public Object createServiceInstance() throws ServiceException; + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptor.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptor.java index e2b01627dcd..0d5f980191c 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptor.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptor.java @@ -1,301 +1,311 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Descriptor of a service. This descriptor describe a service.
- *
- * @author cedirc dumoulin
- *
- */
-public class ServiceDescriptor {
-
- /**
- * Possible kind for service types.
- *
- */
- public enum ServiceTypeKind {
- service, serviceFactory, pojo, alias
- }
-
- /** Classname of the service. USed to start the service */
- private String serviceClassname;
-
- /** Kind of start for this service */
- private ServiceStartKind serviceStartKind;
-
- /** Kind of service */
- private ServiceTypeKind serviceTypeKind = ServiceTypeKind.service;
-
- /**
- * Service priority. If two service are registered under the same key, only
- * the one with the higher priority is started.
- */
- private int priority;
-
- /**
- * Key used to register the service.
- */
- private String key;
-
- /**
- * Id of the bundle owning the .class that is referenced by
- * serviceClassname. Requested when instanciating the class.
- */
- private String classBundleID;
-
- /**
- * If set to true, the service is anonymous : it is not registered and can't
- * be retrieved with getService().
- */
- private boolean isAnonymous = false;
-
- /**
- * List of keys of Services required by this service.
- */
- private List<String> requiredServices = Collections.emptyList();
-
- /**
- * Empty list.
- */
- private static List<String> EMPTY_LIST_STRING = Collections.emptyList();
-
- /**
- * Constructor.
- *
- * @param key
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- * @param requiredServices
- */
- public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) {
- this.key = key;
- this.serviceClassname = serviceClassname;
- this.serviceStartKind = serviceStartKind;
- this.priority = priority;
- this.requiredServices = requiredServices;
- }
-
- /**
- * Constructor.
- *
- * @param key
- * A class used as key. The classname is used as key.
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- * @param requiredServices
- */
- public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) {
- this(key.getName(), serviceClassname, serviceStartKind, priority, requiredServices);
- }
-
- /**
- * Constructor.
- *
- * @param key
- * A class used as key. The classname is used as key.
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- * @param isAnonymous
- * @param requiredServices
- */
- public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous, List<String> requiredServices) {
- this.key = key;
- this.serviceClassname = serviceClassname;
- this.serviceStartKind = serviceStartKind;
- this.priority = priority;
- this.isAnonymous = isAnonymous;
- this.requiredServices = requiredServices;
- }
-
- /**
- * Constructor.
- *
- * @param key
- * A class used as key. The classname is used as key.
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- * @param isAnonymous
- * @param requiredServices
- */
- public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous, List<String> requiredServices) {
- this(key.getName(), serviceClassname, serviceStartKind, priority, isAnonymous, requiredServices);
- }
-
- /**
- * Constructor.
- *
- * @param key
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- */
- public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority) {
- this(key, serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING);
- }
-
- /**
- * Constructor.
- *
- * @param key
- * A class used as key. The classname is used as key.
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- */
- public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority) {
- this(key.getName(), serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING);
- }
-
- /**
- * Constructor.
- *
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- * @param requiredServices
- */
- public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) {
- this(serviceClassname, serviceClassname, serviceStartKind, priority, requiredServices);
- }
-
- /**
- * Constructor.
- *
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- */
- public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous) {
- this(serviceClassname, serviceClassname, serviceStartKind, priority, isAnonymous, EMPTY_LIST_STRING);
- }
-
- /**
- * Constructor.
- *
- * @param serviceClassname
- * @param serviceStartKind
- * @param priority
- */
- public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority) {
- this(serviceClassname, serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING);
- }
-
- /**
- * @return the serviceStartKind
- */
- public ServiceStartKind getServiceStartKind() {
- return serviceStartKind;
- }
-
- /**
- * Return true if StartKind is 'always'.
- *
- * @return
- */
- public boolean isStartAtStartup() {
- return serviceStartKind == ServiceStartKind.STARTUP;
- }
-
- /**
- * @return the priority
- */
- public int getPriority() {
- return priority;
- }
-
- /**
- * @return the key
- */
- public String getKey() {
- return key;
- }
-
- /**
- * @return the serviceClassname
- */
- public String getServiceClassname() {
- return serviceClassname;
- }
-
- /**
- * @return the classBundleID
- */
- public String getClassBundleID() {
- return classBundleID;
- }
-
- /**
- * @param classBundleId
- * the classBundleID to set
- */
- public void setClassBundleID(String classBundleId) {
- classBundleID = classBundleId;
- }
-
- /**
- * Get the keys of all the required services
- *
- * @return the requiredServices
- */
- public List<String> getRequiredServiceKeys() {
- return requiredServices;
- }
-
- /**
- * @param requiredServices
- * the requiredServices to set
- */
- public void setRequiredServiceKeys(List<String> requiredServices) {
- this.requiredServices = requiredServices;
- }
-
- /**
- * @see java.lang.Object#toString()
- * @return
- *
- */
- @Override
- public String toString() {
- return "ServiceDescriptor [key=" + key + ", serviceClassname=" + serviceClassname + ", serviceStartKind=" + serviceStartKind + ", priority=" + priority + "]";
- }
-
- /**
- * @return the isAnonymous
- */
- public boolean isAnonymous() {
- return isAnonymous;
- }
-
- /**
- * @param isAnonymous
- * the isAnonymous to set
- */
- public void setAnonymous(boolean isAnonymous) {
- this.isAnonymous = isAnonymous;
- }
-
- /**
- * @return the serviceTypeKind
- */
- public ServiceTypeKind getServiceTypeKind() {
- return serviceTypeKind;
- }
-
- /**
- * @param serviceTypeKind
- * the serviceTypeKind to set
- */
- public void setServiceTypeKind(ServiceTypeKind serviceTypeKind) {
- this.serviceTypeKind = serviceTypeKind;
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.Collections; +import java.util.List; + +/** + * Descriptor of a service. This descriptor describe a service. + * + * @author cedirc dumoulin + * + */ +public class ServiceDescriptor { + + /** + * Possible kind for service types. + * + */ + public enum ServiceTypeKind { + service, serviceFactory, pojo, alias + } + + /** Classname of the service. USed to start the service */ + private String serviceClassname; + + /** Kind of start for this service */ + private ServiceStartKind serviceStartKind; + + /** Kind of service */ + private ServiceTypeKind serviceTypeKind = ServiceTypeKind.service; + + /** + * Service priority. If two service are registered under the same key, only + * the one with the higher priority is started. + */ + private int priority; + + /** + * Key used to register the service. + */ + private String key; + + /** + * Id of the bundle owning the .class that is referenced by + * serviceClassname. Requested when instanciating the class. + */ + private String classBundleID; + + /** + * If set to true, the service is anonymous : it is not registered and can't + * be retrieved with getService(). + */ + private boolean isAnonymous = false; + + /** + * List of keys of Services required by this service. + */ + private List<String> requiredServices = Collections.emptyList(); + + /** + * Empty list. + */ + private static List<String> EMPTY_LIST_STRING = Collections.emptyList(); + + /** + * Constructor. + * + * @param key + * @param serviceClassname + * @param serviceStartKind + * @param priority + * @param requiredServices + */ + public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) { + this.key = key; + this.serviceClassname = serviceClassname; + this.serviceStartKind = serviceStartKind; + this.priority = priority; + this.requiredServices = requiredServices; + } + + /** + * Constructor. + * + * @param key + * A class used as key. The classname is used as key. + * @param serviceClassname + * @param serviceStartKind + * @param priority + * @param requiredServices + */ + public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) { + this(key.getName(), serviceClassname, serviceStartKind, priority, requiredServices); + } + + /** + * Constructor. + * + * @param key + * A class used as key. The classname is used as key. + * @param serviceClassname + * @param serviceStartKind + * @param priority + * @param isAnonymous + * @param requiredServices + */ + public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous, List<String> requiredServices) { + this.key = key; + this.serviceClassname = serviceClassname; + this.serviceStartKind = serviceStartKind; + this.priority = priority; + this.isAnonymous = isAnonymous; + this.requiredServices = requiredServices; + } + + /** + * Constructor. + * + * @param key + * A class used as key. The classname is used as key. + * @param serviceClassname + * @param serviceStartKind + * @param priority + * @param isAnonymous + * @param requiredServices + */ + public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous, List<String> requiredServices) { + this(key.getName(), serviceClassname, serviceStartKind, priority, isAnonymous, requiredServices); + } + + /** + * Constructor. + * + * @param key + * @param serviceClassname + * @param serviceStartKind + * @param priority + */ + public ServiceDescriptor(String key, String serviceClassname, ServiceStartKind serviceStartKind, int priority) { + this(key, serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING); + } + + /** + * Constructor. + * + * @param key + * A class used as key. The classname is used as key. + * @param serviceClassname + * @param serviceStartKind + * @param priority + */ + public ServiceDescriptor(Class<?> key, String serviceClassname, ServiceStartKind serviceStartKind, int priority) { + this(key.getName(), serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING); + } + + /** + * Constructor. + * + * @param serviceClassname + * @param serviceStartKind + * @param priority + * @param requiredServices + */ + public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority, List<String> requiredServices) { + this(serviceClassname, serviceClassname, serviceStartKind, priority, requiredServices); + } + + /** + * Constructor. + * + * @param serviceClassname + * @param serviceStartKind + * @param priority + */ + public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority, boolean isAnonymous) { + this(serviceClassname, serviceClassname, serviceStartKind, priority, isAnonymous, EMPTY_LIST_STRING); + } + + /** + * Constructor. + * + * @param serviceClassname + * @param serviceStartKind + * @param priority + */ + public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority) { + this(serviceClassname, serviceClassname, serviceStartKind, priority, EMPTY_LIST_STRING); + } + + /** + * @return the serviceStartKind + */ + public ServiceStartKind getServiceStartKind() { + return serviceStartKind; + } + + /** + * Return true if StartKind is 'always'. + * + * @return + */ + public boolean isStartAtStartup() { + return serviceStartKind == ServiceStartKind.STARTUP; + } + + /** + * @return the priority + */ + public int getPriority() { + return priority; + } + + /** + * @return the key + */ + public String getKey() { + return key; + } + + /** + * @return the serviceClassname + */ + public String getServiceClassname() { + return serviceClassname; + } + + /** + * @return the classBundleID + */ + public String getClassBundleID() { + return classBundleID; + } + + /** + * @param classBundleId + * the classBundleID to set + */ + public void setClassBundleID(String classBundleId) { + classBundleID = classBundleId; + } + + /** + * Get the keys of all the required services + * + * @return the requiredServices + */ + public List<String> getRequiredServiceKeys() { + return requiredServices; + } + + /** + * @param requiredServices + * the requiredServices to set + */ + public void setRequiredServiceKeys(List<String> requiredServices) { + this.requiredServices = requiredServices; + } + + /** + * @see java.lang.Object#toString() + * @return + * + */ + @Override + public String toString() { + return "ServiceDescriptor [key=" + key + ", serviceClassname=" + serviceClassname + ", serviceStartKind=" + serviceStartKind + ", priority=" + priority + "]"; + } + + /** + * @return the isAnonymous + */ + public boolean isAnonymous() { + return isAnonymous; + } + + /** + * @param isAnonymous + * the isAnonymous to set + */ + public void setAnonymous(boolean isAnonymous) { + this.isAnonymous = isAnonymous; + } + + /** + * @return the serviceTypeKind + */ + public ServiceTypeKind getServiceTypeKind() { + return serviceTypeKind; + } + + /** + * @param serviceTypeKind + * the serviceTypeKind to set + */ + public void setServiceTypeKind(ServiceTypeKind serviceTypeKind) { + this.serviceTypeKind = serviceTypeKind; + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorUtils.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorUtils.java index 6985e0621aa..a5b51e39a57 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorUtils.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorUtils.java @@ -1,145 +1,145 @@ -/*****************************************************************************
- * Copyright (c) 2012 Cedric Dumoulin.
- *
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AliasDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind;
-
-
-/**
- * Utilities used as bridge between {@link ServiceDescriptor} and {@link AbstractServiceIdDesc}.
- *
- * @author cedric dumoulin
- *
- */
-public class ServiceDescriptorUtils {
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param idDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(AbstractServiceIdDesc idDesc) {
-
-
- if( idDesc instanceof ServiceIdDesc ) {
- return toServiceDescriptor((ServiceIdDesc)idDesc);
- }
- else if(idDesc instanceof AliasIdDesc ) {
- return toServiceDescriptor((AliasIdDesc)idDesc);
- }
-
- // Should not happen
- throw new UnsupportedOperationException("Don't know how to transform '" + idDesc.getClass().getName() + "'.");
- }
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param serviceDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(AbstractServiceDesc serviceDesc) {
- if( serviceDesc instanceof ServiceDesc ) {
- return toServiceDescriptor((ServiceDesc)serviceDesc);
- }
- else if(serviceDesc instanceof AliasDesc ) {
- return toServiceDescriptor((AliasDesc)serviceDesc);
- }
-
- // Should not happen
- throw new UnsupportedOperationException("Don't know how to transform '" + serviceDesc.getClass().getName() + "'.");
- }
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param serviceIdDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(ServiceIdDesc serviceIdDesc) {
-
- ServiceStartKind serviceStartKind = transformToServiceStartKind(serviceIdDesc.getStartKind());
- return new ServiceDescriptor(serviceIdDesc.getName(), serviceIdDesc.getClassname(), serviceStartKind, serviceIdDesc.getPriority(), serviceIdDesc.getDependsOn());
- }
-
- /**
- *
- * @param startKind
- * @return
- */
- private static ServiceStartKind transformToServiceStartKind(StartupKind startKind) {
- switch( startKind) {
- case STARTUP:
- return ServiceStartKind.STARTUP;
- case LAZY:
- return ServiceStartKind.LAZY;
- default:
- return ServiceStartKind.STARTUP;
- }
- }
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param serviceDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(AliasIdDesc serviceDesc) {
-
- return new AliasDescriptor(serviceDesc.getName(), serviceDesc.getAliasedService(), serviceDesc.getPriority());
- }
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param serviceIdDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(ServiceDesc serviceIdDesc) {
-
- ServiceStartKind serviceStartKind = transformToServiceStartKind(serviceIdDesc.getStartKind());
- return new ServiceDescriptor(serviceIdDesc.getName(), serviceIdDesc.getClassname(), serviceStartKind, serviceIdDesc.getPriority(), serviceIdDesc.getDependsOnIds());
- }
-
- /**
- *
- * @param startKind
- * @return
- */
- private static ServiceStartKind transformToServiceStartKind(org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.StartupKind startKind) {
- switch( startKind) {
- case STARTUP:
- return ServiceStartKind.STARTUP;
- case LAZY:
- return ServiceStartKind.LAZY;
- default:
- return ServiceStartKind.STARTUP;
- }
- }
-
- /**
- * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}.
- * @param serviceDesc
- * @return
- */
- public static ServiceDescriptor toServiceDescriptor(AliasDesc serviceDesc) {
-
- return new AliasDescriptor(serviceDesc.getName(), serviceDesc.getAliasedServiceId(), serviceDesc.getPriority());
- }
-
-
-}
+/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AliasDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.ServiceDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AliasIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.StartupKind; + + +/** + * Utilities used as bridge between {@link ServiceDescriptor} and {@link AbstractServiceIdDesc}. + * + * @author cedric dumoulin + * + */ +public class ServiceDescriptorUtils { + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param idDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(AbstractServiceIdDesc idDesc) { + + + if( idDesc instanceof ServiceIdDesc ) { + return toServiceDescriptor((ServiceIdDesc)idDesc); + } + else if(idDesc instanceof AliasIdDesc ) { + return toServiceDescriptor((AliasIdDesc)idDesc); + } + + // Should not happen + throw new UnsupportedOperationException("Don't know how to transform '" + idDesc.getClass().getName() + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param serviceDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(AbstractServiceDesc serviceDesc) { + if( serviceDesc instanceof ServiceDesc ) { + return toServiceDescriptor((ServiceDesc)serviceDesc); + } + else if(serviceDesc instanceof AliasDesc ) { + return toServiceDescriptor((AliasDesc)serviceDesc); + } + + // Should not happen + throw new UnsupportedOperationException("Don't know how to transform '" + serviceDesc.getClass().getName() + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param serviceIdDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(ServiceIdDesc serviceIdDesc) { + + ServiceStartKind serviceStartKind = transformToServiceStartKind(serviceIdDesc.getStartKind()); + return new ServiceDescriptor(serviceIdDesc.getName(), serviceIdDesc.getClassname(), serviceStartKind, serviceIdDesc.getPriority(), serviceIdDesc.getDependsOn()); + } + + /** + * + * @param startKind + * @return + */ + private static ServiceStartKind transformToServiceStartKind(StartupKind startKind) { + switch( startKind) { + case STARTUP: + return ServiceStartKind.STARTUP; + case LAZY: + return ServiceStartKind.LAZY; + default: + return ServiceStartKind.STARTUP; + } + } + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param serviceDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(AliasIdDesc serviceDesc) { + + return new AliasDescriptor(serviceDesc.getName(), serviceDesc.getAliasedService(), serviceDesc.getPriority()); + } + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param serviceIdDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(ServiceDesc serviceIdDesc) { + + ServiceStartKind serviceStartKind = transformToServiceStartKind(serviceIdDesc.getStartKind()); + return new ServiceDescriptor(serviceIdDesc.getName(), serviceIdDesc.getClassname(), serviceStartKind, serviceIdDesc.getPriority(), serviceIdDesc.getDependsOnIds()); + } + + /** + * + * @param startKind + * @return + */ + private static ServiceStartKind transformToServiceStartKind(org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.StartupKind startKind) { + switch( startKind) { + case STARTUP: + return ServiceStartKind.STARTUP; + case LAZY: + return ServiceStartKind.LAZY; + default: + return ServiceStartKind.STARTUP; + } + } + + /** + * Create a {@link ServiceDescriptor} from a {@link AbstractServiceIdDesc}. + * @param serviceDesc + * @return + */ + public static ServiceDescriptor toServiceDescriptor(AliasDesc serviceDesc) { + + return new AliasDescriptor(serviceDesc.getName(), serviceDesc.getAliasedServiceId(), serviceDesc.getPriority()); + } + + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorsWithIdProviderCollection.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorsWithIdProviderCollection.java index dee8bbd9367..946e53cce5d 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorsWithIdProviderCollection.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceDescriptorsWithIdProviderCollection.java @@ -1,257 +1,257 @@ -/*****************************************************************************
- * Copyright (c) 2012 Cedric Dumoulin.
- *
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServicedescriptorswithidFactory;
-
-
-/**
- * A collection of DescriptorsProviders.
- * This provide nearly the same method as DescriptorsProviders, but the search is done over
- * a collection of DescriptorsProviders.
- *
- * @author cedric dumoulin
- *
- * TODO : complete
- */
-public class ServiceDescriptorsWithIdProviderCollection /*implements IServiceDescriptorsWithIdProvider*/ {
-
- protected List<IServiceDescriptorsWithIdProvider> descriptorsProviders;
-
-
-
- /**
- *
- * Constructor.
- *
- */
- public ServiceDescriptorsWithIdProviderCollection() {
- descriptorsProviders = new ArrayList<IServiceDescriptorsWithIdProvider>();
- }
-
- /**
- * Add all the provided {@link IServiceDescriptorsWithIdProvider} to the list of providers to use.
- * @param declaredDescriptorProviders
- */
- public void addAll(IServiceDescriptorsWithIdProvider ... declaredDescriptorProviders) {
-
- for( IServiceDescriptorsWithIdProvider provider : declaredDescriptorProviders) {
- descriptorsProviders.add(provider);
- }
-
- }
-
- /**
- * Get the descriptor for the specified registry.
- * If the registry is found more than one, throw an exception.
- * If the registry is not found, throws an exception.
- *
- * @param registryName The name of the registry for which the descriptor is required.
- *
- * @return The registry descriptor
- * @throws DeclarationException If an error occur while reading declarations.
- *
- */
- public RegistryIdDesc getRegistryIdDesc(String registryName) throws DeclarationException {
-
- RegistryIdDesc found = null;
- for( IServiceDescriptorsWithIdProvider provider : descriptorsProviders) {
-
- RegistryIdDesc res = provider.getRegistryDescriptor(registryName);
- if( found != null && res != null) {
- throw new DeclarationException("Registry '" + registryName + "' is declared more than once in declarations.");
- }
- found = res;
- }
-
- if( found == null ) {
- throw new DeclarationNotFoundException("Can't find registry named '" + registryName + "'.");
- }
-
- return found;
- }
-
- /**
- * Get the descriptor for the specified registry, with all inheritance resolved. This mean that
- * the returned descriptor has no inheritance, but the found inheritance are added in the inner properties
- * (sets, parents).
- *
- * @param registryName
- * @return
- * @throws DeclarationException
- */
- public RegistryIdDesc getResolvedRegistryIdDesc(String registryName) throws DeclarationException {
-
- // Get the original registry desc
- RegistryIdDesc registryIdDesc = getRegistryIdDesc(registryName);
-
- // Is there some inheritance ?
- if( registryIdDesc.getExtends().size() == 0) {
- // Remove doubles
- removeDoubleName( registryIdDesc.getParents() );
- removeDoubleName( registryIdDesc.getSets() );
- return registryIdDesc;
- }
-
- // There is some inheritance
- // Create a new desc, and set single values
- RegistryIdDesc resolvedDesc = ServicedescriptorswithidFactory.eINSTANCE.createRegistryIdDesc();
- resolvedDesc.setName(registryName);
- resolvedDesc.setDescription(registryIdDesc.getDescription());
- resolvedDesc.setIsUnique(registryIdDesc.isUnique());
- resolvedDesc.getSets().addAll( registryIdDesc.getSets());
- resolvedDesc.getParents().addAll( registryIdDesc.getParents());
-
- // Remove doubles from the list of directly inherited registry
- removeDoubleName( registryIdDesc.getExtends() );
-
- // Concat sets and parents from inherited descs
- for( String inheritedRegName : registryIdDesc.getExtends()) {
- // Get the inherited desc
- RegistryIdDesc inheritedReg = getResolvedRegistryIdDesc(inheritedRegName);
- // Concat sets and parents
- resolvedDesc.getSets().addAll( inheritedReg.getSets());
- resolvedDesc.getParents().addAll( inheritedReg.getParents());
-
- }
-
- // Remove doubles
- removeDoubleName( registryIdDesc.getParents() );
- removeDoubleName( registryIdDesc.getSets() );
-
- return resolvedDesc;
- }
-
- /**
- * Get the descriptor for the specified ServiceSetIdDesc, with all inheritance resolved. This mean that
- * the returned {@link ServiceSetIdDesc} has no inheritance. All services found from inherited sets are added in the set,
- * according to the following rules:
- * <ul>
- * <li>Names found in children hides names in parent (overloading)</li>
- * <li></li>
- * <li></li>
- * </ul>
- * @param setName
- * @return
- * @throws DeclarationException
- * @throws DeclarationNotFoundException If the set is not found
- */
- public ServiceSetIdDesc getResolvedServiceSetIdDesc(String setName) throws DeclarationException {
-
-
- ServiceSetIdDesc serviceSetIdDesc = getServiceSet(setName);
- // if no parent, return it directly
- if( serviceSetIdDesc.getExtends().size() == 0) {
- return serviceSetIdDesc;
- }
-
- // Create ServiceSetIdDesc
- ServiceSetIdDesc res = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc();
-
- res.setName(serviceSetIdDesc.getName());
- res.setDescription(serviceSetIdDesc.getDescription());
- res.getServiceDescriptors().addAll(serviceSetIdDesc.getServiceDescriptors());
-
- // Collect all parent's services
- for( String extendsName : serviceSetIdDesc.getExtends() ) {
- collectMissingServices( res, getResolvedServiceSetIdDesc(extendsName) );
- }
-
- return res;
- }
-
- /**
- * Collect the services that are set in the parent, but not found in the collect.
- * @param res
- * @param resolvedServiceSet
- */
- private void collectMissingServices(ServiceSetIdDesc collect, ServiceSetIdDesc parent) {
-
- for( AbstractServiceIdDesc desc : parent.getServiceDescriptors()) {
- if( ! collect.containsService(desc) ) {
- collect.getServiceDescriptors().add(desc);
- }
- }
-
- }
-
- /**
- * Get the {@link ServiceSetIdDesc} concatenating all fragments declaring a part of the ServiceSetIdDesc.
- *
- *
- * @param setName
- * @return
- * @throws DeclarationNotFoundException
- */
- public ServiceSetIdDesc getServiceSet(String serviceSetName) throws DeclarationException {
- ServiceSetIdDesc result = null;
-
-
- for( IServiceDescriptorsWithIdProvider provider : descriptorsProviders) {
-
- List<ServiceSetIdDesc> fragments = provider.getServiceSetFragments(serviceSetName);
- for( ServiceSetIdDesc fragment : fragments) {
- // Create the result ServiceSetIdDesc if needed
- if( result == null) {
- result = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc();
- result.setName(serviceSetName);
- }
- result.getExtends().addAll(fragment.getExtends());
- result.getServiceDescriptors().addAll(fragment.getServiceDescriptors());
-
- }
- }
-
- if( result == null ) {
- throw new DeclarationNotFoundException("Can't find ServiceSetIdDesc named '" + serviceSetName + "'.");
- }
- // Remove doubles
- removeDoubleName(result.getExtends());
-
- return result;
- }
-
- /**
- * Remove double names from the provided list.
- * @param list
- */
- private void removeDoubleName(List<String> list) {
-
- for( int i=0; i<list.size(); i++) {
- String ref = list.get(i);
-
- for( int j = i+1; j<list.size(); ) {
- // If we found the same name, remove the second one, and then check the same index
- // If the string are different, check the next index.
- if( ref.equals( list.get(j))) {
- // Remove it
- list.remove(j);
- }
- else {
- j++;
- }
- } // end j
- } // end i
-
- }
-
-
-}
+/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.AbstractServiceIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.RegistryIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServiceSetIdDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptorswithid.ServicedescriptorswithidFactory; + + +/** + * A collection of DescriptorsProviders. + * This provide nearly the same method as DescriptorsProviders, but the search is done over + * a collection of DescriptorsProviders. + * + * @author cedric dumoulin + * + * TODO : complete + */ +public class ServiceDescriptorsWithIdProviderCollection /*implements IServiceDescriptorsWithIdProvider*/ { + + protected List<IServiceDescriptorsWithIdProvider> descriptorsProviders; + + + + /** + * + * Constructor. + * + */ + public ServiceDescriptorsWithIdProviderCollection() { + descriptorsProviders = new ArrayList<IServiceDescriptorsWithIdProvider>(); + } + + /** + * Add all the provided {@link IServiceDescriptorsWithIdProvider} to the list of providers to use. + * @param declaredDescriptorProviders + */ + public void addAll(IServiceDescriptorsWithIdProvider ... declaredDescriptorProviders) { + + for( IServiceDescriptorsWithIdProvider provider : declaredDescriptorProviders) { + descriptorsProviders.add(provider); + } + + } + + /** + * Get the descriptor for the specified registry. + * If the registry is found more than one, throw an exception. + * If the registry is not found, throws an exception. + * + * @param registryName The name of the registry for which the descriptor is required. + * + * @return The registry descriptor + * @throws DeclarationException If an error occur while reading declarations. + * + */ + public RegistryIdDesc getRegistryIdDesc(String registryName) throws DeclarationException { + + RegistryIdDesc found = null; + for( IServiceDescriptorsWithIdProvider provider : descriptorsProviders) { + + RegistryIdDesc res = provider.getRegistryDescriptor(registryName); + if( found != null && res != null) { + throw new DeclarationException("Registry '" + registryName + "' is declared more than once in declarations."); //$NON-NLS-1$ //$NON-NLS-2$ + } + found = res; + } + + if( found == null ) { + throw new DeclarationNotFoundException("Can't find registry named '" + registryName + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } + + return found; + } + + /** + * Get the descriptor for the specified registry, with all inheritance resolved. This mean that + * the returned descriptor has no inheritance, but the found inheritance are added in the inner properties + * (sets, parents). + * + * @param registryName + * @return + * @throws DeclarationException + */ + public RegistryIdDesc getResolvedRegistryIdDesc(String registryName) throws DeclarationException { + + // Get the original registry desc + RegistryIdDesc registryIdDesc = getRegistryIdDesc(registryName); + + // Is there some inheritance ? + if( registryIdDesc.getExtends().size() == 0) { + // Remove doubles + removeDoubleName( registryIdDesc.getParents() ); + removeDoubleName( registryIdDesc.getSets() ); + return registryIdDesc; + } + + // There is some inheritance + // Create a new desc, and set single values + RegistryIdDesc resolvedDesc = ServicedescriptorswithidFactory.eINSTANCE.createRegistryIdDesc(); + resolvedDesc.setName(registryName); + resolvedDesc.setDescription(registryIdDesc.getDescription()); + resolvedDesc.setIsUnique(registryIdDesc.isUnique()); + resolvedDesc.getSets().addAll( registryIdDesc.getSets()); + resolvedDesc.getParents().addAll( registryIdDesc.getParents()); + + // Remove doubles from the list of directly inherited registry + removeDoubleName( registryIdDesc.getExtends() ); + + // Concat sets and parents from inherited descs + for( String inheritedRegName : registryIdDesc.getExtends()) { + // Get the inherited desc + RegistryIdDesc inheritedReg = getResolvedRegistryIdDesc(inheritedRegName); + // Concat sets and parents + resolvedDesc.getSets().addAll( inheritedReg.getSets()); + resolvedDesc.getParents().addAll( inheritedReg.getParents()); + + } + + // Remove doubles + removeDoubleName( registryIdDesc.getParents() ); + removeDoubleName( registryIdDesc.getSets() ); + + return resolvedDesc; + } + + /** + * Get the descriptor for the specified ServiceSetIdDesc, with all inheritance resolved. This mean that + * the returned {@link ServiceSetIdDesc} has no inheritance. All services found from inherited sets are added in the set, + * according to the following rules: + * <ul> + * <li>Names found in children hides names in parent (overloading)</li> + * <li></li> + * <li></li> + * </ul> + * @param setName + * @return + * @throws DeclarationException + * @throws DeclarationNotFoundException If the set is not found + */ + public ServiceSetIdDesc getResolvedServiceSetIdDesc(String setName) throws DeclarationException { + + + ServiceSetIdDesc serviceSetIdDesc = getServiceSet(setName); + // if no parent, return it directly + if( serviceSetIdDesc.getExtends().size() == 0) { + return serviceSetIdDesc; + } + + // Create ServiceSetIdDesc + ServiceSetIdDesc res = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc(); + + res.setName(serviceSetIdDesc.getName()); + res.setDescription(serviceSetIdDesc.getDescription()); + res.getServiceDescriptors().addAll(serviceSetIdDesc.getServiceDescriptors()); + + // Collect all parent's services + for( String extendsName : serviceSetIdDesc.getExtends() ) { + collectMissingServices( res, getResolvedServiceSetIdDesc(extendsName) ); + } + + return res; + } + + /** + * Collect the services that are set in the parent, but not found in the collect. + * @param res + * @param resolvedServiceSet + */ + private void collectMissingServices(ServiceSetIdDesc collect, ServiceSetIdDesc parent) { + + for( AbstractServiceIdDesc desc : parent.getServiceDescriptors()) { + if( ! collect.containsService(desc) ) { + collect.getServiceDescriptors().add(desc); + } + } + + } + + /** + * Get the {@link ServiceSetIdDesc} concatenating all fragments declaring a part of the ServiceSetIdDesc. + * + * + * @param setName + * @return + * @throws DeclarationNotFoundException + */ + public ServiceSetIdDesc getServiceSet(String serviceSetName) throws DeclarationException { + ServiceSetIdDesc result = null; + + + for( IServiceDescriptorsWithIdProvider provider : descriptorsProviders) { + + List<ServiceSetIdDesc> fragments = provider.getServiceSetFragments(serviceSetName); + for( ServiceSetIdDesc fragment : fragments) { + // Create the result ServiceSetIdDesc if needed + if( result == null) { + result = ServicedescriptorswithidFactory.eINSTANCE.createServiceSetIdDesc(); + result.setName(serviceSetName); + } + result.getExtends().addAll(fragment.getExtends()); + result.getServiceDescriptors().addAll(fragment.getServiceDescriptors()); + + } + } + + if( result == null ) { + throw new DeclarationNotFoundException("Can't find ServiceSetIdDesc named '" + serviceSetName + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } + // Remove doubles + removeDoubleName(result.getExtends()); + + return result; + } + + /** + * Remove double names from the provided list. + * @param list + */ + private void removeDoubleName(List<String> list) { + + for( int i=0; i<list.size(); i++) { + String ref = list.get(i); + + for( int j = i+1; j<list.size(); ) { + // If we found the same name, remove the second one, and then check the same index + // If the string are different, check the next index. + if( ref.equals( list.get(j))) { + // Remove it + list.remove(j); + } + else { + j++; + } + } // end j + } // end i + + } + + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceException.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceException.java index 2b824444f9e..8ed9c311643 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceException.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceException.java @@ -1,57 +1,67 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * Root Exception of Services Exception.
- *
- * @author dumoulin
- *
- */
-public class ServiceException extends Exception {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- */
- public ServiceException() {
- // TODO Auto-generated constructor stub
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public ServiceException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public ServiceException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public ServiceException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * Root Exception of Services Exception. + * + * @author dumoulin + * + */ +public class ServiceException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + */ + public ServiceException() { + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + */ + public ServiceException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param cause + */ + public ServiceException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public ServiceException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceMultiException.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceMultiException.java index faec7d68c30..4bfaca52e06 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceMultiException.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceMultiException.java @@ -1,139 +1,149 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An exception encapsulating multiple exceptions. This exception is thrown when
- * an operation performed on several Services fails on one or more of these
- * Service. The exception contains all the exceptions encoutered while
- * opertating on Services.
- *
- * @author cedric dumoulin
- *
- */
-public class ServiceMultiException extends ServiceException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * List of encountered exceptions.
- */
- List<Throwable> encounteredExceptions = new ArrayList<Throwable>();
-
- /**
- * List of identifiers corresponding to exceptions.
- */
- List<Object> serviceIdentifiers = new ArrayList<Object>();
-
- /**
- * @return the encounteredExceptions
- */
- public List<Throwable> getExceptions() {
- return encounteredExceptions;
- }
-
- /**
- * Constructor.
- *
- */
- public ServiceMultiException() {
- super("Multiple exceptions");
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public ServiceMultiException(String message) {
- super(message);
- }
-
- /**
- * Return the first exception.
- *
- * @see java.lang.Throwable#getCause()
- *
- * @return
- */
- @Override
- public Throwable getCause() {
- return (encounteredExceptions.size() > 0 ? encounteredExceptions.get(0) : null);
- }
-
- /**
- * Return the message if any, or the message of the first exception.
- *
- * @see java.lang.Throwable#getMessage()
- *
- * @return
- */
- @Override
- public String getMessage() {
-
- StringBuffer buffer = new StringBuffer();
-
- String message = super.getMessage();
- if(message != null)
- buffer.append(message).append('\n');
-
- buffer.append("----- exceptions : ----------\n");
- for(int i = 0; i < encounteredExceptions.size(); i++) {
- Throwable exception = encounteredExceptions.get(i);
- Object identifierMsg = serviceIdentifiers.get(i);
-
- if(identifierMsg != null)
- buffer.append(identifierMsg.toString()).append(" : ");
- String msg = exception.getMessage();
- if(msg != null)
- buffer.append(msg).append('\n');
- }
- buffer.append("----------------------------- \n");
-
- return buffer.toString();
- // // Check for first exception
- // if( encounteredExceptions.size() > 1)
- // return encounteredExceptions.get(0).getMessage();
- //
- // // default
- // return null;
- }
-
- /**
- * Add an exception to the list of exceptions.
- *
- * @param exception
- */
- public void addException(Throwable exception) {
- addException("unknown", exception);
- }
-
- /**
- * Add an exception to the list of exceptions. Also record the corresponding
- * model identifier if any.
- *
- * @param exception
- */
- public void addException(Object identifier, Throwable exception) {
- encounteredExceptions.add(exception);
- serviceIdentifiers.add(identifier);
- }
-
- /**
- * Merge both exceptions
- *
- * @param e
- */
- public void addAll(ServiceMultiException e) {
- encounteredExceptions.addAll(e.encounteredExceptions);
- serviceIdentifiers.addAll(serviceIdentifiers);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.List; + +/** + * An exception encapsulating multiple exceptions. This exception is thrown when + * an operation performed on several Services fails on one or more of these + * Service. The exception contains all the exceptions encoutered while + * opertating on Services. + * + * @author cedric dumoulin + * + */ +public class ServiceMultiException extends ServiceException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * List of encountered exceptions. + */ + List<Throwable> encounteredExceptions = new ArrayList<Throwable>(); + + /** + * List of identifiers corresponding to exceptions. + */ + List<Object> serviceIdentifiers = new ArrayList<Object>(); + + /** + * @return the encounteredExceptions + */ + public List<Throwable> getExceptions() { + return encounteredExceptions; + } + + /** + * Constructor. + * + */ + public ServiceMultiException() { + super("Multiple exceptions"); //$NON-NLS-1$ + } + + /** + * Constructor. + * + * @param message + */ + public ServiceMultiException(String message) { + super(message); + } + + /** + * Return the first exception. + * + * @see java.lang.Throwable#getCause() + * + * @return + */ + @Override + public Throwable getCause() { + return (encounteredExceptions.size() > 0 ? encounteredExceptions.get(0) : null); + } + + /** + * Return the message if any, or the message of the first exception. + * + * @see java.lang.Throwable#getMessage() + * + * @return + */ + @Override + public String getMessage() { + + StringBuffer buffer = new StringBuffer(); + + String message = super.getMessage(); + if(message != null) + buffer.append(message).append('\n'); + + buffer.append("----- exceptions : ----------\n"); + for(int i = 0; i < encounteredExceptions.size(); i++) { + Throwable exception = encounteredExceptions.get(i); + Object identifierMsg = serviceIdentifiers.get(i); + + if(identifierMsg != null) + buffer.append(identifierMsg.toString()).append(" : "); + String msg = exception.getMessage(); + if(msg != null) + buffer.append(msg).append('\n'); + } + buffer.append("----------------------------- \n"); + + return buffer.toString(); + // // Check for first exception + // if( encounteredExceptions.size() > 1) + // return encounteredExceptions.get(0).getMessage(); + // + // // default + // return null; + } + + /** + * Add an exception to the list of exceptions. + * + * @param exception + */ + public void addException(Throwable exception) { + addException("unknown", exception); + } + + /** + * Add an exception to the list of exceptions. Also record the corresponding + * model identifier if any. + * + * @param exception + */ + public void addException(Object identifier, Throwable exception) { + encounteredExceptions.add(exception); + serviceIdentifiers.add(identifier); + } + + /** + * Merge both exceptions + * + * @param e + */ + public void addAll(ServiceMultiException e) { + encounteredExceptions.addAll(e.encounteredExceptions); + serviceIdentifiers.addAll(serviceIdentifiers); + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceNotFoundException.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceNotFoundException.java index b3dc07583b6..2e4e890b1a6 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceNotFoundException.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceNotFoundException.java @@ -1,51 +1,64 @@ -package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * Service is not found.
- *
- * @author dumoulin
- *
- */
-public class ServiceNotFoundException extends ServiceException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- */
- public ServiceNotFoundException() {
- super();
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public ServiceNotFoundException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public ServiceNotFoundException(String message) {
- super(message);
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public ServiceNotFoundException(Throwable cause) {
- super(cause);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * Service is not found. + * + * @author dumoulin + * + */ +public class ServiceNotFoundException extends ServiceException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + */ + public ServiceNotFoundException() { + super(); + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public ServiceNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message + */ + public ServiceNotFoundException(String message) { + super(message); + } + + /** + * Constructor. + * + * @param cause + */ + public ServiceNotFoundException(Throwable cause) { + super(cause); + } + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceRegistryFactory.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceRegistryFactory.java index 00c8cd1f545..574a52b6917 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceRegistryFactory.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceRegistryFactory.java @@ -1,226 +1,226 @@ -/*****************************************************************************
- * Copyright (c) 2012 Cedric Dumoulin.
- *
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc;
-import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.RegistryDesc;
-
-
-/**
- * @author cedric dumoulin
- *
- */
-public class ServiceRegistryFactory {
-
- /**
- * Repository of single registries.
- */
- protected Map<String, ServicesRegistry> singleRegistries;
-
- /**
- * DescriptorProviders access point.
- */
- protected DescriptorsCache descriptorProviders;
-
- /**
- * Constructor.
- *
- */
- public ServiceRegistryFactory(DescriptorsCache descriptorProviders) {
- this.descriptorProviders = descriptorProviders;
- }
-
- /**
- * Constructor.
- *
- * @param declaredDescriptorProviders Array of providers to be used by the {@link ServiceDescriptorsWithIdProviderCollection}.
- */
- public ServiceRegistryFactory(IServiceDescriptorsWithIdProvider ... declaredDescriptorProviders ) {
-
- descriptorProviders = new DescriptorsCache();
- descriptorProviders.addAll(declaredDescriptorProviders);
- }
-
- /**
- * Create a {@link ServicesRegistry} from the specified description.
- * The description is searched in the associated {@link ServiceDescriptorsWithIdProviderCollection}.
- *
- * @param registryName The name of the description used to initialized the ServicesRegistry.
- *
- * @return The requested {@link ServicesRegistry}
- * @throws DeclarationException
- */
- public ServicesRegistry getServicesRegistry( String registryName ) throws DeclarationException {
-
- RegistryDesc registryIdDesc = descriptorProviders.getRegistryDesc( registryName);
-
- return getServicesRegistry(registryIdDesc);
- }
-
- /**
- * Get a {@link ServicesRegistry} corresponding to the specified descriptor. Also create recursively referenced
- * registries and services.
- *
- * If the registry is "unique", lookup for an already existing instance, and return it if found.
- * If the registry is not unique, create a new instance corresponding to the descriptor.
- * Referenced descriptions are searched in the associated ConfigurationProvider.
- *
- * @param registryIdDesc The descriptor used to initialized the ServicesRegistry.
- *
- * @return The requested {@link ServicesRegistry}
- * @throws DeclarationException
- */
- protected ServicesRegistry getServicesRegistry( RegistryDesc registryIdDesc ) throws DeclarationException {
-
- ServicesRegistry registry;
-
- if(registryIdDesc.isUnique() ) {
- // lookup for an instance
- registry = getSingleRegistry(registryIdDesc);
- if( registry != null )
- return registry;
- // Not found: create it
- }
-
- // create a new Registry
- List<DeclarationException> errors = new ArrayList<DeclarationException>();
- registry = new ServicesRegistry();
- // Initialize it
- // add parents
- for(RegistryDesc parentName: registryIdDesc.getParents()) {
- try {
- ServicesRegistry parent = getServicesRegistry(parentName);
- registry.addParentRegistry(parent);
- } catch (DeclarationException e) {
- errors.add(e);
- }
- }
-
- // Add services
- for(AbstractServiceDesc serviceDesc: registryIdDesc.getServices()) {
-
- registry.add(ServiceDescriptorUtils.toServiceDescriptor(serviceDesc) );
- }
-
- // Throw exceptions if pb encountered
- if(errors.size() >0) {
- if(errors.size() == 1) {
- throw errors.get(0);
- }
- else {
- // TODO: throw a multi exception
- throw new DeclarationException("Somme services are not started (first is shown)", errors.get(0));
- }
- }
-
- return registry;
- }
-
- /**
- * Extends the specified registry with all services and parents declared in the specified descriptor.
- * Only missing services and parents are added.
- * <br>If both the original registry and the additional registry contain a service with the same name,
- * the service from the original registry is conserved.
- *
- * @param registry The registry to extends.
- * @param extendsWithRegistryName The name of the descriptor used to extends the registry.
- * @return
- * @throws DeclarationException
- */
- public ServicesRegistry extendsServicesRegistry( ServicesRegistry registry, String extendsWithRegistryName ) throws DeclarationException {
-
- RegistryDesc registryDesc = descriptorProviders.getRegistryDesc( extendsWithRegistryName);
-
- return extendsServicesRegistry(registry, registryDesc);
- }
-
- /**
- * Extends the specified registry with all services and parents declared in the specified descriptor.
- * Only missing services and parents are added.
- * <br>If both the original registry and the additional registry contain a service with the same name,
- * the service from the original registry is conserved.
- *
- * @param extendRegistryDesc The descriptor used to initialized the ServicesRegistry.
- *
- * @return The requested {@link ServicesRegistry}
- * @throws DeclarationException
- */
- protected ServicesRegistry extendsServicesRegistry( ServicesRegistry registry, RegistryDesc extendRegistryDesc ) throws DeclarationException {
-
- // create a new Registry
- List<Throwable> errors = new ArrayList<Throwable>();
-
- // add missing parents
- //
- if( extendRegistryDesc.getParents().size()>0) {
- throw new UnsupportedOperationException("Registry extension with parents not yet implemented.");
- }
-// for(RegistryDesc newExtend: extendRegistryDesc.getParents()) {
-// try {
-// if( !registry.containsParent(newExtend.getName()) ) {
-// ServicesRegistry parent = getServicesRegistry(newExtend.getName());
-// registry.addParentRegistry(parent);
-// }
-//
-// } catch (DeclarationException e) {
-// errors.add(e);
-// }
-// }
-
-
- // Add missing services
- for( AbstractServiceDesc idDesc : extendRegistryDesc.getServices() ) {
- try {
- if( ! registry.isStarted(idDesc.getName(), false)) {
- registry.add(ServiceDescriptorUtils.toServiceDescriptor(idDesc) );
- }
- } catch (ServiceNotFoundException e) {
- errors.add(e);
- }
- }
-
- // Throw exceptions if pb encountered
- if(errors.size() >0) {
- if(errors.size() == 1) {
- throw new DeclarationException(errors.get(0));
- }
- else {
- // TODO: throw a multi exception
- throw new DeclarationMultiException("Somme services are not started.", errors);
- }
- }
-
- return registry;
- }
-
- /**
- * Get the specified single registry by its name.
- * Return null if not found or if the repository do not exist.
- *
- * @param registryIdDesc
- * @return
- */
- private ServicesRegistry getSingleRegistry(RegistryDesc registryIdDesc) {
- if( singleRegistries == null)
- return null;
- return singleRegistries.get( registryIdDesc.getName() );
- }
-
-
-}
+/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.AbstractServiceDesc; +import org.eclipse.papyrus.infra.core.serviceregistry.servicedescriptors.RegistryDesc; + + +/** + * @author cedric dumoulin + * + */ +public class ServiceRegistryFactory { + + /** + * Repository of single registries. + */ + protected Map<String, ServicesRegistry> singleRegistries; + + /** + * DescriptorProviders access point. + */ + protected DescriptorsCache descriptorProviders; + + /** + * Constructor. + * + */ + public ServiceRegistryFactory(DescriptorsCache descriptorProviders) { + this.descriptorProviders = descriptorProviders; + } + + /** + * Constructor. + * + * @param declaredDescriptorProviders Array of providers to be used by the {@link ServiceDescriptorsWithIdProviderCollection}. + */ + public ServiceRegistryFactory(IServiceDescriptorsWithIdProvider ... declaredDescriptorProviders ) { + + descriptorProviders = new DescriptorsCache(); + descriptorProviders.addAll(declaredDescriptorProviders); + } + + /** + * Create a {@link ServicesRegistry} from the specified description. + * The description is searched in the associated {@link ServiceDescriptorsWithIdProviderCollection}. + * + * @param registryName The name of the description used to initialized the ServicesRegistry. + * + * @return The requested {@link ServicesRegistry} + * @throws DeclarationException + */ + public ServicesRegistry getServicesRegistry( String registryName ) throws DeclarationException { + + RegistryDesc registryIdDesc = descriptorProviders.getRegistryDesc( registryName); + + return getServicesRegistry(registryIdDesc); + } + + /** + * Get a {@link ServicesRegistry} corresponding to the specified descriptor. Also create recursively referenced + * registries and services. + * + * If the registry is "unique", lookup for an already existing instance, and return it if found. + * If the registry is not unique, create a new instance corresponding to the descriptor. + * Referenced descriptions are searched in the associated ConfigurationProvider. + * + * @param registryIdDesc The descriptor used to initialized the ServicesRegistry. + * + * @return The requested {@link ServicesRegistry} + * @throws DeclarationException + */ + protected ServicesRegistry getServicesRegistry( RegistryDesc registryIdDesc ) throws DeclarationException { + + ServicesRegistry registry; + + if(registryIdDesc.isUnique() ) { + // lookup for an instance + registry = getSingleRegistry(registryIdDesc); + if( registry != null ) + return registry; + // Not found: create it + } + + // create a new Registry + List<DeclarationException> errors = new ArrayList<DeclarationException>(); + registry = new ServicesRegistry(); + // Initialize it + // add parents + for(RegistryDesc parentName: registryIdDesc.getParents()) { + try { + ServicesRegistry parent = getServicesRegistry(parentName); + registry.addParentRegistry(parent); + } catch (DeclarationException e) { + errors.add(e); + } + } + + // Add services + for(AbstractServiceDesc serviceDesc: registryIdDesc.getServices()) { + + registry.add(ServiceDescriptorUtils.toServiceDescriptor(serviceDesc) ); + } + + // Throw exceptions if pb encountered + if(errors.size() >0) { + if(errors.size() == 1) { + throw errors.get(0); + } + else { + // TODO: throw a multi exception + throw new DeclarationException("Somme services are not started (first is shown)", errors.get(0)); //$NON-NLS-1$ + } + } + + return registry; + } + + /** + * Extends the specified registry with all services and parents declared in the specified descriptor. + * Only missing services and parents are added. + * <br>If both the original registry and the additional registry contain a service with the same name, + * the service from the original registry is conserved. + * + * @param registry The registry to extends. + * @param extendsWithRegistryName The name of the descriptor used to extends the registry. + * @return + * @throws DeclarationException + */ + public ServicesRegistry extendsServicesRegistry( ServicesRegistry registry, String extendsWithRegistryName ) throws DeclarationException { + + RegistryDesc registryDesc = descriptorProviders.getRegistryDesc( extendsWithRegistryName); + + return extendsServicesRegistry(registry, registryDesc); + } + + /** + * Extends the specified registry with all services and parents declared in the specified descriptor. + * Only missing services and parents are added. + * <br>If both the original registry and the additional registry contain a service with the same name, + * the service from the original registry is conserved. + * + * @param extendRegistryDesc The descriptor used to initialized the ServicesRegistry. + * + * @return The requested {@link ServicesRegistry} + * @throws DeclarationException + */ + protected ServicesRegistry extendsServicesRegistry( ServicesRegistry registry, RegistryDesc extendRegistryDesc ) throws DeclarationException { + + // create a new Registry + List<Throwable> errors = new ArrayList<Throwable>(); + + // add missing parents + // + if( extendRegistryDesc.getParents().size()>0) { + throw new UnsupportedOperationException("Registry extension with parents not yet implemented."); //$NON-NLS-1$ + } +// for(RegistryDesc newExtend: extendRegistryDesc.getParents()) { +// try { +// if( !registry.containsParent(newExtend.getName()) ) { +// ServicesRegistry parent = getServicesRegistry(newExtend.getName()); +// registry.addParentRegistry(parent); +// } +// +// } catch (DeclarationException e) { +// errors.add(e); +// } +// } + + + // Add missing services + for( AbstractServiceDesc idDesc : extendRegistryDesc.getServices() ) { + try { + if( ! registry.isStarted(idDesc.getName(), false)) { + registry.add(ServiceDescriptorUtils.toServiceDescriptor(idDesc) ); + } + } catch (ServiceNotFoundException e) { + errors.add(e); + } + } + + // Throw exceptions if pb encountered + if(errors.size() >0) { + if(errors.size() == 1) { + throw new DeclarationException(errors.get(0)); + } + else { + // TODO: throw a multi exception + throw new DeclarationMultiException("Somme services are not started.", errors); + } + } + + return registry; + } + + /** + * Get the specified single registry by its name. + * Return null if not found or if the repository do not exist. + * + * @param registryIdDesc + * @return + */ + private ServicesRegistry getSingleRegistry(RegistryDesc registryIdDesc) { + if( singleRegistries == null) + return null; + return singleRegistries.get( registryIdDesc.getName() ); + } + + +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceStartKind.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceStartKind.java index 9071b2bdbde..9be909b3846 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceStartKind.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceStartKind.java @@ -1,18 +1,28 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * Kind of possible start method for a service. LAZY - The service start when it
- * is requested for the first time. STARTUP - The service start as soon as the
- * registry is started, or when the service is added is the registry is already
- * started.
- *
- * @author dumoulin
- *
- */
-public enum ServiceStartKind {
-
- LAZY, STARTUP;
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * Kind of possible start method for a service. LAZY - The service start when it + * is requested for the first time. STARTUP - The service start as soon as the + * registry is started, or when the service is added is the registry is already + * started. + * + * @author dumoulin + * + */ +public enum ServiceStartKind { + + LAZY, STARTUP; +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceState.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceState.java index 409a9bcf683..2f7514352b1 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceState.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServiceState.java @@ -1,14 +1,24 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-/**
- * The different states that a service can have.
- *
- * @author dumoulin
- *
- */
-public enum ServiceState {
- registered, created, initialized, starting, started, disposed, error
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +/** + * The different states that a service can have. + * + * @author dumoulin + * + */ +public enum ServiceState { + registered, created, initialized, starting, started, disposed, error +} diff --git a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServicesRegistry.java b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServicesRegistry.java index c46bc43eb47..1525420b466 100644 --- a/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServicesRegistry.java +++ b/plugins/infra/core/serviceregistry/org.eclipse.papyrus.infra.core.serviceregistry/src/org/eclipse/papyrus/infra/core/serviceregistry/ServicesRegistry.java @@ -1,1368 +1,1378 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.serviceregistry;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.eclipse.papyrus.infra.core.serviceregistry.ServiceDescriptor.ServiceTypeKind;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.AliasServiceEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.LazyStartupEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.PojoServiceEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceFactoryEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceStartupEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceTypeEntry;
-import org.eclipse.papyrus.infra.core.serviceregistry.internal.StartStartupEntry;
-
-/**
- * A registry of services. This registry allows to get a service by its
- * identifier. The identifier is generally the classname of the service.
- * Services can be added using the Eclipse extension mechanism (if you use {@link ExtensionServicesRegistry}). <br>
- * A Service is a class providing operations. The ServiceRegistry is used to
- * share objects (i.e. services) between nested editors and also the core main
- * editor.
- *
- * <br>
- * In this implementation, services should be added to the registry before the
- * call to createServices(). If a service is added after the call, it will not
- * be started (except if it is a lazy service). <br>
- * A typical usage is:
- *
- * <pre>
- * <code>
- * ServicesRegistry serviceRegistry = new ServiceRegistry();
- * // Add your services
- * serviceRegistry.add( ...);
- * serviceRegistry.add( ...);
- *
- * // start the services
- * serviceRegistry.startRegistry();
- *
- * // Retrieve a service
- * myService = serviceRegistry.getService( serviceKey );
- * </code>
- * </pre>
- *
- * It is possible to register new services after the serviceRegistry has been
- * started. In this case, you need to start them explicitly if they are of type
- * ServiceStartKind.STARTUP.
- *
- * <pre>
- * <code>
- * // Add your new services
- * serviceRegistry.add( key1, ...);
- * serviceRegistry.add( key2, ...);
- *
- * // start the new services
- * serviceRegistry.startRegistry(key1, key2);
- * </code>
- * </pre>
- *
- * <ul>
- * <li></li>
- * <li></li>
- * </ul>
- *
- * @author cedric dumoulin
- *
- *
- */
-public class ServicesRegistry {
-
- /** Log object */
- protected Logger log = Logger.getLogger(getClass().getName());
-
- /**
- * Map of existing services.
- */
- // private Map<Object, AbstractServiceEntry> services;
-
- /**
- * A Map of services added to the register (thow the addXxx() methods), but
- * not yet registered. They will be registered after a call to startXxx().
- */
- private Map<String, ServiceStartupEntry> addedServices = new HashMap<String, ServiceStartupEntry>();
-
- /**
- * Map of services registered with a name.
- */
- private Map<String, ServiceStartupEntry> namedServices = new HashMap<String, ServiceStartupEntry>();
-
- /**
- * Map of services registered without a name (anonymous). Such services
- * can't be retrieved.
- */
- private List<ServiceStartupEntry> anonymousServices = new ArrayList<ServiceStartupEntry>();
-
- /**
- * List of parents used as fallback if the service is not found in this registry.
- */
- private List<ServicesRegistry> parents = new ArrayList<ServicesRegistry>();
-
- /**
- * Constructor.
- */
- public ServicesRegistry() {
- }
-
- /**
- * Add a service by its ServiceDescriptor.
- *
- * @param serviceDescriptor
- * Descriptor describing the service.
- * @throws ServiceException
- * If an error occurs while initializing service.
- */
- public void add(ServiceDescriptor serviceDescriptor) {
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(serviceDescriptor.getKey());
- if(service != null) {
- if(service.getDescriptor().getPriority() > serviceDescriptor.getPriority())
- return;
- else if(service.getDescriptor().getPriority() == serviceDescriptor.getPriority()) {
- log.warning("Two services with same priority (" + serviceDescriptor.getPriority() + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only. (bundles: " + service.getDescriptor().getClassBundleID() + ", " + serviceDescriptor.getClassBundleID() + ")");
- }
- }
-
- // Compute the service type entry
- ServiceTypeEntry serviceTypeEntry;
- ServiceTypeKind typeKind = serviceDescriptor.getServiceTypeKind();
- switch( typeKind) {
- case service:
- serviceTypeEntry = new ServiceEntry(serviceDescriptor);
- break;
- case serviceFactory:
- serviceTypeEntry = new ServiceFactoryEntry(serviceDescriptor);
- break;
- case pojo:
- serviceTypeEntry = new PojoServiceEntry(serviceDescriptor);
- break;
- case alias:
- serviceTypeEntry = new AliasServiceEntry(serviceDescriptor);
- break;
- default:
- // Add as pojo
- // Should better throw an exception. (MalformedDescriptor ?)
- serviceTypeEntry = new PojoServiceEntry(serviceDescriptor);
- }
-
- // Create the entry
- ServiceStartupEntry serviceEntry;
- switch(serviceDescriptor.getServiceStartKind()) {
- case STARTUP:
- serviceEntry = new StartStartupEntry(serviceTypeEntry);
- break;
- case LAZY:
- serviceEntry = new LazyStartupEntry(serviceTypeEntry, this);
- break;
- default:
- // Add as LAZY
- // Should better throw an exception. (MalformedDescriptor ?)
- serviceEntry = new LazyStartupEntry(serviceTypeEntry, this);
- }
-
- // Add the entry
- addedServices.put(serviceDescriptor.getKey(), serviceEntry);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(String key, int priority, IService serviceInstance) {
- add(key, priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, IService serviceInstance) {
- add(key.getName(), priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(String key, int priority, IService serviceInstance, ServiceStartKind startKind) {
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(key);
- if(service != null) {
- if(service.getDescriptor().getPriority() > priority)
- return;
- else if(service.getDescriptor().getPriority() == priority)
- log.warning("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
- }
-
- // Create descriptor and add service.
- ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority);
-
- if(startKind == ServiceStartKind.STARTUP)
- addedServices.put(key, new StartStartupEntry(new ServiceEntry(descriptor, serviceInstance)));
- else
- addedServices.put(key, new LazyStartupEntry(new ServiceEntry(descriptor, serviceInstance), this));
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key Class used as key. The classname is used as key.
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, IService serviceInstance, ServiceStartKind startKind) {
-
- add(key.getName(), priority, serviceInstance, startKind);
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, Object serviceInstance) {
- add(key, priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- * @param startKind
- *
- */
- public void add(String key, int priority, Object serviceInstance, ServiceStartKind startKind) {
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(key);
- if(service != null) {
- if(service.getDescriptor().getPriority() > priority)
- return;
- else if(service.getDescriptor().getPriority() == priority)
- log.warning("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
- }
-
- // Create descriptor and add service.
- ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority);
-
- if(startKind == ServiceStartKind.STARTUP)
- addedServices.put(key, new StartStartupEntry(new PojoServiceEntry(descriptor, serviceInstance)));
- else
- addedServices.put(key, new LazyStartupEntry(new PojoServiceEntry(descriptor, serviceInstance), this));
-
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key Class used as key. The classname is used as key.
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- * @param startKind
- *
- */
- public void add(Class<?> key, int priority, Object serviceInstance, ServiceStartKind startKind) {
-
- add(key.getName(), priority, serviceInstance, startKind);
- }
-
- /**
- * Remove the specified Registry as parent of this registry.
- * .
- * @param parentRegistry
- */
- public void addParentRegistry(ServicesRegistry parentRegistry) {
-
- if( parentRegistry == null) {
- return;
- }
- parents.add(parentRegistry);
- }
-
- /**
- *
- * @param parentRegistry
- */
- public void removeParentRegistry(ServicesRegistry parentRegistry) {
-
- if( parentRegistry == null) {
- return;
- }
- parents.remove(parentRegistry);
- }
-
-
- /**
- * Remove the specified service from the registry.
- *
- * @param key
- */
- public void remove(ServiceDescriptor serviceDescriptor) throws ServiceException {
- remove(serviceDescriptor.getKey());
- }
-
- /**
- * Remove the specified service from the registry.
- *
- * @param key
- */
- public void remove(Object key) throws ServiceException {
- ServiceStartupEntry service = namedServices.remove(key);
- if(service == null) {
- return;
- }
-
- // Stop the service
- service.disposeService();
- }
-
- /**
- * Get the requested service by its key. The key is usually the classname of
- * the service.
- *
- * @param serviceClass
- * @return
- * @throws ServiceException
- * If servive can't be started
- */
- public Object getService(Object key) throws ServiceException {
- ServiceStartupEntry serviceEntry = namedServices.get(key);
- if(serviceEntry == null) {
- // Check if we can find it in parents
- Object service = getServiceFromParents(key);
- if(service != null) {
- // Found in parent, return it
- return service;
- }
-
- // Not found in parents. Throw an exception
- // throw an appropriate exception (If added, say it).
- serviceEntry = addedServices.get(key);
- if(serviceEntry != null)
- throw new BadStateException("Registry should be started before.", serviceEntry.getState(), serviceEntry.getDescriptor());
- else
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- return serviceEntry.getServiceInstance();
- }
-
- /**
- * Get the requested service by its class (the service has to be registered
- * by its class object).
- *
- * @param key
- * The service class.
- * @return The service.
- * @throws ServiceException
- * If service can't be started
- */
- @SuppressWarnings("unchecked")
- public <S> S getService(Class<S> key) throws ServiceException {
-
- String realKey = key.getName();
- ServiceStartupEntry serviceEntry = namedServices.get(realKey);
-
- // Lookup in parents if not found
- if( serviceEntry == null) {
-
- // Check if we can find it in parents
- S service = (S)getServiceFromParents(realKey);
- if(service != null) {
- // Found in parent, return it
- return service;
- }
-
- // Not found in parents. Throw an exception
- // throw an appropriate exception (If added, say it).
- serviceEntry = addedServices.get(realKey);
- if(serviceEntry != null)
- throw new BadStateException("Registry should be started before.", serviceEntry.getState(), serviceEntry.getDescriptor());
- else
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- // Service found, return it.
- return (S)serviceEntry.getServiceInstance();
- }
-
- /**
- * Get the requested service by its class (the service has to be registered
- * by its class object).
- *
- * @param key
- * The service class.
- * @return The service.
- * @throws ServiceException
- * If service can't be started
- */
- private Object getServiceFromParents(Object key) throws ServiceException {
-
- Object foundService;
-
- for( ServicesRegistry parent : parents) {
- foundService = parent.getServiceUnchecked(key);
- // Check if we have found the service
- if( foundService != null) {
- // Found, return it
- return foundService;
- }
- }
- // Not found
- return null;
- }
-
- /**
- * Get the requested service by its key. The key is usually the classname of
- * the service.
- * Return the service, or null if not found.
- * This is for internal use.
- *
- * @param serviceClass
- * @return The service, or null if not found.
- * @throws ServiceException
- * If servive can't be started
- */
- protected Object getServiceUnchecked(Object key) throws ServiceException {
- ServiceStartupEntry service = namedServices.get(key);
- if(service == null) {
- return null;
- }
-
- return service.getServiceInstance();
- }
-
- /**
- * Try to get the {@link ServiceStartupEntry} of the specified service.
- * Search in local namedServices.
- * Also lookup in parents. Return null if not found.
- * The returned entry should not be modified by caller.
- *
- * @param key
- * @return The requested entry, or null if not found.
- */
- protected ServiceStartupEntry getServiceStartupEntry( Object key ) {
-
- return getServiceStartupEntry(key, true);
- }
-
- /**
- * Try to get the {@link ServiceStartupEntry} of the specified service.
- * Search in local namedServices.
- * Also lookup in parents. Return null if not found.
- * The returned entry should not be modified by caller.
- *
- * @param key
- * @param searchInParent True if we should search in parent, false if search take place in this registry only.
- * @return The requested entry, or null if not found.
- */
- protected ServiceStartupEntry getServiceStartupEntry( Object key, boolean searchInParent ) {
-
- ServiceStartupEntry service = namedServices.get(key);
- if( service != null) {
- return service;
- }
-
- // Check in new services
- service = addedServices.get(key);
- if( service != null) {
- return service;
- }
-
- if( searchInParent ) {
- // Lookup in parents
- for(ServicesRegistry registry : parents) {
- service = registry.getServiceStartupEntry(key);
- if( service != null) {
- return service;
- }
- }
- }
-
- // Not found
- return null;
- }
-
- /**
- * Return true if the service is instantiated. Return false otherwise.
- *
- * @return
- */
- public boolean isStarted(Object key) throws ServiceNotFoundException {
- return isStarted(key, true);
- }
-
- /**
- * Return true if the service is instantiated. Return false otherwise.
- *
- * @return
- */
- public boolean isStarted(Object key, boolean searchInParents) throws ServiceNotFoundException {
- ServiceStartupEntry service = getServiceStartupEntry(key, searchInParents);
- if(service == null) {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- return service.isStarted();
- }
-
- /**
- * Return true if the service is instantiated. Return false otherwise.
- * The service type is converted to its name, then the method is performed.
- * @see #isStarted(Class)
- *
- * @return
- */
- public boolean isStarted(Class<?> serviceType) throws ServiceNotFoundException {
- return isStarted(serviceType.getName(), true);
- }
-
- /**
- * Return true if the service is instantiated. Return false otherwise.
- * The service type is converted to its name, then the method is performed.
- * @see #isStarted(Class)
- *
- * @return
- */
- public boolean isStarted(Class<?> serviceType, boolean searchInParents) throws ServiceNotFoundException {
- return isStarted(serviceType.getName(), searchInParents);
- }
-
- /**
- * Return the state of the specified service.
- *
- * @return
- */
- public ServiceState serviceState(Object key) throws ServiceNotFoundException {
- return serviceState(key, true);
- }
-
- /**
- * Return the state of the specified service.
- * @param key
- * @param searchInParents
- * @return
- * @throws ServiceNotFoundException
- */
- public ServiceState serviceState(Object key, boolean searchInParents ) throws ServiceNotFoundException {
- ServiceStartupEntry service = getServiceStartupEntry(key, searchInParents);
- if(service == null) {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- return service.getState();
- }
-
- /**
- * Return the state of the specified service.
- *
- * @return
- */
- public ServiceState serviceState(Class<?> serviceType) throws ServiceNotFoundException {
- return serviceState(serviceType.getName(), true);
- }
-
- /**
- * Return the state of the specified service.
- *
- * @return
- */
- public ServiceState serviceState(Class<?> serviceType, boolean searchInParents) throws ServiceNotFoundException {
- return serviceState(serviceType.getName(), searchInParents);
- }
-
- /**
- * Start services newly added.
- * Start all services marked as start = STARTUP.
- * All services are first created, then initialized and finally
- * started. If an error occur on a service during one of this step, the
- * service is removed from the registry and and the error is logged.
-
- * @throws ServiceMultiException
- *
- * @throws ServiceException
- * If a service can't be started.
- *
- */
- public void startNewServices() throws ServiceMultiException {
- // Build the lookup maps
- LookupMap localSpace = new LookupMap(addedServices, namedServices);
- // search space including parents
- LookupMap fullSpace = new LookupMap(addedServices, namedServices, parents);
-
- // Check if all dependencies exist.
- checkDependencies(addedServices.values(), fullSpace);
-
- // Get all roots : LAZY and START
- Collection<ServiceStartupEntry> roots = getServiceRoots(addedServices.values(), localSpace);
- // showServices(" Roots:", roots);
- // Detect cycles
- checkCycle(roots, localSpace);
-
- // Order services in the order we should start them.
- // Lazy services are taken into account, as they can be in a chain of start.
- List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, localSpace);
-
- // Retain only services with startupkind == START
- //
- roots = retainsToStartServices(roots);
-
- if(Activator.log.isDebugEnabled()) {
- showServices(" Services to start:", toStart);
- }
-
- // Create an object to collect errors if any.
- ServiceMultiException errors = new ServiceMultiException();
-
- createServices(toStart, errors);
- // Register all new services : lazy and start
- registerServices(addedServices.values());
- initServices(toStart, errors);
- startServices(toStart, errors);
-
- // Report errors if any
- if(errors.getExceptions().size() > 0)
- throw errors;
-
-
- }
-
- /**
- * Start the registry. Start all services marked as start = STARTUP are
- * started. All services are first created, then initialized and finally
- * started. If an error occur on a service during one of this step, the
- * service is removed from the registry and and the error is logged.
- *
- * @throws ServiceMultiException
- *
- * @throws ServiceException
- * If a service can't be started.
- *
- * @deprecated Use {@link #startNewServices()}
- */
- protected void startRegistry() throws ServiceMultiException {
-
- startNewServices();
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the addServices or already registered. Start all
- * services marked as start = STARTUP . All eligible services are first
- * created, then initialized and finally started. If an error occur on a
- * service during one of this step, the service is removed from the registry
- * and and the error is logged.
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServices(List<String> serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- // Build the lookup maps
- LookupMap map = new LookupMap(addedServices, namedServices);
-
- // Get the services
- List<ServiceStartupEntry> services = keysToServices(serviceKeys, map);
-
- // Start them
- startServices(services, map);
- }
-
- /**
- * Same as {@link #startServices(List)}, but with an array as input.
- *
- * @see #startServices(List)
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServices(String... serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- List<String> serviceKeysList = Arrays.asList(serviceKeys);
- startServices(serviceKeysList);
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the addServices or already registered. Start all
- * services marked as start = STARTUP . All eligible services are first
- * created, then initialized and finally started. If an error occur on a
- * service during one of this step, the service is removed from the registry
- * and and the error is logged.
- *
- * @param serviceKeys
- * Keys of services to start. Keys will be translated to the
- * classname.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServicesByClassKeys(List<Class<?>> serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- // Build the lookup maps
- LookupMap map = new LookupMap(addedServices, namedServices);
-
- // Get the services
- List<ServiceStartupEntry> services = classKeysToServices(serviceKeys, map);
-
- // Start them
- startServices(services, map);
- }
-
- /**
- * Same as {@link #startServicesByClassKeys(List)}, but with an array as
- * input.
- *
- * @see #startServices(List)
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServicesByClassKeys(Class<?>... serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- List<Class<?>> serviceKeysList = Arrays.asList(serviceKeys);
- startServicesByClassKeys(serviceKeysList);
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the specified map. The map is also used to resolves
- * dependencies. Start all services marked as start = STARTUP . All eligible
- * services are first created, then initialized and finally started. If an
- * error occur on a service during one of this step, the service is removed
- * from the registry and and the error is logged.
- *
- * @param services
- * Services to start
- * @param map
- * a table of (key, service) used to get a service by its key.
- * @throws ServiceMultiException
- * If a service can't be started.
- */
- private void startServices(List<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException {
- // Check if all dependencies exist.
- checkDependencies(services, map);
-
- // Get all roots : LAZY and START
- Collection<ServiceStartupEntry> roots = getServiceRoots(services, map);
- if(Activator.log.isDebugEnabled()) {
- showServices(" Roots:", roots);
- }
- // Detect cycles
- checkCycle(roots, map);
- // Retain only services with startupkind == START and state ==
- // REGISTERED
- roots = retainsToStartServices(roots);
- //
- List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map);
-
- // Remove already started services
- toStart = retainsToStartServices(toStart);
-
- // if( log.isLoggable(Level.FINE))
- // {
- showServices(" Services to start:", toStart);
- // }
-
- // Create an object to collect errors if any.
- ServiceMultiException errors = new ServiceMultiException();
-
- createServices(toStart, errors);
- // Register all started services
- registerServices(toStart);
- initServices(toStart, errors);
- startServices(toStart, errors);
-
- // Report errors if any
- if(errors.getExceptions().size() > 0)
- throw errors;
- }
-
- /**
- * Return a list of services from a list of services keys.
- *
- * @param serviceKeys
- * @param map
- * @return
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- */
- private List<ServiceStartupEntry> keysToServices(List<String> serviceKeys, LookupMap map) throws ServiceNotFoundException {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size());
-
- for(String key : serviceKeys) {
- result.add(map.getChecked(key));
- }
- return result;
- }
-
- /**
- * Return a list of services from a list of services keys.
- *
- * @param serviceKeys
- * @param map
- * @return
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- */
- private List<ServiceStartupEntry> classKeysToServices(List<Class<?>> serviceKeys, LookupMap map) throws ServiceNotFoundException {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size());
-
- for(Class<?> key : serviceKeys) {
- result.add(map.getChecked(key.getName()));
- }
- return result;
- }
-
- /**
- * Print the services. For debug purpose
- *
- * @param roots
- */
- private void showServices(String message, Collection<ServiceStartupEntry> roots) {
- StringBuffer buffer = new StringBuffer();
- buffer.append("--------------------------\n");
- buffer.append(message);
- buffer.append("\n");
- for(ServiceStartupEntry service : roots) {
- buffer.append(" ");
- buffer.append(service.getDescriptor().toString());
- buffer.append("\n");
- }
- buffer.append("--------- done -----------\n");
- Activator.log.debug(buffer.toString());
- }
-
- /**
- * Check if all dependencies exist. Throw an error if a declared dependency
- * has no corresponding service.
- *
- * @param services
- * Services to check
- * @param map
- * Map of services by keys.
- * @throws ServiceMultiException
- */
- private void checkDependencies(Collection<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException {
-
- ServiceMultiException errors = new ServiceMultiException();
-
- // Walk each service and check if its required services exist.
- for(ServiceStartupEntry service : services) {
- ServiceDescriptor desc = service.getDescriptor();
-
- // Check each required service
- for(String key : desc.getRequiredServiceKeys()) {
-
- // Check if service can be found
- try {
- map.getChecked(key);
- } catch (ServiceNotFoundException e) {
- errors.addException(desc.getKey(), e);
- }
- }
- }
-
- // Throw errors if any
- if(errors.getExceptions().size() > 0)
- throw errors;
- }
-
- /**
- * Retains only the services that should be started. Retains only services
- * with startupkind = START and state == REGISTERED
- *
- * @param services
- * Collection to filter
- * @return a new Collection containing the services to start.
- */
- private List<ServiceStartupEntry> retainsToStartServices(Collection<ServiceStartupEntry> services) {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>();
- for(ServiceStartupEntry service : services) {
- ServiceDescriptor desc = service.getDescriptor();
- if(service.getState() == ServiceState.registered && desc.isStartAtStartup()) {
- result.add(service);
- }
- }
-
- return result;
- }
-
- /**
- * Check for cycles. Throws an exception if a cycle is discovered. Each root
- * is checked to see if it contains a cycle.
- *
- * @param roots
- * @param map
- */
- private void checkCycle(Collection<ServiceStartupEntry> roots, LookupMap map) {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * Build a list of services to start, in the topological order (right
- * order). The required services are placed before the dependent services in
- * the list. Services already started are disguarded.
- *
- * @param roots
- * @param map
- * Map used to resolve the entry by their key.
- * @return
- */
- private List<ServiceStartupEntry> buildTopologicalListOfServicesToStart(Collection<ServiceStartupEntry> roots, LookupMap map) {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>();
-
- // Each root represent a graph. Walk the root and its child in the list,
- // in the right order.
- for(ServiceStartupEntry root : roots) {
- walkGraphDepthFirst(result, root, map);
- }
-
- return result;
- }
-
- /**
- * Add recursively the provided node, and then its direct children.
- *
- * @param result
- * The list where the node are added
- * @param node
- * The node to add
- * @param map
- */
- private void walkGraphDepthFirst(List<ServiceStartupEntry> result, ServiceStartupEntry node, LookupMap map) {
-
- // Do not add already added or started node.
- if(result.contains(node) || node.isStarted())
- return;
-
- // add direct child
- for(String serviceKey : node.getDescriptor().getRequiredServiceKeys()) {
- try {
- ServiceStartupEntry child = map.getChecked(serviceKey);
- walkGraphDepthFirst(result, child, map);
- } catch (ServiceNotFoundException e) {
- // Do nothing, we have already reported the problems with
- // checkServices;
- }
- }
-
- // Now add the node
- result.add(node);
- }
-
- /**
- * Create a List of the root services. The roots are services that are not
- * required by any service.
- *
- * @param addedServices
- * A collection from which roots are required. The collection is
- * unmodified.
- * @param map
- * @return
- */
- private Collection<ServiceStartupEntry> getServiceRoots(Collection<ServiceStartupEntry> addedServices, LookupMap keyServiceMap) {
-
- // Create a copy of the list of services
- Collection<ServiceStartupEntry> services = new ArrayList<ServiceStartupEntry>(addedServices);
-
- List<ServiceStartupEntry> allRequired = new ArrayList<ServiceStartupEntry>();
-
- // The roots are services that are not required by any service.
- // Build a list of the services required by all other services.
- for(ServiceStartupEntry service : services) {
- // Add each child to the list of required
- for(String serviceKey : service.getDescriptor().getRequiredServiceKeys()) {
- try {
-
- ServiceStartupEntry child = keyServiceMap.getChecked(serviceKey);
- allRequired.add(child);
- } catch (ServiceNotFoundException e) {
- // Do nothing, we have already reported the problems with
- // checkServices;
- }
- }
-
- }
-
- // Roots are those that are not required.
- // So it is the original list minus the required.
- services.removeAll(allRequired);
-
- return services;
- }
-
- /**
- * Dispose all services for this registry and its parents.
- *
- * @throws ServiceMultiException
- */
- public void disposeRegistry() throws ServiceMultiException {
-
- disposeRegistry(true);
- }
-
- /**
- * Dispose all services, and parent registries if any.
- *
- * @throws ServiceMultiException
- */
- public void disposeRegistry(boolean isRecursive) throws ServiceMultiException {
-
- // List of keys of service in error.
- ServiceMultiException errors = new ServiceMultiException();
- disposeRegistry(errors, isRecursive);
- // Report errors if any
- if(errors.getExceptions().size() > 0)
- throw errors;
- }
-
- /**
- * Dispose all services, and parent registries if any.
- *
- * @throws ServiceMultiException
- */
- protected void disposeRegistry(ServiceMultiException errors, boolean isRecursive) throws ServiceMultiException {
-
- // List of keys of service in error.
- disposeServices(namedServices.values(), errors);
- disposeServices(anonymousServices, errors);
-
- // Clean up properties to help GC
- addedServices.clear();
- addedServices = null;
- anonymousServices.clear();
- anonymousServices = null;
- namedServices.clear();
- namedServices = null;
-
- // Do parents
- if( isRecursive ) {
- for( ServicesRegistry parent : parents) {
- parent.disposeRegistry( errors, true);
- }
- }
- }
-
- /**
- * Create all services provided in the list
- *
- * @param toStart
- * List of services to create.
- * @param errors
- * Exception to collect errors.
- *
- * @throws ServiceMultiException
- * If an error occure during the creation
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void createServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException {
-
- // Loop on all services
- for(ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.createService();
- } catch (ServiceException e) {
- log.log(Level.SEVERE, "Can't create service '" + serviceEntry + "'", e);
-
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Register all services provided in the list. After this operation,
- * services are available thru {@link #getService(Class)}.
- *
- * @param toStart
- * List of services to register.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void registerServices(Collection<ServiceStartupEntry> toStart) {
-
- // Loop on all services
- for(ServiceStartupEntry serviceEntry : toStart) {
- ServiceDescriptor desc = serviceEntry.getDescriptor();
- if(desc.isAnonymous()) {
- anonymousServices.add(serviceEntry);
- } else {
- namedServices.put(desc.getKey(), serviceEntry);
- }
- }
- }
-
- /**
- * Init all services provided in the list
- *
- * @param toStart
- * List of services to init.
- * @param errors
- *
- * @throws ServiceMultiException
- * If an error occure during the process
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void initServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException {
-
- // Loop on all services
- for(ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.initService(this);
- } catch (ServiceException e) {
- log.log(Level.SEVERE, "Can't initialize service '" + serviceEntry + "'", e);
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Init all services provided in the list
- *
- * @param toStart
- * List of services to init.
- * @param errors
- *
- * @throws ServiceMultiException
- * If an error occure during the process
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void startServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException {
-
- // Loop on all services
- for(ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.startService();
- } catch (ServiceException e) {
- log.log(Level.SEVERE, "Can't start service '" + serviceEntry + "'", e);
-
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Dispose all started services.
- * Services are disposed in creation reverse order
- *
- * @throws ServiceMultiException
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void disposeServices(Collection<ServiceStartupEntry> services, ServiceMultiException errors) {
-
- // Dispose services
- for(ServiceStartupEntry serviceEntry : services) {
- try {
- serviceEntry.disposeService();
- } catch (ServiceException e) {
- log.log(Level.SEVERE, "Can't dispose service '" + serviceEntry.getDescriptor().getKey() + "'", e);
- errors.addException(serviceEntry.getDescriptor(), e);
- }
- }
- }
-
- /**
- * This class represents a union of two maps of <String,
- * ServiceStartupEntry>. It provide specific methods to retrieve a {@link ServiceStartupEntry} by its key.
- * <br>
- * This class is used to lookup {@link ServiceStartupEntry} in multiple namespaces (2 maps, and then registries).
- *
- *
- * @author cedric dumoulin
- *
- */
- private class LookupMap {
-
- Map<String, ServiceStartupEntry> map1;
-
- Map<String, ServiceStartupEntry> map2;
-
- // additional service registries into which we should search
- List<ServicesRegistry> registries;
-
- /**
- *
- * Constructor. Build a union of two maps.
- *
- * @param map1
- * @param map2
- */
- public LookupMap(Map<String, ServiceStartupEntry> map1, Map<String, ServiceStartupEntry> map2) {
- this.map1 = map1;
- this.map2 = map2;
- }
-
- public LookupMap(Map<String, ServiceStartupEntry> space1, Map<String, ServiceStartupEntry> space2, List<ServicesRegistry> registries) {
- this( space1, space2);
- this.registries = registries;
- }
-
- /**
- *
- * Constructor. Build a union of one map (sic).
- *
- * @param map
- */
- @SuppressWarnings("unused")
- public LookupMap(Map<String, ServiceStartupEntry> map) {
- this(map, null);
- }
-
- /**
- * Get a service by its key.
- *
- * @param key
- * @return the service or null if not found.
- */
- @SuppressWarnings("unused")
- public ServiceStartupEntry get(String key) {
-
- ServiceStartupEntry res = map1.get(key);
- if(res != null)
- return res;
- if(map2 != null) {
- res = map2.get(key);
- }
- if( res == null && registries != null) {
- // lookup in registries
- res = getFromRegistries(key);
- }
-
- return res;
- }
-
- /**
- * Get a service by its key.
- *
- * @param key
- * @return The requested service.
- * @throws ServiceNotFoundException
- * if the service can't be found.
- */
- public ServiceStartupEntry getChecked(String key) throws ServiceNotFoundException {
-
- ServiceStartupEntry res = map1.get(key);
- if(res != null)
- return res;
- if(map2 != null)
- res = map2.get(key);
- if( res == null && registries != null) {
- // lookup in registries
- res = getFromRegistries(key);
- }
- if(res != null)
- return res;
-
- throw new ServiceNotFoundException("No service found under key '" + key.toString() + "'");
- }
-
- /**
- * Try to get the entry from the registries.
- * @param key
- * @return
- */
- private ServiceStartupEntry getFromRegistries(String key) {
-
- ServiceStartupEntry service;
- // Lookup in parents
- for(ServicesRegistry registry : registries) {
- service = registry.getServiceStartupEntry(key);
- if( service != null) {
- return service;
- }
- }
-
- return null;
- }
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 LIFL and others. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIFL - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.serviceregistry; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.papyrus.infra.core.serviceregistry.ServiceDescriptor.ServiceTypeKind; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.AliasServiceEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.LazyStartupEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.PojoServiceEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceFactoryEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceStartupEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.ServiceTypeEntry; +import org.eclipse.papyrus.infra.core.serviceregistry.internal.StartStartupEntry; + +/** + * A registry of services. This registry allows to get a service by its + * identifier. The identifier is generally the classname of the service. + * Services can be added using the Eclipse extension mechanism (if you use {@link ExtensionServicesRegistry}). <br> + * A Service is a class providing operations. The ServiceRegistry is used to + * share objects (i.e. services) between nested editors and also the core main + * editor. + * + * <br> + * In this implementation, services should be added to the registry before the + * call to createServices(). If a service is added after the call, it will not + * be started (except if it is a lazy service). <br> + * A typical usage is: + * + * <pre> + * <code> + * ServicesRegistry serviceRegistry = new ServiceRegistry(); + * // Add your services + * serviceRegistry.add( ...); + * serviceRegistry.add( ...); + * + * // start the services + * serviceRegistry.startRegistry(); + * + * // Retrieve a service + * myService = serviceRegistry.getService( serviceKey ); + * </code> + * </pre> + * + * It is possible to register new services after the serviceRegistry has been + * started. In this case, you need to start them explicitly if they are of type + * ServiceStartKind.STARTUP. + * + * <pre> + * <code> + * // Add your new services + * serviceRegistry.add( key1, ...); + * serviceRegistry.add( key2, ...); + * + * // start the new services + * serviceRegistry.startRegistry(key1, key2); + * </code> + * </pre> + * + * <ul> + * <li></li> + * <li></li> + * </ul> + * + * @author cedric dumoulin + * + * + */ +public class ServicesRegistry { + + /** Log object */ + protected Logger log = Logger.getLogger(getClass().getName()); + + /** + * Map of existing services. + */ + // private Map<Object, AbstractServiceEntry> services; + + /** + * A Map of services added to the register (thow the addXxx() methods), but + * not yet registered. They will be registered after a call to startXxx(). + */ + private Map<String, ServiceStartupEntry> addedServices = new HashMap<String, ServiceStartupEntry>(); + + /** + * Map of services registered with a name. + */ + private Map<String, ServiceStartupEntry> namedServices = new HashMap<String, ServiceStartupEntry>(); + + /** + * Map of services registered without a name (anonymous). Such services + * can't be retrieved. + */ + private List<ServiceStartupEntry> anonymousServices = new ArrayList<ServiceStartupEntry>(); + + /** + * List of parents used as fallback if the service is not found in this registry. + */ + private List<ServicesRegistry> parents = new ArrayList<ServicesRegistry>(); + + /** + * Constructor. + */ + public ServicesRegistry() { + } + + /** + * Add a service by its ServiceDescriptor. + * + * @param serviceDescriptor + * Descriptor describing the service. + * @throws ServiceException + * If an error occurs while initializing service. + */ + public void add(ServiceDescriptor serviceDescriptor) { + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(serviceDescriptor.getKey()); + if(service != null) { + if(service.getDescriptor().getPriority() > serviceDescriptor.getPriority()) + return; + else if(service.getDescriptor().getPriority() == serviceDescriptor.getPriority()) { + log.warning("Two services with same priority (" + serviceDescriptor.getPriority() + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only. (bundles: " + service.getDescriptor().getClassBundleID() + ", " + serviceDescriptor.getClassBundleID() + ")"); + } + } + + // Compute the service type entry + ServiceTypeEntry serviceTypeEntry; + ServiceTypeKind typeKind = serviceDescriptor.getServiceTypeKind(); + switch( typeKind) { + case service: + serviceTypeEntry = new ServiceEntry(serviceDescriptor); + break; + case serviceFactory: + serviceTypeEntry = new ServiceFactoryEntry(serviceDescriptor); + break; + case pojo: + serviceTypeEntry = new PojoServiceEntry(serviceDescriptor); + break; + case alias: + serviceTypeEntry = new AliasServiceEntry(serviceDescriptor); + break; + default: + // Add as pojo + // Should better throw an exception. (MalformedDescriptor ?) + serviceTypeEntry = new PojoServiceEntry(serviceDescriptor); + } + + // Create the entry + ServiceStartupEntry serviceEntry; + switch(serviceDescriptor.getServiceStartKind()) { + case STARTUP: + serviceEntry = new StartStartupEntry(serviceTypeEntry); + break; + case LAZY: + serviceEntry = new LazyStartupEntry(serviceTypeEntry, this); + break; + default: + // Add as LAZY + // Should better throw an exception. (MalformedDescriptor ?) + serviceEntry = new LazyStartupEntry(serviceTypeEntry, this); + } + + // Add the entry + addedServices.put(serviceDescriptor.getKey(), serviceEntry); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(String key, int priority, IService serviceInstance) { + add(key, priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, IService serviceInstance) { + add(key.getName(), priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(String key, int priority, IService serviceInstance, ServiceStartKind startKind) { + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(key); + if(service != null) { + if(service.getDescriptor().getPriority() > priority) + return; + else if(service.getDescriptor().getPriority() == priority) + log.warning("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + // Create descriptor and add service. + ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority); + + if(startKind == ServiceStartKind.STARTUP) + addedServices.put(key, new StartStartupEntry(new ServiceEntry(descriptor, serviceInstance))); + else + addedServices.put(key, new LazyStartupEntry(new ServiceEntry(descriptor, serviceInstance), this)); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key Class used as key. The classname is used as key. + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, IService serviceInstance, ServiceStartKind startKind) { + + add(key.getName(), priority, serviceInstance, startKind); + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, Object serviceInstance) { + add(key, priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + * @param startKind + * + */ + public void add(String key, int priority, Object serviceInstance, ServiceStartKind startKind) { + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(key); + if(service != null) { + if(service.getDescriptor().getPriority() > priority) + return; + else if(service.getDescriptor().getPriority() == priority) + log.warning("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + // Create descriptor and add service. + ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority); + + if(startKind == ServiceStartKind.STARTUP) + addedServices.put(key, new StartStartupEntry(new PojoServiceEntry(descriptor, serviceInstance))); + else + addedServices.put(key, new LazyStartupEntry(new PojoServiceEntry(descriptor, serviceInstance), this)); + + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key Class used as key. The classname is used as key. + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + * @param startKind + * + */ + public void add(Class<?> key, int priority, Object serviceInstance, ServiceStartKind startKind) { + + add(key.getName(), priority, serviceInstance, startKind); + } + + /** + * Remove the specified Registry as parent of this registry. + * . + * @param parentRegistry + */ + public void addParentRegistry(ServicesRegistry parentRegistry) { + + if( parentRegistry == null) { + return; + } + parents.add(parentRegistry); + } + + /** + * + * @param parentRegistry + */ + public void removeParentRegistry(ServicesRegistry parentRegistry) { + + if( parentRegistry == null) { + return; + } + parents.remove(parentRegistry); + } + + + /** + * Remove the specified service from the registry. + * + * @param key + */ + public void remove(ServiceDescriptor serviceDescriptor) throws ServiceException { + remove(serviceDescriptor.getKey()); + } + + /** + * Remove the specified service from the registry. + * + * @param key + */ + public void remove(Object key) throws ServiceException { + ServiceStartupEntry service = namedServices.remove(key); + if(service == null) { + return; + } + + // Stop the service + service.disposeService(); + } + + /** + * Get the requested service by its key. The key is usually the classname of + * the service. + * + * @param serviceClass + * @return + * @throws ServiceException + * If servive can't be started + */ + public Object getService(Object key) throws ServiceException { + ServiceStartupEntry serviceEntry = namedServices.get(key); + if(serviceEntry == null) { + // Check if we can find it in parents + Object service = getServiceFromParents(key); + if(service != null) { + // Found in parent, return it + return service; + } + + // Not found in parents. Throw an exception + // throw an appropriate exception (If added, say it). + serviceEntry = addedServices.get(key); + if(serviceEntry != null) + throw new BadStateException("Registry should be started before.", serviceEntry.getState(), serviceEntry.getDescriptor()); //$NON-NLS-1$ + else + throw new ServiceNotFoundException("No service registered under '" + key + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + return serviceEntry.getServiceInstance(); + } + + /** + * Get the requested service by its class (the service has to be registered + * by its class object). + * + * @param key + * The service class. + * @return The service. + * @throws ServiceException + * If service can't be started + */ + @SuppressWarnings("unchecked") + public <S> S getService(Class<S> key) throws ServiceException { + + String realKey = key.getName(); + ServiceStartupEntry serviceEntry = namedServices.get(realKey); + + // Lookup in parents if not found + if( serviceEntry == null) { + + // Check if we can find it in parents + S service = (S)getServiceFromParents(realKey); + if(service != null) { + // Found in parent, return it + return service; + } + + // Not found in parents. Throw an exception + // throw an appropriate exception (If added, say it). + serviceEntry = addedServices.get(realKey); + if(serviceEntry != null) + throw new BadStateException("Registry should be started before.", serviceEntry.getState(), serviceEntry.getDescriptor()); //$NON-NLS-1$ + else + throw new ServiceNotFoundException("No service registered under '" + key + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + // Service found, return it. + return (S)serviceEntry.getServiceInstance(); + } + + /** + * Get the requested service by its class (the service has to be registered + * by its class object). + * + * @param key + * The service class. + * @return The service. + * @throws ServiceException + * If service can't be started + */ + private Object getServiceFromParents(Object key) throws ServiceException { + + Object foundService; + + for( ServicesRegistry parent : parents) { + foundService = parent.getServiceUnchecked(key); + // Check if we have found the service + if( foundService != null) { + // Found, return it + return foundService; + } + } + // Not found + return null; + } + + /** + * Get the requested service by its key. The key is usually the classname of + * the service. + * Return the service, or null if not found. + * This is for internal use. + * + * @param serviceClass + * @return The service, or null if not found. + * @throws ServiceException + * If servive can't be started + */ + protected Object getServiceUnchecked(Object key) throws ServiceException { + ServiceStartupEntry service = namedServices.get(key); + if(service == null) { + return null; + } + + return service.getServiceInstance(); + } + + /** + * Try to get the {@link ServiceStartupEntry} of the specified service. + * Search in local namedServices. + * Also lookup in parents. Return null if not found. + * The returned entry should not be modified by caller. + * + * @param key + * @return The requested entry, or null if not found. + */ + protected ServiceStartupEntry getServiceStartupEntry( Object key ) { + + return getServiceStartupEntry(key, true); + } + + /** + * Try to get the {@link ServiceStartupEntry} of the specified service. + * Search in local namedServices. + * Also lookup in parents. Return null if not found. + * The returned entry should not be modified by caller. + * + * @param key + * @param searchInParent True if we should search in parent, false if search take place in this registry only. + * @return The requested entry, or null if not found. + */ + protected ServiceStartupEntry getServiceStartupEntry( Object key, boolean searchInParent ) { + + ServiceStartupEntry service = namedServices.get(key); + if( service != null) { + return service; + } + + // Check in new services + service = addedServices.get(key); + if( service != null) { + return service; + } + + if( searchInParent ) { + // Lookup in parents + for(ServicesRegistry registry : parents) { + service = registry.getServiceStartupEntry(key); + if( service != null) { + return service; + } + } + } + + // Not found + return null; + } + + /** + * Return true if the service is instantiated. Return false otherwise. + * + * @return + */ + public boolean isStarted(Object key) throws ServiceNotFoundException { + return isStarted(key, true); + } + + /** + * Return true if the service is instantiated. Return false otherwise. + * + * @return + */ + public boolean isStarted(Object key, boolean searchInParents) throws ServiceNotFoundException { + ServiceStartupEntry service = getServiceStartupEntry(key, searchInParents); + if(service == null) { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + return service.isStarted(); + } + + /** + * Return true if the service is instantiated. Return false otherwise. + * The service type is converted to its name, then the method is performed. + * @see #isStarted(Class) + * + * @return + */ + public boolean isStarted(Class<?> serviceType) throws ServiceNotFoundException { + return isStarted(serviceType.getName(), true); + } + + /** + * Return true if the service is instantiated. Return false otherwise. + * The service type is converted to its name, then the method is performed. + * @see #isStarted(Class) + * + * @return + */ + public boolean isStarted(Class<?> serviceType, boolean searchInParents) throws ServiceNotFoundException { + return isStarted(serviceType.getName(), searchInParents); + } + + /** + * Return the state of the specified service. + * + * @return + */ + public ServiceState serviceState(Object key) throws ServiceNotFoundException { + return serviceState(key, true); + } + + /** + * Return the state of the specified service. + * @param key + * @param searchInParents + * @return + * @throws ServiceNotFoundException + */ + public ServiceState serviceState(Object key, boolean searchInParents ) throws ServiceNotFoundException { + ServiceStartupEntry service = getServiceStartupEntry(key, searchInParents); + if(service == null) { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + return service.getState(); + } + + /** + * Return the state of the specified service. + * + * @return + */ + public ServiceState serviceState(Class<?> serviceType) throws ServiceNotFoundException { + return serviceState(serviceType.getName(), true); + } + + /** + * Return the state of the specified service. + * + * @return + */ + public ServiceState serviceState(Class<?> serviceType, boolean searchInParents) throws ServiceNotFoundException { + return serviceState(serviceType.getName(), searchInParents); + } + + /** + * Start services newly added. + * Start all services marked as start = STARTUP. + * All services are first created, then initialized and finally + * started. If an error occur on a service during one of this step, the + * service is removed from the registry and and the error is logged. + + * @throws ServiceMultiException + * + * @throws ServiceException + * If a service can't be started. + * + */ + public void startNewServices() throws ServiceMultiException { + // Build the lookup maps + LookupMap localSpace = new LookupMap(addedServices, namedServices); + // search space including parents + LookupMap fullSpace = new LookupMap(addedServices, namedServices, parents); + + // Check if all dependencies exist. + checkDependencies(addedServices.values(), fullSpace); + + // Get all roots : LAZY and START + Collection<ServiceStartupEntry> roots = getServiceRoots(addedServices.values(), localSpace); + // showServices(" Roots:", roots); + // Detect cycles + checkCycle(roots, localSpace); + + // Order services in the order we should start them. + // Lazy services are taken into account, as they can be in a chain of start. + List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, localSpace); + + // Retain only services with startupkind == START + // + roots = retainsToStartServices(roots); + + if(Activator.log.isDebugEnabled()) { + showServices(" Services to start:", toStart); + } + + // Create an object to collect errors if any. + ServiceMultiException errors = new ServiceMultiException(); + + createServices(toStart, errors); + // Register all new services : lazy and start + registerServices(addedServices.values()); + initServices(toStart, errors); + startServices(toStart, errors); + + // Report errors if any + if(errors.getExceptions().size() > 0) + throw errors; + + + } + + /** + * Start the registry. Start all services marked as start = STARTUP are + * started. All services are first created, then initialized and finally + * started. If an error occur on a service during one of this step, the + * service is removed from the registry and and the error is logged. + * + * @throws ServiceMultiException + * + * @throws ServiceException + * If a service can't be started. + * + * @deprecated Use {@link #startNewServices()} + */ + protected void startRegistry() throws ServiceMultiException { + + startNewServices(); + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the addServices or already registered. Start all + * services marked as start = STARTUP . All eligible services are first + * created, then initialized and finally started. If an error occur on a + * service during one of this step, the service is removed from the registry + * and and the error is logged. + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServices(List<String> serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + // Build the lookup maps + LookupMap map = new LookupMap(addedServices, namedServices); + + // Get the services + List<ServiceStartupEntry> services = keysToServices(serviceKeys, map); + + // Start them + startServices(services, map); + } + + /** + * Same as {@link #startServices(List)}, but with an array as input. + * + * @see #startServices(List) + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServices(String... serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + List<String> serviceKeysList = Arrays.asList(serviceKeys); + startServices(serviceKeysList); + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the addServices or already registered. Start all + * services marked as start = STARTUP . All eligible services are first + * created, then initialized and finally started. If an error occur on a + * service during one of this step, the service is removed from the registry + * and and the error is logged. + * + * @param serviceKeys + * Keys of services to start. Keys will be translated to the + * classname. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServicesByClassKeys(List<Class<?>> serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + // Build the lookup maps + LookupMap map = new LookupMap(addedServices, namedServices); + + // Get the services + List<ServiceStartupEntry> services = classKeysToServices(serviceKeys, map); + + // Start them + startServices(services, map); + } + + /** + * Same as {@link #startServicesByClassKeys(List)}, but with an array as + * input. + * + * @see #startServices(List) + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServicesByClassKeys(Class<?>... serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + List<Class<?>> serviceKeysList = Arrays.asList(serviceKeys); + startServicesByClassKeys(serviceKeysList); + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the specified map. The map is also used to resolves + * dependencies. Start all services marked as start = STARTUP . All eligible + * services are first created, then initialized and finally started. If an + * error occur on a service during one of this step, the service is removed + * from the registry and and the error is logged. + * + * @param services + * Services to start + * @param map + * a table of (key, service) used to get a service by its key. + * @throws ServiceMultiException + * If a service can't be started. + */ + private void startServices(List<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException { + // Check if all dependencies exist. + checkDependencies(services, map); + + // Get all roots : LAZY and START + Collection<ServiceStartupEntry> roots = getServiceRoots(services, map); + if(Activator.log.isDebugEnabled()) { + showServices(" Roots:", roots); + } + // Detect cycles + checkCycle(roots, map); + // Retain only services with startupkind == START and state == + // REGISTERED + roots = retainsToStartServices(roots); + // + List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map); + + // Remove already started services + toStart = retainsToStartServices(toStart); + + // if( log.isLoggable(Level.FINE)) + // { + showServices(" Services to start:", toStart); + // } + + // Create an object to collect errors if any. + ServiceMultiException errors = new ServiceMultiException(); + + createServices(toStart, errors); + // Register all started services + registerServices(toStart); + initServices(toStart, errors); + startServices(toStart, errors); + + // Report errors if any + if(errors.getExceptions().size() > 0) + throw errors; + } + + /** + * Return a list of services from a list of services keys. + * + * @param serviceKeys + * @param map + * @return + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + */ + private List<ServiceStartupEntry> keysToServices(List<String> serviceKeys, LookupMap map) throws ServiceNotFoundException { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size()); + + for(String key : serviceKeys) { + result.add(map.getChecked(key)); + } + return result; + } + + /** + * Return a list of services from a list of services keys. + * + * @param serviceKeys + * @param map + * @return + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + */ + private List<ServiceStartupEntry> classKeysToServices(List<Class<?>> serviceKeys, LookupMap map) throws ServiceNotFoundException { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size()); + + for(Class<?> key : serviceKeys) { + result.add(map.getChecked(key.getName())); + } + return result; + } + + /** + * Print the services. For debug purpose + * + * @param roots + */ + private void showServices(String message, Collection<ServiceStartupEntry> roots) { + StringBuffer buffer = new StringBuffer(); + buffer.append("--------------------------\n"); + buffer.append(message); + buffer.append("\n"); + for(ServiceStartupEntry service : roots) { + buffer.append(" "); + buffer.append(service.getDescriptor().toString()); + buffer.append("\n"); + } + buffer.append("--------- done -----------\n"); + Activator.log.debug(buffer.toString()); + } + + /** + * Check if all dependencies exist. Throw an error if a declared dependency + * has no corresponding service. + * + * @param services + * Services to check + * @param map + * Map of services by keys. + * @throws ServiceMultiException + */ + private void checkDependencies(Collection<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException { + + ServiceMultiException errors = new ServiceMultiException(); + + // Walk each service and check if its required services exist. + for(ServiceStartupEntry service : services) { + ServiceDescriptor desc = service.getDescriptor(); + + // Check each required service + for(String key : desc.getRequiredServiceKeys()) { + + // Check if service can be found + try { + map.getChecked(key); + } catch (ServiceNotFoundException e) { + errors.addException(desc.getKey(), e); + } + } + } + + // Throw errors if any + if(errors.getExceptions().size() > 0) + throw errors; + } + + /** + * Retains only the services that should be started. Retains only services + * with startupkind = START and state == REGISTERED + * + * @param services + * Collection to filter + * @return a new Collection containing the services to start. + */ + private List<ServiceStartupEntry> retainsToStartServices(Collection<ServiceStartupEntry> services) { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(); + for(ServiceStartupEntry service : services) { + ServiceDescriptor desc = service.getDescriptor(); + if(service.getState() == ServiceState.registered && desc.isStartAtStartup()) { + result.add(service); + } + } + + return result; + } + + /** + * Check for cycles. Throws an exception if a cycle is discovered. Each root + * is checked to see if it contains a cycle. + * + * @param roots + * @param map + */ + private void checkCycle(Collection<ServiceStartupEntry> roots, LookupMap map) { + // TODO Auto-generated method stub + + } + + /** + * Build a list of services to start, in the topological order (right + * order). The required services are placed before the dependent services in + * the list. Services already started are disguarded. + * + * @param roots + * @param map + * Map used to resolve the entry by their key. + * @return + */ + private List<ServiceStartupEntry> buildTopologicalListOfServicesToStart(Collection<ServiceStartupEntry> roots, LookupMap map) { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(); + + // Each root represent a graph. Walk the root and its child in the list, + // in the right order. + for(ServiceStartupEntry root : roots) { + walkGraphDepthFirst(result, root, map); + } + + return result; + } + + /** + * Add recursively the provided node, and then its direct children. + * + * @param result + * The list where the node are added + * @param node + * The node to add + * @param map + */ + private void walkGraphDepthFirst(List<ServiceStartupEntry> result, ServiceStartupEntry node, LookupMap map) { + + // Do not add already added or started node. + if(result.contains(node) || node.isStarted()) + return; + + // add direct child + for(String serviceKey : node.getDescriptor().getRequiredServiceKeys()) { + try { + ServiceStartupEntry child = map.getChecked(serviceKey); + walkGraphDepthFirst(result, child, map); + } catch (ServiceNotFoundException e) { + // Do nothing, we have already reported the problems with + // checkServices; + } + } + + // Now add the node + result.add(node); + } + + /** + * Create a List of the root services. The roots are services that are not + * required by any service. + * + * @param addedServices + * A collection from which roots are required. The collection is + * unmodified. + * @param map + * @return + */ + private Collection<ServiceStartupEntry> getServiceRoots(Collection<ServiceStartupEntry> addedServices, LookupMap keyServiceMap) { + + // Create a copy of the list of services + Collection<ServiceStartupEntry> services = new ArrayList<ServiceStartupEntry>(addedServices); + + List<ServiceStartupEntry> allRequired = new ArrayList<ServiceStartupEntry>(); + + // The roots are services that are not required by any service. + // Build a list of the services required by all other services. + for(ServiceStartupEntry service : services) { + // Add each child to the list of required + for(String serviceKey : service.getDescriptor().getRequiredServiceKeys()) { + try { + + ServiceStartupEntry child = keyServiceMap.getChecked(serviceKey); + allRequired.add(child); + } catch (ServiceNotFoundException e) { + // Do nothing, we have already reported the problems with + // checkServices; + } + } + + } + + // Roots are those that are not required. + // So it is the original list minus the required. + services.removeAll(allRequired); + + return services; + } + + /** + * Dispose all services for this registry and its parents. + * + * @throws ServiceMultiException + */ + public void disposeRegistry() throws ServiceMultiException { + + disposeRegistry(true); + } + + /** + * Dispose all services, and parent registries if any. + * + * @throws ServiceMultiException + */ + public void disposeRegistry(boolean isRecursive) throws ServiceMultiException { + + // List of keys of service in error. + ServiceMultiException errors = new ServiceMultiException(); + disposeRegistry(errors, isRecursive); + // Report errors if any + if(errors.getExceptions().size() > 0) + throw errors; + } + + /** + * Dispose all services, and parent registries if any. + * + * @throws ServiceMultiException + */ + protected void disposeRegistry(ServiceMultiException errors, boolean isRecursive) throws ServiceMultiException { + + // List of keys of service in error. + disposeServices(namedServices.values(), errors); + disposeServices(anonymousServices, errors); + + // Clean up properties to help GC + addedServices.clear(); + addedServices = null; + anonymousServices.clear(); + anonymousServices = null; + namedServices.clear(); + namedServices = null; + + // Do parents + if( isRecursive ) { + for( ServicesRegistry parent : parents) { + parent.disposeRegistry( errors, true); + } + } + } + + /** + * Create all services provided in the list + * + * @param toStart + * List of services to create. + * @param errors + * Exception to collect errors. + * + * @throws ServiceMultiException + * If an error occure during the creation + * + * @throws ServiceException + * If a service can't be started. + */ + private void createServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException { + + // Loop on all services + for(ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.createService(); + } catch (ServiceException e) { + log.log(Level.SEVERE, "Can't create service '" + serviceEntry + "'", e); //$NON-NLS-1$ //$NON-NLS-2$ + + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Register all services provided in the list. After this operation, + * services are available thru {@link #getService(Class)}. + * + * @param toStart + * List of services to register. + * + * @throws ServiceException + * If a service can't be started. + */ + private void registerServices(Collection<ServiceStartupEntry> toStart) { + + // Loop on all services + for(ServiceStartupEntry serviceEntry : toStart) { + ServiceDescriptor desc = serviceEntry.getDescriptor(); + if(desc.isAnonymous()) { + anonymousServices.add(serviceEntry); + } else { + namedServices.put(desc.getKey(), serviceEntry); + } + } + } + + /** + * Init all services provided in the list + * + * @param toStart + * List of services to init. + * @param errors + * + * @throws ServiceMultiException + * If an error occure during the process + * + * @throws ServiceException + * If a service can't be started. + */ + private void initServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException { + + // Loop on all services + for(ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.initService(this); + } catch (ServiceException e) { + log.log(Level.SEVERE, "Can't initialize service '" + serviceEntry + "'", e); //$NON-NLS-1$ //$NON-NLS-2$ + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Init all services provided in the list + * + * @param toStart + * List of services to init. + * @param errors + * + * @throws ServiceMultiException + * If an error occure during the process + * + * @throws ServiceException + * If a service can't be started. + */ + private void startServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) throws ServiceMultiException { + + // Loop on all services + for(ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.startService(); + } catch (ServiceException e) { + log.log(Level.SEVERE, "Can't start service '" + serviceEntry + "'", e); //$NON-NLS-1$ //$NON-NLS-2$ + + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Dispose all started services. + * Services are disposed in creation reverse order + * + * @throws ServiceMultiException + * + * @throws ServiceException + * If a service can't be started. + */ + private void disposeServices(Collection<ServiceStartupEntry> services, ServiceMultiException errors) { + + // Dispose services + for(ServiceStartupEntry serviceEntry : services) { + try { + serviceEntry.disposeService(); + } catch (ServiceException e) { + log.log(Level.SEVERE, "Can't dispose service '" + serviceEntry.getDescriptor().getKey() + "'", e); //$NON-NLS-1$ //$NON-NLS-2$ + errors.addException(serviceEntry.getDescriptor(), e); + } + } + } + + /** + * This class represents a union of two maps of <String, + * ServiceStartupEntry>. It provide specific methods to retrieve a {@link ServiceStartupEntry} by its key. + * <br> + * This class is used to lookup {@link ServiceStartupEntry} in multiple namespaces (2 maps, and then registries). + * + * + * @author cedric dumoulin + * + */ + private class LookupMap { + + Map<String, ServiceStartupEntry> map1; + + Map<String, ServiceStartupEntry> map2; + + // additional service registries into which we should search + List<ServicesRegistry> registries; + + /** + * + * Constructor. Build a union of two maps. + * + * @param map1 + * @param map2 + */ + public LookupMap(Map<String, ServiceStartupEntry> map1, Map<String, ServiceStartupEntry> map2) { + this.map1 = map1; + this.map2 = map2; + } + + public LookupMap(Map<String, ServiceStartupEntry> space1, Map<String, ServiceStartupEntry> space2, List<ServicesRegistry> registries) { + this( space1, space2); + this.registries = registries; + } + + /** + * + * Constructor. Build a union of one map (sic). + * + * @param map + */ + @SuppressWarnings("unused") + public LookupMap(Map<String, ServiceStartupEntry> map) { + this(map, null); + } + + /** + * Get a service by its key. + * + * @param key + * @return the service or null if not found. + */ + @SuppressWarnings("unused") + public ServiceStartupEntry get(String key) { + + ServiceStartupEntry res = map1.get(key); + if(res != null) + return res; + if(map2 != null) { + res = map2.get(key); + } + if( res == null && registries != null) { + // lookup in registries + res = getFromRegistries(key); + } + + return res; + } + + /** + * Get a service by its key. + * + * @param key + * @return The requested service. + * @throws ServiceNotFoundException + * if the service can't be found. + */ + public ServiceStartupEntry getChecked(String key) throws ServiceNotFoundException { + + ServiceStartupEntry res = map1.get(key); + if(res != null) + return res; + if(map2 != null) + res = map2.get(key); + if( res == null && registries != null) { + // lookup in registries + res = getFromRegistries(key); + } + if(res != null) + return res; + + throw new ServiceNotFoundException("No service found under key '" + key.toString() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Try to get the entry from the registries. + * @param key + * @return + */ + private ServiceStartupEntry getFromRegistries(String key) { + + ServiceStartupEntry service; + // Lookup in parents + for(ServicesRegistry registry : registries) { + service = registry.getServiceStartupEntry(key); + if( service != null) { + return service; + } + } + + return null; + } + } + +} |