/**
*
*/
package org.eclipse.papyrus.infra.core.services;
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.services.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;
}
}