/******************************************************************************* * 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.util; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.resource.ResourceSet; import org.reuseware.coconut.compositionprogram.CompositionProgram; import org.reuseware.coconut.compositionprogram.CompositionprogramPackage; import org.reuseware.coconut.compositionprogram.FragmentInstance; import org.reuseware.coconut.fracol.FracolPackage; import org.reuseware.coconut.resource.sokan.IndexConstants; import org.reuseware.coconut.resource.util.DirtyReuseResourceIDCollection; import org.reuseware.coconut.resource.util.ReuseResourcesUtil; import org.reuseware.coconut.reuseextension.ReuseextensionPackage; import org.reuseware.coconut.reuseextensionactivator.ReuseExtensionActivator; import org.reuseware.coconut.reuseextensionactivator.ReuseExtensionActivatorList; import org.reuseware.coconut.reuseextensionactivator.ReuseextensionactivatorPackage; import org.reuseware.sokan.Constraint; import org.reuseware.sokan.FacetedRequest; import org.reuseware.sokan.ID; import org.reuseware.sokan.IndexRow; import org.reuseware.sokan.index.DependencyMap; import org.reuseware.sokan.index.solr.SolrConst; import org.reuseware.sokan.index.util.FacetUtil; import org.reuseware.sokan.index.util.IndexUtil; import org.reuseware.sokan.index.util.ResourceUtil; import org.reuseware.sokan.index.util.SokanConst; import org.reuseware.sokan.index.util.StoreUtil; /** * Utility methods specific to handling reuse resources with Sokan. */ public final class SokanReuseResourceUtil { private SokanReuseResourceUtil() { } /** * Translates a dirty ID collection of reuse resources into a * Sokan dependency map. * * @param dirtyIDs the dirty ID collection * @param dependencyMap the dependency map to fill */ public static void processDirtyIDs( DirtyReuseResourceIDCollection dirtyIDs, DependencyMap dependencyMap) { for (List<String> ufi : dirtyIDs.getFragmentCompositionInterfaceIDs()) { dependencyMap.put( ResourceUtil.idFrom(ufi), IndexConstants.GENERATOR_FRAGMENT_COMPOSITION_INTERFACE); } for (List<String> ucpi : dirtyIDs.getDerivedCompositionProgramIDs()) { dependencyMap.put( ResourceUtil.idFrom(ucpi), IndexConstants.GENERATOR_DERIVED_COMPOSITION_PROGRAM); } for (List<String> ucpi : dirtyIDs.getComposingCompositionProgramIDs()) { dependencyMap.put( ResourceUtil.idFrom(ucpi), IndexConstants.GENERATOR_COMPOSED_FRAGMENTS); } for (List<String> ufi : dirtyIDs.getCompositionProgramSourceIDs()) { dependencyMap.put( ResourceUtil.idFrom(ufi), IndexConstants.INDEXER_COMPOSITION_PROGRAM_SOURCE); } } /** * Finds all reuse extension activators that influence the fragment * with the given UFI. * * @param ufi the UFI * @param resourceSet the resource set to use * @return the found reuse extension activators */ public static List<ReuseExtensionActivator> findReuseExtensionActivators( List<String> ufi, ResourceSet resourceSet) { List<ReuseExtensionActivator> result = new ArrayList<ReuseExtensionActivator>(); //TODO #1261: complex query used here //find reuse extension activators List<String> queries = new ArrayList<String>(); for (int i = ufi.size() - 1; i >= 0; i--) { String packageName = ResourceUtil.idString(ufi.subList(0, i)); String rexActivatorQuery = packageName + SokanConst.SEPERATOR + "*" + ".rex_activator"; rexActivatorQuery = rexActivatorQuery + " NOT " + packageName + SokanConst.SEPERATOR + "*" + SokanConst.SEPERATOR + "*" + ".rex_activator"; queries.add(rexActivatorQuery); } String completeQueryString = ""; for (Iterator<String> i = queries.iterator(); i.hasNext();) { String query = i.next(); completeQueryString = completeQueryString + "(" + query + ")"; if (i.hasNext()) { completeQueryString = completeQueryString + " OR "; } } List<Constraint> constraints = FacetUtil.buildConstraints( SolrConst.SYS_FIELD_ID, completeQueryString); FacetedRequest request = FacetUtil.buildFacetedRequest(constraints); List<IndexRow> response = IndexUtil.INSTANCE.getIndex(request); for (IndexRow rexActicatorRow : response) { ID rexActivatorID = rexActicatorRow.getArtifactID(); URI rexActivatorURI = ResourceUtil.uriFrom(rexActivatorID); ReuseExtensionActivatorList rexActivatorList = ReuseResourcesUtil.getReuseExtensionActivatorList( ResourceUtil.idFrom(rexActivatorURI).getSegments(), resourceSet); if (rexActivatorList != null) { result.addAll(rexActivatorList.getActivators()); } } return result; } /** * Determines the URI for the derived composition program * with the given UCPI. * * @param ucpi the UCPI * @param derivedFromUFI the UFI of the fragment from which * the composition program was derived * @param locationHint a location hint * * @return the URI for storing the composition program */ public static URI getDerivedCompositionProgramURI( List<String> ucpi, List<String> derivedFromUFI, String locationHint) { List<String> referenceID = derivedFromUFI; URI referenceURI = ResourceUtil.uriFrom(ResourceUtil.idFrom(derivedFromUFI)); URI locationURI = uriForLocationHint(locationHint, referenceID, referenceURI); URI store = StoreUtil.INSTANCE.getStoreContainerFor(locationURI); if (store != null) { referenceID = Collections.emptyList(); referenceURI = locationURI; } return uriForID( ucpi, referenceID, referenceURI); } /** * Determines the URI for the composed fragment * with the given UFI. * * @param ufi the UFI * @param composingCompositionProgram * the composition program responsible for composing the fragment * * @return the URI for storing the composed fragment */ public static URI getComposedFragmentURI( List<String> ufi, CompositionProgram composingCompositionProgram) { String locationHint = null; for (FragmentInstance fragmentInstance : composingCompositionProgram.getFragmentInstances()) { if (ufi.equals(fragmentInstance.getTargetUFI()) && fragmentInstance.isTarget()) { locationHint = fragmentInstance.getTargetPhysicalLocation(); break; } } List<String> referenceID = composingCompositionProgram.getUCPI(); URI referenceURI = composingCompositionProgram.eResource().getURI(); URI locationURI = uriForLocationHint(locationHint, referenceID, referenceURI); URI store = StoreUtil.INSTANCE.getStoreContainerFor(locationURI); if (store != null) { referenceID = Collections.emptyList(); referenceURI = locationURI; } return uriForID( ufi, referenceID, referenceURI); } private static URI uriForLocationHint( String locationHint, List<String> referenceID, URI referenceURI) { if (locationHint == null || "".equals(locationHint)) { return null; } URI locationURI = null; if (locationHint.contains(":")) { //absolute with scheme locationURI = URI.createURI(locationHint); } else if (locationHint.startsWith("/")) { //absolute in workspace locationURI = URI.createPlatformResourceURI(locationHint, true); } else { //relative to current store's container locationURI = URI.createURI(locationHint).resolve(referenceURI.trimSegments(referenceID.size())); } return locationURI; } private static URI uriForID( List<String> iD, List<String> referenceID, URI referenceURI) { return referenceURI.trimSegments(referenceID.size()).appendSegments( iD.toArray(new String[iD.size()])); } /** * @param row an index row * @return true if the row represents a meta artifact (fracol or rex file) */ public static boolean isMetaArtifact(IndexRow row) { if (row == null || row.getMetaData() == null) { return false; } if (row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).contains( SokanReuseResourceUtil.eClassToString(FracolPackage.Literals.FRAGMENT_COLLABORATION)) && row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).size() == 1) { return true; } if (row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).contains( SokanReuseResourceUtil.eClassToString(ReuseextensionPackage.Literals.REUSE_EXTENSION)) && row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).size() == 2) { return true; } return false; } /** * @param row an index row * @return true if the row represents a reuse extension activator */ public static boolean isRexActivator(IndexRow row) { if (row == null || row.getMetaData() == null) { return false; } if (row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).contains( SokanReuseResourceUtil.eClassToString(ReuseextensionactivatorPackage.Literals.REUSE_EXTENSION_ACTIVATOR_LIST)) && row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).size() == 1) { return true; } return false; } /** * @param row an index row * @return true if the row represents a diagram */ public static boolean isDiagram(IndexRow row) { if (row == null || row.getMetaData() == null) { return false; } return !row.getMetaData().getMulti(IndexConstants.COLUMN_DIAGRAM_FOR).isEmpty(); } /** * @param row an index row * @return true if the row represents a composition program */ public static boolean isCompositionProgram(IndexRow row) { if (row == null || row.getMetaData() == null) { return false; } if (row.getMetaData().getMulti(IndexConstants.COLUMN_ROOT_ECLASS).contains( SokanReuseResourceUtil.eClassToString(CompositionprogramPackage.Literals.COMPOSITION_PROGRAM))) { return true; } return false; } /** * Returns a string representation of the given EClass that can * be stored in the index. The string is created from the nsURI * of the EClass' package and the EClass' name. * * @param eClass the EClass * @return the string representation */ public static String eClassToString(EClass eClass) { if (eClass == null || eClass.getEPackage() == null) { return null; } return eClass.getEPackage().getNsURI() + "::" + eClass.getName(); } }