/***************************************************************************** * Copyright (c) 2014,2015 ASML Netherlands B.V. and others. * * 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: * ASML Netherlands B.V. - Initial API and implementation * *****************************************************************************/ package org.eclipse.m2m.internal.qvt.oml.tools.coverage.ui; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.util.URI; import org.eclipse.m2m.internal.qvt.oml.InternalTransformationExecutor; import org.eclipse.m2m.internal.qvt.oml.compiler.CompiledUnit; import org.eclipse.m2m.internal.qvt.oml.emf.util.URIUtils; import org.eclipse.m2m.internal.qvt.oml.expressions.Constructor; import org.eclipse.m2m.internal.qvt.oml.expressions.Helper; import org.eclipse.m2m.internal.qvt.oml.expressions.Library; import org.eclipse.m2m.internal.qvt.oml.expressions.MappingOperation; import org.eclipse.m2m.internal.qvt.oml.expressions.Module; import org.eclipse.ocl.ecore.OCLExpression; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; @SuppressWarnings("restriction") public class TransformationCoverageModel { private URI uri; private Map<NodeCoverageModel, NodeCoverageModel> nodes = new HashMap<NodeCoverageModel, NodeCoverageModel>(); private Module module; private IProject project; private IFile file; private RangeSet<Integer> touchedRanges; private RangeSet<Integer> untouchedRanges; public TransformationCoverageModel() { } public TransformationCoverageModel(URI uri) { setURI(uri); } public void setURI(URI aUri) { uri = aUri; } public URI getURI() { return uri; } private Set<NodeCoverageModel> getNodes(boolean touched, Class<?> c) { Set<NodeCoverageModel> desiredNodes = new HashSet<NodeCoverageModel>(); for (NodeCoverageModel n : nodes.values()) { if (c.isInstance(n.getNode()) && n.getTouched() == touched) { desiredNodes.add(n); } } return desiredNodes; } private Set<NodeCoverageModel> getMappingNodes(boolean touched) { return getNodes(touched, MappingOperation.class); } // TODO add fields for these to improve speed public Set<NodeCoverageModel> getUntouchedMappingNodes() { return getMappingNodes(false); } public Set<NodeCoverageModel> getTouchedMappingNodes() { return getMappingNodes(true); } private Set<NodeCoverageModel> getHelperNodes(boolean touched) { return getNodes(touched, Helper.class); } public Set<NodeCoverageModel> getUntouchedHelperNodes() { return getHelperNodes(false); } public Set<NodeCoverageModel> getTouchedHelperNodes() { return getHelperNodes(true); } private Set<NodeCoverageModel> getConstructorNodes(boolean touched) { return getNodes(touched, Constructor.class); } public Set<NodeCoverageModel> getUntouchedConstructorNodes() { return getConstructorNodes(false); } public Set<NodeCoverageModel> getTouchedConstructorNodes() { return getConstructorNodes(true); } private Set<NodeCoverageModel> getExpressionNodes(boolean touched) { return getNodes(touched, OCLExpression.class); } public Set<NodeCoverageModel> getUntouchedExpressionNodes() { return getExpressionNodes(false); } public Set<NodeCoverageModel> getTouchedExpressionNodes() { return getExpressionNodes(true); } public RangeSet<Integer> getTouchedRanges() { if (touchedRanges == null) { touchedRanges = TreeRangeSet.create(); for (NodeCoverageModel nodeModel : getTouchedExpressionNodes()) { touchedRanges.add(Range.closed(nodeModel.getStart(), nodeModel.getEnd() + 1)); } // Now remove untouched ranges for (Range<Integer> untouchedRange : getUntouchedRanges().asRanges()) { touchedRanges.remove(untouchedRange); } } return touchedRanges; } public RangeSet<Integer> getUntouchedRanges() { if (untouchedRanges == null) { untouchedRanges = TreeRangeSet.create(); for (NodeCoverageModel nodeModel : getUntouchedExpressionNodes()) { untouchedRanges.add(Range.closed(nodeModel.getStart(), nodeModel.getEnd() + 1)); } } return untouchedRanges; } public IFile getFile() { if (file == null) { file = URIUtils.getFile(getURI()); } return file; } public IProject getProject() { if (project == null) { project = this.getFile().getProject(); } return project; } public Module getModule() { if (module == null) { // Check for transformation first InternalTransformationExecutor executor = new InternalTransformationExecutor(getURI()); executor.loadTransformation(new NullProgressMonitor()); module = executor.getTransformation(); // Otherwise find library if (module == null) { CompiledUnit unit = executor.getUnit(); if (unit != null) { for (Module m : unit.getModules()) { // TODO: definitely should choose correct one, according // to URI if (m instanceof Library) { module = m; } } } } } return module; } public boolean containsNode(NodeCoverageModel n) { return nodes.containsKey(n); } public NodeCoverageModel getNode(NodeCoverageModel n) { return nodes.get(n); } public void addNode(NodeCoverageModel nodeModel) { nodes.put(nodeModel, nodeModel); } public Set<NodeCoverageModel> getUntouchedNodes() { Set<NodeCoverageModel> untouched = new HashSet<NodeCoverageModel>(); untouched.addAll(getUntouchedMappingNodes()); untouched.addAll(getUntouchedHelperNodes()); untouched.addAll(getUntouchedConstructorNodes()); untouched.addAll(getUntouchedExpressionNodes()); return untouched; } public Set<NodeCoverageModel> getTouchedNodes() { Set<NodeCoverageModel> touched = new HashSet<NodeCoverageModel>(); touched.addAll(getTouchedMappingNodes()); touched.addAll(getTouchedHelperNodes()); touched.addAll(getTouchedConstructorNodes()); touched.addAll(getTouchedExpressionNodes()); return touched; } }