/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.coconut.resource.sokan.indexer; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.EList; 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.reuseware.coconut.compositionprogram.CompositionprogramFactory; import org.reuseware.coconut.compositionprogram.DerivedCompositionProgram; import org.reuseware.coconut.resource.sokan.IndexConstants; import org.reuseware.coconut.resource.sokan.util.SokanReuseResourceUtil; import org.reuseware.coconut.resource.util.ReuseResourcesUtil; import org.reuseware.coconut.reuseextension.CompositionLanguageSpecification; import org.reuseware.coconut.reuseextension.ReuseExtension; import org.reuseware.coconut.reuseextension.RootElementContext; import org.reuseware.coconut.reuseextension.evaluator.EvaluatorUtil; import org.reuseware.coconut.reuseextensionactivator.Argument; import org.reuseware.coconut.reuseextensionactivator.ReuseExtensionActivator; import org.reuseware.sokan.ID; import org.reuseware.sokan.IndexMetaData; import org.reuseware.sokan.index.DependencyMap; import org.reuseware.sokan.index.indexer.Indexer; import org.reuseware.sokan.index.util.IndexUtil; import org.reuseware.sokan.index.util.ResourceUtil; /** * This indexer is responsible for identifying if a certain * artifact is source of one or more derived composition * programs. If yes, it also ensures that the derived * composition program is (initially empty) created in the * resource set of the indexing process. * <p> * Index field: <i>org.reuseware.coconut.resource.sokan.derivedCompositionProgram</i>. */ public class CompositionProgramSourceIndexer implements Indexer { /** * @param artifactURI the URI * @param metaData the meta data to fill * @param resourceSet the resource set to use */ public void createIndex(URI artifactURI, IndexMetaData metaData, ResourceSet resourceSet) { metaData.getMulti(IndexConstants.COLUMN_DERIVED_COMPOSITION_PROGRAM).clear(); Resource resource = null; try { resource = resourceSet.getResource(artifactURI, true); } catch (Exception e) { //ok } if (resource == null || resource.getContents().isEmpty()) { return; } indexDerivedCompositionProgramSource(resource, metaData, resourceSet); } private void indexDerivedCompositionProgramSource(Resource resource, IndexMetaData metaData, ResourceSet resourceSet) { ID iD = ResourceUtil.idFrom(resource.getURI()); if (iD == null) { return; } EList<String> ufi = iD.getSegments(); List<ReuseExtensionActivator> rexActivatorList = SokanReuseResourceUtil.findReuseExtensionActivators(ufi, resourceSet); for (ReuseExtensionActivator rexActivator : rexActivatorList) { if (rexActivator.getReuseExtension() instanceof CompositionLanguageSpecification) { if (influencesFragment(rexActivator, resource, ufi)) { CompositionLanguageSpecification clSpec = (CompositionLanguageSpecification) rexActivator.getReuseExtension(); String idExp = clSpec.getUcpiExpression(); String locationExp = clSpec.getCompositionProgramPhysicalLocationExpression(); EObject context = resource.getContents().get(0); Map<String, String> args = new LinkedHashMap<String, String>(); for (Argument arg : rexActivator.getArguments()) { args.put(arg.getParameter(), arg.getValue()); } List<String> ucpi = EvaluatorUtil.deriveID(ufi, context, idExp, args); String locationHint = EvaluatorUtil.derive(ufi, context, locationExp, args); URI derivedCpURI = SokanReuseResourceUtil.getDerivedCompositionProgramURI(ucpi, ufi, locationHint); if (!IndexUtil.INSTANCE.isArtifact(ResourceUtil.idFrom(derivedCpURI))) { //derived cp has not been registered with sokan yet createResourceForDerivedCompositionProgram( CompositionprogramFactory.eINSTANCE.createDerivedCompositionProgram(), derivedCpURI, resourceSet); } metaData.putMultiple( IndexConstants.COLUMN_DERIVED_COMPOSITION_PROGRAM, ResourceUtil.idString(ucpi)); } } } } private Resource createResourceForDerivedCompositionProgram( DerivedCompositionProgram derivedCompositionProgram, URI derivedCpURI, ResourceSet resourceSet) { Resource derivedCpResource = null; derivedCpResource = resourceSet.getResource(derivedCpURI, false); if (derivedCpResource == null) { derivedCpResource = resourceSet.createResource(derivedCpURI); } DerivedCompositionProgram derivedCP = derivedCompositionProgram; derivedCpResource.getContents().clear(); derivedCpResource.getContents().add(derivedCP); derivedCpResource.setModified(true); return derivedCpResource; } private boolean influencesFragment(ReuseExtensionActivator rexActivator, Resource resource, List<String> ufi) { ReuseExtension rex = rexActivator.getReuseExtension(); for (EObject root : resource.getContents()) { for (RootElementContext rootElementContext : rex.getRootElementContexts()) { if (rootElementContext.getEBoundClass().isInstance(root)) { Map<String, String> args = new LinkedHashMap<String, String>(); for (Argument arg : rexActivator.getArguments()) { args.put(arg.getParameter(), arg.getValue()); } if (EvaluatorUtil.eval( ufi, root, rootElementContext.getIsExpression(), args)) { return true; } } } } return false; } /** * This implementation makes sure that the DerivedCompositionProgramGenerator * is called for all derived composition programs. * * @param artifactID the artifact's ID * @param depMap the dependency map to fill */ public void getDependent(ID artifactID, DependencyMap depMap) { SokanReuseResourceUtil.processDirtyIDs(ReuseResourcesUtil.compositionProgramSourceChanged(artifactID.getSegments()), depMap); } }