blob: 9cea8aedf84796472243c54042eed4f081f0c082 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2014 Borland Software Corporation 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:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.tests.qvt.oml.transform;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.common.MDAConstants;
import org.eclipse.m2m.internal.qvt.oml.common.MdaException;
import org.eclipse.m2m.internal.qvt.oml.common.io.CFile;
import org.eclipse.m2m.internal.qvt.oml.common.io.FileUtil;
import org.eclipse.m2m.internal.qvt.oml.common.io.eclipse.EclipseFile;
import org.eclipse.m2m.internal.qvt.oml.common.io.eclipse.EclipseResource;
import org.eclipse.m2m.internal.qvt.oml.common.launch.TargetUriData;
import org.eclipse.m2m.internal.qvt.oml.common.launch.TargetUriData.TargetType;
import org.eclipse.m2m.internal.qvt.oml.emf.util.ModelContent;
import org.eclipse.m2m.internal.qvt.oml.project.QVTOProjectPlugin;
import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilder;
import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilderConfig;
import org.eclipse.m2m.internal.qvt.oml.project.nature.NatureUtils;
import org.eclipse.m2m.internal.qvt.oml.runtime.launch.QvtLaunchConfigurationDelegateBase;
import org.eclipse.m2m.internal.qvt.oml.runtime.project.QvtTransformation;
import org.eclipse.m2m.internal.qvt.oml.runtime.project.TransformationUtil;
import org.eclipse.m2m.internal.qvt.oml.runtime.project.QvtTransformation.TransformationParameter;
import org.eclipse.m2m.internal.qvt.oml.runtime.project.QvtTransformation.TransformationParameter.DirectionKind;
import org.eclipse.m2m.qvt.oml.util.IContext;
import org.eclipse.m2m.tests.qvt.oml.TestProject;
import org.eclipse.m2m.tests.qvt.oml.util.TestUtil;
public abstract class TestTransformation extends TestCase {
private ModelTestData myData;
private TestProject myProject;
private File myDestFolder;
public TestTransformation(ModelTestData data) {
super(data.getName());
myData = data;
myProject = null;
}
public IProject getProject() {
return myProject.getProject();
}
public TestProject getTestProject() {
return myProject;
}
public ModelTestData getData() {
return myData;
}
protected String getProjectName() {
return "TransformationTest"; //$NON-NLS-1$
}
protected boolean isSaveXmi() {
return myData.isUseCompiledXmi();
}
@Override
public void setUp() throws Exception {
TestUtil.turnOffAutoBuilding();
String name = getProjectName();
myProject = TestProject.getExistingProject(name);
if(myProject == null) {
myProject = new TestProject(name, new String[] {}, 0);
myProject.getProject().setDefaultCharset(ModelTestData.ENCODING, null);
NatureUtils.addNature(getProject(), QVTOProjectPlugin.NATURE_ID);
IProjectDescription description = getProject().getDescription();
ICommand[] buildSpec = description.getBuildSpec();
ICommand buildCommand = NatureUtils.findCommand(buildSpec, QVTOProjectPlugin.BUILDER_ID);
assertNotNull(buildCommand);
Map<String, String> arguments = buildCommand.getArguments();
arguments.put(QVTOBuilder.SAVE_AST_XMI, Boolean.toString(isSaveXmi()));
buildCommand.setArguments(arguments);
description.setBuildSpec(buildSpec);
getProject().setDescription(description, null);
QVTOBuilderConfig.getConfig(getProject()).setSourceContainer(getProject());
}
copyModelData();
myData.prepare(myProject);
}
protected void buildTestProject() throws Exception {
getProject().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
assertBuildOK(getProject());
}
protected void assertBuildOK(IProject project) throws Exception {
IMarker[] problems = project.findMarkers(QVTOProjectPlugin.PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
StringBuilder buf = new StringBuilder();
IMarker firstError = null;
try {
for (IMarker next : problems) {
if(Integer.valueOf(IMarker.SEVERITY_ERROR).equals(next.getAttribute(IMarker.SEVERITY))) {
firstError = next;
break;
}
}
if(firstError == null) {
return;
}
IMarker marker = firstError;
buf.append(marker.getAttribute(IMarker.MESSAGE));
buf.append(", line:").append(marker.getAttribute(IMarker.LINE_NUMBER)); //$NON-NLS-1$
buf.append(", path:").append(marker.getResource().getProjectRelativePath()); //$NON-NLS-1$
} finally {
try {
// do clean even if we have failed
if(firstError != null) {
tearDown();
getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
fail(buf.toString());
}
protected void assertEqualContents(String expectedContents, String actualContents) {
String lineSeparator = System.getProperty("line.separator");
if (!"\n".equals(lineSeparator)) {
expectedContents = expectedContents.replace(lineSeparator, "\n");
actualContents = actualContents.replace(lineSeparator, "\n");
}
assertEquals(expectedContents, actualContents);
}
@Override
public void tearDown() throws Exception {
if (myData == null) {
return;
}
getData().dispose(myProject);
if (myDestFolder.exists()) {
delete(myDestFolder);
}
getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
myData = null;
}
public static void delete(File file) {
if(file.isDirectory()) {
File[] children = file.listFiles();
for(int i = 0; i < children.length; i++) {
delete(children[i]);
}
}
file.delete();
}
public static interface IChecker {
void check(ModelTestData data, IProject project) throws Exception;
}
public static class TransformationChecker implements IChecker {
public TransformationChecker(ITransformer transformer) {
myTransformer = transformer;
}
public void check(ModelTestData data, IProject project) throws Exception {
IFile transformation = getIFile(data.getTransformation(project));
List<URI> transfResult = myTransformer.transform(transformation, data.getIn(project), data.getContext());
List<URI> expectedResultURIs = data.getExpected(project);
ResourceSetImpl rs = new ResourceSetImpl();
rs.setPackageRegistry(data.getMetamodelResolutionRegistry(project, rs));
int i = 0;
for (URI actualResultURI : transfResult) {
URI uri = expectedResultURIs.get(i++);
Resource expectedResource = rs.getResource(uri, true);
List<EObject> actualExtentObjects = rs.getResource(actualResultURI, true).getContents();
data.compareWithExpected(expectedResource.getContents(), actualExtentObjects);
}
}
private final ITransformer myTransformer;
};
public static interface ITransformer {
List<URI> transform(IFile transformation, List<URI> inUris, IContext context) throws Exception;
}
protected void checkTransformation(IChecker checker) throws Exception {
checker.check(myData, getProject());
getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
}
private void copyModelData() throws Exception {
File srcFolder = TestUtil.getPluginRelativeFile(myData.getBundle(), myData.getTestDataFolder() + "/models/" + myData.getName()); //$NON-NLS-1$
myDestFolder = new File(getProject().getLocation().toString() + "/models/" + myData.getName()); //$NON-NLS-1$
myDestFolder.mkdirs();
FileUtil.copyFolder(srcFolder, myDestFolder);
getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
}
public static IFile getIFile(File fileUnderWorkspace) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IPath location = new Path(fileUnderWorkspace.getAbsolutePath());
IFile ifile = workspace.getRoot().getFileForLocation(location);
if(ifile == null) {
throw new RuntimeException("File not found: " + fileUnderWorkspace); //$NON-NLS-1$
}
return ifile;
}
public static CFile getTraceFile(CFile qvtFile) throws MdaException {
String fileName = qvtFile.getUnitName() + MDAConstants.QVTO_TRACEFILE_EXTENSION_WITH_DOT;
CFile traceFile = qvtFile.getParent().getFile(fileName);
return traceFile;
}
protected static CFile getModelExtentFile(CFile qvtFile, TransformationParameter transfParam) throws MdaException {
String fileExtension = transfParam.getMetamodels().isEmpty() ? TransformationUtil.DEFAULT_RESULT_EXTENSION
: transfParam.getMetamodels().get(0).getName();
String fileName = qvtFile.getUnitName() + ".extent_" + transfParam.getName() + '.' + fileExtension; //$NON-NLS-1$
CFile modelExtentFile = qvtFile.getParent().getFile(fileName);
return modelExtentFile;
}
protected static List<URI> launchTransform(IFile transformation, List<URI> inUris, IContext qvtContext,
QvtTransformation transf) throws Exception {
EclipseFile eclipseFile = new EclipseFile(transformation);
List<ModelContent> inObjects = new ArrayList<ModelContent>(transf.getParameters().size());
List<TargetUriData> targetData = new ArrayList<TargetUriData>(transf.getParameters().size());
List<URI> resultUris = new ArrayList<URI>(transf.getParameters().size());
int inoutExtentCount = transf.getResourceSet().getResources().size() + inUris.size();
int outExtentCount = 0;
Iterator<URI> itInUris = inUris.iterator();
for (TransformationParameter transfParam : transf.getParameters()) {
URI inUri = null;
if (transfParam.getDirectionKind() == DirectionKind.IN || transfParam.getDirectionKind() == DirectionKind.INOUT) {
inUri = itInUris.next();
ModelContent inModel = transf.loadInput(inUri);
inObjects.add(inModel);
if (transfParam.getDirectionKind() == DirectionKind.IN
&& inModel.getContent().size() == 1
&& inModel.getContent().get(0) instanceof EPackage) {
String nsURI = ((EPackage) inModel.getContent().get(0)).getNsURI();
if (transf.getResourceSet().getPackageRegistry().getEPackage(nsURI) == inModel.getContent().get(0)) {
--outExtentCount;
}
}
}
if (transfParam.getDirectionKind() == DirectionKind.OUT || transfParam.getDirectionKind() == DirectionKind.INOUT) {
if (inUri == null) {
CFile outFile = getModelExtentFile(eclipseFile, transfParam);
inUri = URI.createFileURI(outFile.getFullPath());
++outExtentCount;
}
targetData.add(new TargetUriData(TargetType.NEW_MODEL, inUri.toString(), null, false));
resultUris.add(inUri);
}
}
URI traceURI = URI.createFileURI(((EclipseResource) getTraceFile(eclipseFile)).getResource().getLocation().toString());
QvtLaunchConfigurationDelegateBase.doLaunch(transf, inObjects, targetData, traceURI.toString(), qvtContext);
assertTrue(
NLS.bind("Unexpected number of resources. Expected ({0}), got ({1}).", inoutExtentCount + outExtentCount, //$NON-NLS-1$
transf.getResourceSet().getResources().size()),
inoutExtentCount + outExtentCount == transf.getResourceSet().getResources().size());
transf.cleanup();
return resultUris;
}
}