/******************************************************************************* * Copyright (c) 2010-2015 Henshin developers. 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: * TU Berlin, University of Luxembourg, SES S.A. *******************************************************************************/ package de.tub.tfs.henshin.editor.util; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.henshin.model.Formula; import org.eclipse.emf.henshin.model.Mapping; import org.eclipse.emf.henshin.model.Node; import org.eclipse.emf.henshin.model.Rule; public class MappingUtil { private static HashMap<Rule,Pair<Integer,LinkedHashSet<HashSet<Node>>>> cachedMappings = new HashMap<Rule, Pair<Integer,LinkedHashSet<HashSet<Node>>>>(); public static HashSet<HashSet<Node>> convertMappings(Rule r){ return convertMappings(r.getMappings(),getAllMappingsFromFormula(r.getLhs().getFormula())); } public static int convertMappings(Rule r,Node focusedNode){ return getMappingNumber(focusedNode,r.getMappings(),getAllMappingsFromFormula(r.getLhs().getFormula())); } public static HashSet<HashSet<Node>> convertMappings(List<Mapping>... mappings){ HashSet<HashSet<Node>> result = new LinkedHashSet<HashSet<Node>>(); LinkedList<Mapping> allMappings = new LinkedList<Mapping>(); for (List<Mapping> mappingList : mappings) { allMappings.addAll(mappingList); } for (Mapping mapping : allMappings) { HashSet<Node> targetSet = null; Iterator<HashSet<Node>> iterator = result.iterator(); while (iterator.hasNext()) { HashSet<Node> mappingSet = iterator.next(); if (mappingSet.contains(mapping.getOrigin()) || mappingSet.contains(mapping.getImage())){ if (targetSet == null){ targetSet = mappingSet; } else { targetSet.addAll(mappingSet); iterator.remove(); } } } if (targetSet == null){ targetSet = new HashSet<Node>(); result.add(targetSet); } targetSet.add(mapping.getImage()); targetSet.add(mapping.getOrigin()); } return result; } public static int getMappingNumber(Node focusNode,List<Mapping>... mappings){ LinkedHashSet<HashSet<Node>> result = null; LinkedList<Mapping> allMappings = new LinkedList<Mapping>(); for (List<Mapping> mappingList : mappings) { allMappings.addAll(mappingList); } Pair<Integer, LinkedHashSet<HashSet<Node>>> pair = cachedMappings.get(focusNode.getGraph().getRule()); if (pair != null && pair.getFirst() == allMappings.hashCode()){ result = pair.getSecond(); } if (result == null){ result = new LinkedHashSet<HashSet<Node>>(); for (Mapping mapping : allMappings) { HashSet<Node> targetSet = null; Iterator<HashSet<Node>> iterator = result.iterator(); while (iterator.hasNext()) { HashSet<Node> mappingSet = iterator.next(); if (mappingSet.contains(mapping.getOrigin()) || mappingSet.contains(mapping.getImage())){ if (targetSet == null){ targetSet = mappingSet; } else { targetSet.addAll(mappingSet); iterator.remove(); } } } if (targetSet == null){ targetSet = new HashSet<Node>(); result.add(targetSet); } targetSet.add(mapping.getImage()); targetSet.add(mapping.getOrigin()); } cachedMappings.put(focusNode.getGraph().getRule(), new Pair<Integer, LinkedHashSet<HashSet<Node>>>(allMappings.hashCode(), result)); } int i = 0; for (HashSet<Node> mappedNodes : result) { if (mappedNodes.contains(focusNode)) return i; i++; } return -1; } public static List<Mapping> getAllMappingsFromFormula(Formula formula){ List<Mapping> result = new LinkedList<Mapping>(); if (formula != null){ TreeIterator<EObject> eAllContents = formula.eAllContents(); while (eAllContents.hasNext()){ EObject eObj = eAllContents.next(); if (eObj instanceof Mapping){ result.add((Mapping) eObj); } } } return result; } }