/******************************************************************************* * 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.resourceset; import java.io.IOException; 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.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.reuseware.coconut.compositionprogram.CompositionProgram; import org.reuseware.coconut.compositionprogram.CompositionprogramFactory; import org.reuseware.coconut.compositionprogram.DerivedCompositionProgram; import org.reuseware.coconut.fragment.ComposedFragment; import org.reuseware.coconut.resource.ReuseResources; import org.reuseware.coconut.resource.util.DirtyReuseResourceIDCollection; import org.reuseware.coconut.resource.util.ReuseResourcesUtil; /** * A resource set that instantly updates resources * that have 'reuse' relationships to a resource that change. */ public class ReuseResourceSet extends ResourceSetImpl { public void demandLoad(Resource resource) throws IOException { super.demandLoad(resource); URI uri = resource.getURI(); List<String> ID = ReuseResources.INSTANCE.getID(uri); if (ID == null) { return; } if (uri.fileExtension().equals("fracol")) { clean(ReuseResourcesUtil.fragmentCollaborationChanged(ID)); } else if (uri.fileExtension().equals("rex")) { clean(ReuseResourcesUtil.componentModelSpecChanged(ID)); clean(ReuseResourcesUtil.compositionLanguageSpecChanged(ID)); } else if (uri.fileExtension().equals("rex_activator")) { clean(ReuseResourcesUtil.reuseExtensionActivatorChanged(ID)); } else if (uri.fileExtension().equals("ucl")) { executeComposition(ID); clean(ReuseResourcesUtil.compositionProgramChanged(ID)); } else { clean(ReuseResourcesUtil.fragmentChanged(ID)); } } protected List<URI> composedFragmentURIs = new ArrayList<URI>(); public List<URI> getComposedFragmentURIs() { //check if the composed fragments do all still exist for(Iterator<URI> i = composedFragmentURIs.iterator(); i.hasNext(); ) { URI next = i.next(); if (getResource(next, false) == null) { i.remove(); } } return Collections.unmodifiableList(composedFragmentURIs); } private void clean(DirtyReuseResourceIDCollection dirtyIDs) throws IOException { for(List<String> fragmentID : dirtyIDs.getFragmentCompositionInterfaceIDs()) { clean(ReuseResourcesUtil.fragmentChanged(fragmentID)); } for(List<String> derivedUCPI : dirtyIDs.getDerivedCompositionProgramIDs()) { deriveCompositionProgram(derivedUCPI); executeComposition(derivedUCPI); clean(ReuseResourcesUtil.compositionProgramChanged(derivedUCPI)); } for(List<String> composingUCPI : dirtyIDs.getComposingCompositionProgramIDs()) { executeComposition(composingUCPI); clean(ReuseResourcesUtil.compositionProgramChanged(composingUCPI)); } } private void deriveCompositionProgram(List<String> derivedUCPI) throws IOException { URI uri = ReuseResources.INSTANCE.getContentsURI(derivedUCPI); ResourceSet resourceSetForDerivation = newResourceSet(); Resource derivedCPResource = resourceSetForDerivation.createResource(uri); DerivedCompositionProgram derivedCP = CompositionprogramFactory.eINSTANCE.createDerivedCompositionProgram(); derivedCP.getUCPI().addAll(derivedUCPI); for(Resource resource : new ArrayList<Resource>(getResources())) { List<String> UFI = ReuseResources.INSTANCE.getID(resource.getURI()); if (UFI == null) { continue; } } // TODO #1558: Use composition program extractor registry derivedCP.extractCompositionProgram(); derivedCPResource.getContents().add(derivedCP); ReuseResourcesUtil.completeCompositionProgram(derivedCPResource); derivedCPResource.save(resourceSetForDerivation.getLoadOptions()); } private void executeComposition(List<String> composingUCPI) throws IOException { ResourceSet resourceSetForComposition = newResourceSet(); CompositionProgram compositionProgram = ReuseResourcesUtil.getCompositionProgram( composingUCPI, resourceSetForComposition); if (compositionProgram == null) { return; } compositionProgram.compose(); List<Resource> composedResources = new ArrayList<Resource>(); for(ComposedFragment composed : compositionProgram.getComposedFragments()) { URI uri = ReuseResources.INSTANCE.getContentsURI(composed.getUFI()); Resource composedResource = resourceSetForComposition.createResource(uri); composedResource.getContents().clear(); composedResource.getContents().addAll(composed.getContents()); composedResources.add(composedResource); composedFragmentURIs.add(uri); } //save after all resources have been prepared to ensure correct cross-references for(Resource composedResource : composedResources) { composedResource.save(resourceSetForComposition.getLoadOptions()); } } private ResourceSet newResourceSet() { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.getLoadOptions().putAll(getLoadOptions()); return resourceSet; } }