/** * Optimus, framework for Model Transformation * * Copyright (C) 2013 Worldline or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.atos.optimus.m2m.engine.sdk.tom.extension.datasource; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import net.atos.optimus.m2m.engine.core.requirements.AbstractRequirement; import net.atos.optimus.m2m.engine.core.transformations.DefaultTransformationSet; import net.atos.optimus.m2m.engine.core.transformations.ITransformationFactory; import net.atos.optimus.m2m.engine.core.transformations.TransformationDataSource; import net.atos.optimus.m2m.engine.core.transformations.TransformationReference; import net.atos.optimus.m2m.engine.sdk.tom.Requirement; import net.atos.optimus.m2m.engine.sdk.tom.Transformation; import net.atos.optimus.m2m.engine.sdk.tom.TransformationSet; import net.atos.optimus.m2m.engine.sdk.tom.TransformationSetExtension; import net.atos.optimus.m2m.engine.sdk.tom.TransformationSets; import net.atos.optimus.m2m.engine.sdk.tom.extension.Activator; import net.atos.optimus.m2m.engine.sdk.tom.extension.logging.DependencyDiagramMessages; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.osgi.framework.Bundle; /** * Transformation Data Source based on transformation dependency diagrams * extension point. * * @author tnachtergaele <nachtergaele.thomas@gmail.com> * * */ public class ExtensionPointTransformationDiagramDataSource extends TransformationDataSource { /** The description of the transformation data source */ public static final String DESCRIPTION = "Optimus Transformation Dependency Diagram Extension Point Transformation Data Source"; /** The name of the associated extension point */ public static final String EXTENSION_POINT_NAME = "TransformationDependencyDiagrams"; /** The name of the element in the extension */ public static final String EXTENSION_ELEMENT = "transformationDependencyDiagram"; /** The name of the attribute containing the .tom file */ public static final String ATTRIBUTE_DIAGRAM = "diagram"; /** The extension of diagram file */ public static final String EXTENSION_DIAGRAM = ".tom"; /** * Map that holds the transformation references, sorted by id */ protected Map<String, TransformationReference> transformationReferencesMap; /** * Map that holds the transformation sets (Optimus) by ID. */ protected Map<String, net.atos.optimus.m2m.engine.core.transformations.TransformationSet> transformationSetsMap; /** Map that holds the bundles sorted by associated contributor name */ protected Map<String, Bundle> bundlesMap; /** * Constructor * */ public ExtensionPointTransformationDiagramDataSource() { super(ExtensionPointTransformationDiagramDataSource.DESCRIPTION); this.transformationSetsMap = new HashMap<String, net.atos.optimus.m2m.engine.core.transformations.TransformationSet>(); this.transformationReferencesMap = new HashMap<String, TransformationReference>(); this.bundlesMap = new HashMap<String, Bundle>(); this.loadExtensionsPoint(); } @Override public TransformationReference getById(String id) { return this.transformationReferencesMap.get(id); } @Override public Collection<TransformationReference> getAll() { return Collections.unmodifiableCollection(transformationReferencesMap.values()); } /** * Load the extension points. */ protected void loadExtensionsPoint() { DependencyDiagramMessages.EP01.log(); /* Create resource set and load transformation sets */ ResourceSet resourceSet = this.createExtensionResourseSet(); /* Load transformation set extensions */ this.loadTransformationSetExtensions(resourceSet); /* Load transformation requirements */ this.loadReferenceRequirements(resourceSet); /* Clean resource set */ DependencyDiagramMessages.EP03.log(); this.cleanResourceSet(resourceSet); DependencyDiagramMessages.EP02.log(); } /** * Create the resource set containing all contributed dependency diagram * * @return the resource set containing all contributed dependency diagram. */ protected ResourceSet createExtensionResourseSet() { ResourceSet resourceSet = new ResourceSetImpl(); IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(Activator.PLUGIN_ID, ExtensionPointTransformationDiagramDataSource.EXTENSION_POINT_NAME); for (IExtension extension : extensionPoint.getExtensions()) { /* Add the associated bundle in the map */ String contributorName = extension.getContributor().getName(); this.bundlesMap.put(contributorName, Platform.getBundle(contributorName)); DependencyDiagramMessages.EP04.log(contributorName); for (IConfigurationElement configurationElement : extension.getConfigurationElements()) { /* Test diagram presence in the extension point */ if (ExtensionPointTransformationDiagramDataSource.EXTENSION_ELEMENT.equals(configurationElement .getName())) { String diagramFilename = configurationElement .getAttribute(ExtensionPointTransformationDiagramDataSource.ATTRIBUTE_DIAGRAM); DependencyDiagramMessages.EP05.log(diagramFilename); if (diagramFilename.endsWith(ExtensionPointTransformationDiagramDataSource.EXTENSION_DIAGRAM)) { URI fileURI = URI.createPlatformPluginURI(contributorName + "/" + diagramFilename, true); /* Load Resource */ Resource resource = resourceSet.getResource(fileURI, true); this.loadTransformationSet(resource, contributorName); } else { DependencyDiagramMessages.EP06.log(diagramFilename); } } } } return resourceSet; } /** * Load a transformation set associated to a resource and put it in the * associated map * * @param resource * the resource. * @param contributorName * the contributor name associated to the resource. */ protected void loadTransformationSet(Resource resource, String contributorName) { Bundle bundle = this.bundlesMap.get(contributorName); for (EObject root : resource.getContents()) { /* Instance of meta-model */ if (root instanceof TransformationSets) { DependencyDiagramMessages.EP07.log(); /* Load all transformation sets */ for (TransformationSet transformationSet : ((TransformationSets) root).getTransformationSets()) { /* Optimus transformation set creation */ net.atos.optimus.m2m.engine.core.transformations.TransformationSet optimusTransformationSet = null; if (transformationSet.getName() == null || "".equals(transformationSet.getName().trim())) { DependencyDiagramMessages.EP20.log(); } else if (transformationSet.getImplementation() == null || "".equals(transformationSet.getImplementation().trim())) { DependencyDiagramMessages.EP21.log(); } else { try { optimusTransformationSet = (net.atos.optimus.m2m.engine.core.transformations.TransformationSet) bundle .loadClass(transformationSet.getImplementation()).newInstance(); } catch (InstantiationException e) { DependencyDiagramMessages.EP08.log(transformationSet.getName()); } catch (IllegalAccessException e) { DependencyDiagramMessages.EP08.log(transformationSet.getName()); } catch (ClassNotFoundException e) { DependencyDiagramMessages.EP08.log(transformationSet.getName()); } } if(optimusTransformationSet == null){ optimusTransformationSet = new DefaultTransformationSet(); } /* Fill Optimus transformation set */ optimusTransformationSet.setContributor(contributorName); optimusTransformationSet.setId(transformationSet.getName()); optimusTransformationSet.setDescription(transformationSet.getDescription()); optimusTransformationSet.setPrivate(transformationSet.isPrivate()); optimusTransformationSet.setTransformationDataSource(this); this.transformationSetsMap.put(optimusTransformationSet.getId(), optimusTransformationSet); DependencyDiagramMessages.EP09.log(transformationSet.getName(), transformationSet.getImplementation()); /* * Load all transformation reference in this transformation * set */ for (Transformation transformation : transformationSet.getTransformations()) { this.loadTransformationReference(transformation, optimusTransformationSet.getId()); } } } } } /** * Load transformation set extensions * * @param resourceSet * the resource set of dependency diagram. */ protected void loadTransformationSetExtensions(ResourceSet resourceSet) { for (Resource resource : resourceSet.getResources()) { for (EObject root : resource.getContents()) { /* Instance of meta-model */ if (root instanceof TransformationSets) { for (TransformationSetExtension transformationSetExtension : ((TransformationSets) root) .getTransformationSetExtensions()) { /* Test if original transformation set exists */ net.atos.optimus.m2m.engine.core.transformations.TransformationSet optimusTransformationSet = this.transformationSetsMap .get(transformationSetExtension.getTransformationSetId()); if (optimusTransformationSet != null) { DependencyDiagramMessages.EP16.log(transformationSetExtension.getTransformationSetId()); /* * Load all transformation reference in this * transformation set extension */ for (Transformation transformation : transformationSetExtension.getTransformations()) { this.loadTransformationReference(transformation, optimusTransformationSet.getId()); } } else { DependencyDiagramMessages.EP17.log(transformationSetExtension.getTransformationSetId()); } } } } } } /** * Load a transformation * * @param transformation * the transformation to load. * @param transformationSetName * the transformation set name associated to the transformation. */ protected void loadTransformationReference(Transformation transformation, String transformationSetName) { TransformationReference transformationReference = this.transformationReferencesMap .get(transformation.getName()); net.atos.optimus.m2m.engine.core.transformations.TransformationSet optimusTransformationSet = this.transformationSetsMap .get(transformationSetName); Bundle bundle = this.bundlesMap.get(optimusTransformationSet.getContributor()); if (transformation.getName() == null || "".equals(transformation.getName().trim())) { DependencyDiagramMessages.EP22.log(); } else if (transformation.getFactory() == null || "".equals(transformation.getFactory().trim())) { DependencyDiagramMessages.EP23.log(); } /* Test the priority of the transformation if exists already one */ else if (transformationReference == null || transformationReference.getPriority() < transformation.getPriority()) { /* Transformation factory creation */ ITransformationFactory transformationFactory = null; try { transformationFactory = (ITransformationFactory) bundle.loadClass(transformation.getFactory()) .newInstance(); } catch (InstantiationException e) { handlingExceptionLoadingTransformation(e, transformation); } catch (IllegalAccessException e) { handlingExceptionLoadingTransformation(e, transformation); } catch (ClassNotFoundException e) { handlingExceptionLoadingTransformation(e, transformation); } /* Transformation reference creation */ transformationReference = new TransformationReference(transformation.getName(), transformationFactory, optimusTransformationSet, transformation.getDescription(), transformation.getPriority()); transformationReference.setContributor(optimusTransformationSet.getContributor()); DependencyDiagramMessages.EP11.log(transformation.getName(), transformation.getFactory()); this.transformationReferencesMap.put(transformation.getName(), transformationReference); } } /** * Load transformation requirements * * @param transformation * the transformation to load associated requirements. * @param transformationSetName * the transformation set name associated to the transformation. */ protected void loadReferenceRequirements(ResourceSet resourceSet) { for (Resource resource : resourceSet.getResources()) { for (EObject root : resource.getContents()) { /* Instance of meta-model */ if (root instanceof TransformationSets) { for (TransformationSet transformationSet : ((TransformationSets) root).getTransformationSets()) { for (Transformation transformation : transformationSet.getTransformations()) { this.loadTransformationRequirements(transformation, transformationSet.getName()); } } for (TransformationSetExtension transformationSetExtension : ((TransformationSets) root) .getTransformationSetExtensions()) { if (this.transformationSetsMap.containsKey(transformationSetExtension.getTransformationSetId())) { for (Transformation transformation : transformationSetExtension.getTransformations()) { this.loadTransformationRequirements(transformation, transformationSetExtension.getTransformationSetId()); } } } } } } } /** * Load requirements for a specified transformation * * @param transformation * @param transformationSetName */ protected void loadTransformationRequirements(Transformation transformation, String transformationSetName) { TransformationReference transformationReference = this.transformationReferencesMap .get(transformation.getName()); net.atos.optimus.m2m.engine.core.transformations.TransformationSet optimusTransformationSet = this.transformationSetsMap .get(transformationSetName); Bundle bundle = this.bundlesMap.get(optimusTransformationSet.getContributor()); if (transformationReference != null && transformationReference.getPriority() == transformation.getPriority()) { for (Requirement requirement : transformation.getRequirements()) { if (this.transformationReferencesMap.containsKey(requirement.getReference().getName())) { AbstractRequirement abstractRequirement = AbstractRequirementChainFactory.INSTANCE .createAbstractRequirement(transformationReference, requirement, bundle); if (abstractRequirement != null) { transformationReference.addRequirement(abstractRequirement); } } else { DependencyDiagramMessages.EP18.log(requirement.getReference().getName()); } } } } /** * Clean a resource set * * @param resourceSet * the resource set to clean. */ protected void cleanResourceSet(ResourceSet resourceSet) { for (Resource resource : resourceSet.getResources()) { resource.unload(); } resourceSet.getResources().clear(); this.bundlesMap.clear(); } /** * Handler when loading transformation encountered an exception * * @param e * the exception. * @param transformation * the transformation attended to load. */ protected void handlingExceptionLoadingTransformation(Exception e, Transformation transformation) { DependencyDiagramMessages.EP10.log(e.getMessage()); Activator .getDefault() .getLog() .log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid transformation set implementation : " + transformation.getFactory(), e)); } }