blob: d388209dc74ff323beefc3dc528ed1c0bcce9614 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* SAP AG - initial API and implementation
******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.benchmark.preparation.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import modelmanagement.Package;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
public class PackageDependencyGraph {
private Map<Package, Collection<EObject>> aggregatedElements;
private Map<Package, List<Package>> dependencies;
private Collection<EObject> modelElementList;
public PackageDependencyGraph(Resource resource) {
buildDependencyGraph(resource);
}
public int getNumberOfPackages(){
assert aggregatedElements.size() == dependencies.size();
return dependencies.size();
}
public Map<Package, List<Package>> getDependencies(){
return dependencies;
}
public Collection<Package> getAllPackages(){
return dependencies.keySet();
}
public void removePackage(Package packageToRemove){
modelElementList.removeAll(aggregatedElements.get(packageToRemove));
aggregatedElements.remove(packageToRemove);
for(Package pack : dependencies.keySet()){
boolean packageWasRemoved = false;
do{
packageWasRemoved = dependencies.get(pack).remove(packageToRemove);
}while(packageWasRemoved == true);
}
dependencies.remove(packageToRemove);
}
private void buildDependencyGraph(Resource resourceToShrink) {
aggregateElementsInPackages(resourceToShrink);
//System.out.println("\t\t\tBuild Dependency Graph");
Collection<ModelReference> modelReferenceList = ResourceTraversalHelper
.getModelReferencesForModelElements(modelElementList);
// FIXME: The following code is obviously not optimized for performance
for (Package key : aggregatedElements.keySet()) {
Collection<EObject> elementInPackageList = aggregatedElements.get(key);
for (EObject elementInPackage : elementInPackageList) {
for (ModelReference modelReference : modelReferenceList) {
if (elementInPackage.equals(modelReference.getFrom())) {
Package referencedPackage = navigateToPackage(modelReference.getTo());
List<Package> contents = dependencies.get(referencedPackage);
if (contents == null) {
contents = new ArrayList<Package>();
}
if ((referencedPackage == null || !referencedPackage.equals(key))) {
contents.add(key);
}
dependencies.put(referencedPackage, contents);
}
}
}
}
}
private void aggregateElementsInPackages(Resource resourceToShrink) {
dependencies = new HashMap<Package, List<Package>>();
modelElementList = ResourceTraversalHelper.getModelElementsInResource(resourceToShrink);
aggregatedElements = aggregateElementsInPackages(modelElementList);
}
private HashMap<Package, Collection<EObject>> aggregateElementsInPackages(Collection<EObject> modelElementList) {
HashMap<Package, Collection<EObject>> result = new HashMap<Package, Collection<EObject>>();
for (EObject object : modelElementList) {
Package pack = navigateToPackage(object);
Collection<EObject> aggregatedElements = result.get(pack);
if (aggregatedElements == null) {
aggregatedElements = new ArrayList<EObject>();
}
aggregatedElements.add(object);
result.put(pack, aggregatedElements);
}
return result;
}
private Package navigateToPackage(EObject containedElement) {
EObject container = containedElement;
while (container.eContainer() != null && !(container instanceof Package)) {
container = container.eContainer();
}
if(container.equals(containedElement))
return null;
// FIXME: Add error handling
// if(!(container instanceof Package))
// throw new RuntimeException("Cannot determine toplevel package");
if (container instanceof Package)
return (Package) container;
return null;
}
}