/******************************************************************************* * Copyright (c) 2006-2013 * 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.emftext.language.java.test.xmi; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.EcoreUtil.EqualityHelper; import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; import org.emftext.language.java.containers.CompilationUnit; import org.emftext.language.java.containers.JavaRoot; import org.emftext.language.java.containers.Package; import org.emftext.language.java.test.AbstractJavaParserTestCase; public class JavaXMISerializationTest extends AbstractJavaParserTestCase { protected static final String TEST_INPUT_FOLDER_NAME = "src-input"; protected static final String TEST_OUTPUT_FOLDER_NAME = "output"; // The following files can not be saved to XMI, because they contain // characters XML (1.0) does not support. protected static final String[] filesWithInvalidCharacters = new String [] { "EscapedStrings.java", "UnicodeIdentifiers.java", "SpecialCharacters.java", "StaticImports.java", //because it depends on EscapedStrings "MoreUnicodeCharacters.java", "ControlZ.java", "UnicodeSurrogateCharacters.java" //here the issue exists only in the layout information }; public static Test suite() throws Exception { Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put( "xmi", new XMIResourceFactoryImpl()); final JavaXMISerializationTest test = new JavaXMISerializationTest(); TestSuite suite = new TestSuite( "Suite testing XMI conversion for all files in the input directory automatically"); File inputFolder = new File("./" + TEST_INPUT_FOLDER_NAME); List<File> allTestFiles = collectAllFilesRecursive(inputFolder, "java"); File last = null; for (final File file : allTestFiles) { test.addFileToClasspath(file, test.getResourceSet()); if (file.getName().equals("TypeReferencing.java")) { last = file; continue; } } if (last != null) { //put the "TypeReferencing.java" file last, because it contains inner //types referenced by other files. If these types are not registered //before proxy resolving, the test will fail. allTestFiles.remove(last); allTestFiles.add(last); } for (final File file : allTestFiles) { if (!Arrays.asList(filesWithInvalidCharacters).contains(file.getName())) { addLoadTest(test, suite, file); } } addTransferToXMITest(test, suite); for (final File file : allTestFiles) { if (!Arrays.asList(filesWithInvalidCharacters).contains(file.getName())) { addSaveAndCompareTest(test, suite, file); } } return suite; } private static void addLoadTest(final JavaXMISerializationTest test, TestSuite suite, final File file) { suite.addTest(new TestCase("Loading " + file.getName()) { public void runTest() { try { test.loadResource(file.getAbsolutePath()); } catch (Exception e) { e.printStackTrace(); fail(e.getClass() + ": " + e.getMessage()); } } }); } private static void addTransferToXMITest(final JavaXMISerializationTest test, TestSuite suite) { suite.addTest(new TestCase("Coverting all Java resources to XMI") { public void runTest() { try { test.transferToXMI(); } catch (Exception e) { e.printStackTrace(); fail(e.getClass() + ": " + e.getMessage()); } } }); } private static void addSaveAndCompareTest(final JavaXMISerializationTest test, TestSuite suite, final File file) { suite.addTest(new TestCase("Saving and comparing XMI " + file.getName()) { public void runTest() { try { test.compare(file); } catch (Exception e) { e.printStackTrace(); fail(e.getClass() + ": " + e.getMessage()); } } }); } private ResourceSet sharedTestResourceSet = null; @Override protected ResourceSet getResourceSet() throws Exception { if (sharedTestResourceSet == null) { sharedTestResourceSet = super.getResourceSet(); } return sharedTestResourceSet; } @Override protected Map<? extends Object, ? extends Object> getLoadOptions() { Map<? extends Object, ? extends Object> m = super.getLoadOptions(); //m.put(XMIResource.OPTION_XML_VERSION, "1.1"); return m; } protected void transferToXMI() throws Exception { ResourceSet rs = getResourceSet(); EcoreUtil.resolveAll(rs); for (Resource javaResource : new ArrayList<Resource>(rs.getResources())) { assertResolveAllProxies(javaResource); if (javaResource.getContents().isEmpty()) { System.out.println("WARNING: Emtpy Resource: " + javaResource.getURI()); continue; } JavaRoot root = (JavaRoot) javaResource.getContents().get(0); String outputFileName = "ERROR"; if (root instanceof CompilationUnit) { outputFileName = root.getName().substring(0, root.getName().length() - 5).replace(".", File.separator); } else if (root instanceof Package) { outputFileName = root.getNamespacesAsString().replace(".", File.separator) + File.separator + root.getName() + File.separator + "package-info"; if (outputFileName.startsWith(File.separator)) { outputFileName = outputFileName.substring(1); } } else { fail(); } File outputFile = new File("." + File.separator + TEST_OUTPUT_FOLDER_NAME + File.separator + outputFileName); URI xmiFileURI = URI.createFileURI(outputFile.getAbsolutePath()).appendFileExtension("xmi"); Resource xmiResource = rs.createResource(xmiFileURI); xmiResource.getContents().addAll(javaResource.getContents()); } for (Resource xmiResource : rs.getResources()) { if (xmiResource instanceof XMIResource) { try { xmiResource.save(rs.getLoadOptions()); } catch (Exception e) { e.printStackTrace(); } } } } protected void compare(File file) throws Exception { ResourceSet rs = getResourceSet(); String outputXMIFileName = calculateOutputFilename(file, getTestInputFolder(), TEST_OUTPUT_FOLDER); URI xmiFileURI = URI.createFileURI(outputXMIFileName).trimFileExtension().appendFileExtension("xmi"); Resource xmiResource = rs.getResource(xmiFileURI, false); assertNotNull(xmiResource); EObject root = xmiResource.getContents().get(0); xmiResource.save(rs.getLoadOptions()); //reload ResourceSet reloadeSet = super.getResourceSet(); Resource reloadedResource = null; try { reloadedResource = reloadeSet.getResource(xmiFileURI, true); } catch (Exception e) { fail(e.getClass() + ": " + e.getMessage()); return; } assertResolveAllProxies(reloadedResource); for (Diagnostic d : reloadedResource.getErrors()) { System.out.println(d.getMessage()); } assertTrue("Parsed XMI contains errors", reloadedResource.getErrors().isEmpty()); EObject reloadedRoot = reloadedResource.getContents().get(0); EqualityHelper equalityHelper = new EqualityHelper() { private static final long serialVersionUID = 1L; @Override public boolean equals(EObject eObject1, EObject eObject2) { boolean result = super.equals(eObject1, eObject2); if (!result) { System.out.println("Not equal: " + eObject1 + " != " + eObject2); } return result; } @Override protected boolean haveEqualFeature(EObject eObject1, EObject eObject2, EStructuralFeature feature) { if (feature.isTransient()) { //ignore transient features return true; } return super.haveEqualFeature(eObject1, eObject2, feature); } }; assertTrue("Original and reloaded XMI are not equal", equalityHelper.equals(root, reloadedRoot)); } @Override protected boolean isExcludedFromReprintTest(String filename) { return true; } @Override protected String getTestInputFolder() { return TEST_INPUT_FOLDER_NAME; } }