/* * Copyright (c) 2007, 2010 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: * Alexander Fedorov (Borland) - initial API and implementation */ package org.eclipse.gmf.tests.tr; import java.io.IOException; import java.net.URL; import java.util.Collections; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.ContentHandler; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator; import org.eclipse.gmf.gmfgraph.Canvas; import org.eclipse.gmf.gmfgraph.Connection; import org.eclipse.gmf.gmfgraph.DiagramLabel; import org.eclipse.gmf.gmfgraph.Node; import org.eclipse.gmf.internal.bridge.transform.GenModelDetector; import org.eclipse.gmf.internal.bridge.transform.TransformToGenModelOperation; import org.eclipse.gmf.internal.common.URIUtil; import org.eclipse.gmf.mappings.CanvasMapping; import org.eclipse.gmf.mappings.GMFMapFactory; import org.eclipse.gmf.mappings.LinkMapping; import org.eclipse.gmf.mappings.Mapping; import org.eclipse.gmf.mappings.NodeMapping; import org.eclipse.gmf.mappings.TopNodeReference; import org.eclipse.gmf.tests.ConfiguredTestCase; import org.eclipse.gmf.tests.Plugin; import org.eclipse.gmf.tests.setup.DiaDefSetup; import org.eclipse.gmf.tests.setup.DiaDefSource; import org.eclipse.gmf.tests.setup.MapDefSource; import org.eclipse.gmf.tests.setup.ToolDefSource; public class TransformToGenModelOperationTest extends ConfiguredTestCase { public TransformToGenModelOperationTest(String name) { super(name); } private static String FOLDER_MODELS = "models"; //$NON-NLS-1$ private static String FILE_BASE = "test"; //$NON-NLS-1$ private static String FILE_EXT_ECORE = "ecore"; //$NON-NLS-1$ private static String FILE_EXT_GMFGEN = "gmfgen"; //$NON-NLS-1$ private static String FILE_EXT_GMFGRAPH = "gmfgraph"; //$NON-NLS-1$ private static String FILE_EXT_GMFMAP = "gmfmap"; //$NON-NLS-1$ private static String FILE_EXT_GMFTOOL = "gmftool"; //$NON-NLS-1$ private IProject myProject; private TransformToGenModelOperation myOperation; @Override protected void setUp() throws Exception { super.setUp(); myOperation = new TransformToGenModelOperation(new ResourceSetImpl()); myProject = createProject(); IFolder models = myProject.getFolder(FOLDER_MODELS); models.create(true, false, new NullProgressMonitor()); } @Override protected void tearDown() throws Exception { deleteProject(); myProject = null; myOperation = null; super.tearDown(); } public void testErrorArguments() { ResourceSetImpl rs = new ResourceSetImpl(); URI toolURI = prepareResource(rs, FILE_EXT_GMFTOOL, getSetup().getToolDefModel().getRegistry()); prepareResource(rs, FILE_EXT_GMFMAP, getSetup().getMapModel().getMapping()); try { myOperation.loadMappingModel(toolURI, null); fail("Invalid MappingModel should not be accepted"); } catch (CoreException e) { Diagnostic validationResult = myOperation.getMapmodelValidationResult(); assertNotNull("MappingModel validation result should be set", validationResult); assertFalse("Load MappingModel status should differ from OK value", IStatus.OK == validationResult.getSeverity()); assertNull("GenModelDetector should be reset", myOperation.getGenModelDetector()); assertNull("GenModel should be reset", myOperation.getGenModel()); } try { myOperation.loadMappingModel(null, null); fail("null gmfmap URI should not be accepted"); } catch (CoreException e) { assertIllegalArgument(e); } } public void testErrorState() { IStatus s = myOperation.executeTransformation(null); assertFalse("Target gmfgen URI should be specified", s.isOK()); myOperation.setGenURI(createURI(FILE_EXT_GMFGEN)); s = myOperation.executeTransformation(null); assertFalse("Mapping model should be loaded before calling executeTransformation()", s.isOK()); try { myOperation.loadGenModel(null, null); fail("MappingModel should be loaded before calling loadGenModel()"); } catch (CoreException e) { assertIllegalState(e); } try { myOperation.findGenmodel(); fail("MappingModel should be loaded before calling findGenmodel()"); } catch (CoreException e) { assertIllegalState(e); } } public void testTransformMappingModel() { URI mapURI = prepareResources(); loadMappingModel(mapURI); findAbsentGenmodel(); URI genmodelURI = createDefaultGenModel(mapURI); GenModel genModel = null; try { genModel = myOperation.loadGenModel(genmodelURI, null); assertNotNull("Failed to load GenModel", genModel); } catch (CoreException e) { assertNotNull("Failed to load GenModel", genModel); } myOperation.setGenURI(createURI(FILE_EXT_GMFGEN)); IStatus status = myOperation.executeTransformation(null); assertTrue(status.isOK()); } public void testTransfromDesignMapping() { URI mapURI = prepareDesignResources(); loadMappingModel(mapURI); myOperation.setGenURI(createURI(FILE_EXT_GMFGEN)); IStatus status = myOperation.executeTransformation(null); assertTrue(status.isOK()); } public void testPreReconcileHookOption() throws Exception { URI mapURI = prepareResources(); loadMappingModel(mapURI); // GenModelDetector#detect() should be invoked prior to #createDefaultGenModel() myOperation.getGenModelDetector().detect(); myOperation.loadGenModel(createDefaultGenModel(mapURI), null); myOperation.setGenURI(createURI(FILE_EXT_GMFGEN)); // assertNull("[sanity]", myOperation.getOptions().getPostReconcileTransform()); // no post-reconcile hook, only pre-reconcile myOperation.getOptions().setPreReconcileTransform(new URL(Plugin.createURI("/transforms/PrePostReconcileHook.qvto").toString())); // IStatus status = myOperation.executeTransformation(null); assertTrue(status.isOK()); GenEditorGenerator result = (GenEditorGenerator) myOperation.getResourceSet().getResource(myOperation.getGenURI(), true).getContents().get(0); assertNull("PreReconcile hook is expected to clean genEditor.navigator", result.getNavigator()); } public void testPostReconcileHookOption() throws Exception { URI mapURI = prepareResources(); loadMappingModel(mapURI); myOperation.getGenModelDetector().detect(); myOperation.loadGenModel(createDefaultGenModel(mapURI), null); myOperation.setGenURI(createURI(FILE_EXT_GMFGEN)); // assertNull("[sanity]", myOperation.getOptions().getPreReconcileTransform()); // no pre-reconcile hook, only post-reconcile myOperation.getOptions().setPostReconcileTransform(new URL(Plugin.createURI("/transforms/PrePostReconcileHook.qvto").toString())); // IStatus status = myOperation.executeTransformation(null); assertTrue(status.isOK()); GenEditorGenerator result = (GenEditorGenerator) myOperation.getResourceSet().getResource(myOperation.getGenURI(), true).getContents().get(0); assertNull("PostReconcile hook is expected to clean genEditor.navigator", result.getNavigator()); } private void loadMappingModel(URI mapURI) { Mapping mapping = null; try { mapping = myOperation.loadMappingModel(mapURI, null); assertNotNull("Mapping should be resolved", mapping); Diagnostic validationResult = myOperation.getMapmodelValidationResult(); assertNotNull("MappingModel validation result should be set", validationResult); assertFalse("MappingModel validation result should differ from CANCEL value", IStatus.CANCEL == validationResult.getSeverity()); assertFalse("MappingModel validation result should differ from ERROR value", IStatus.ERROR == validationResult.getSeverity()); assertNotNull("GenModelDetector should be initialized", myOperation.getGenModelDetector()); assertNull("GenModel should be reset", myOperation.getGenModel()); } catch (CoreException e) { fail(e.getStatus().getMessage()); } } private void findAbsentGenmodel() { try { myOperation.findGenmodel(); fail("GenModel should not be found"); } catch (CoreException e) { assertNull("GenModel should not be found", myOperation.getGenModel()); } } private URI createDefaultGenModel(URI mapURI) { URI genmodelURI = null; try { GenModelDetector gmd = myOperation.getGenModelDetector(); assertNotNull("GenModelDetector should be initialized", gmd); genmodelURI = gmd.createDefault(getProject().getName(), URIUtil.getFile(mapURI)); assertNotNull("GenModel URI should be created", genmodelURI); IFile file = URIUtil.getFile(mapURI); assertNotNull("GenModel file should be created", file); assertTrue("GenModel file should exists", file.exists()); } catch (CoreException e) { fail("Failed to create default GenModel: " + e.getMessage()); } return genmodelURI; } protected IProject createProject() { String projectName = "TransformToGenModelOperationTest_" + String.valueOf(System.currentTimeMillis()); //$NON-NLS-1$ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); assertFalse("Project with this name already present in the workspace: " + projectName, project.exists()); try { project.create(new NullProgressMonitor()); project.open(new NullProgressMonitor()); } catch (CoreException e) { fail(e.getMessage()); } assertTrue("Project was not created: " + projectName, project.exists()); return project; } protected void deleteProject() throws CoreException { if (getProject() != null) { if (getProject().isOpen()) { getProject().close(new NullProgressMonitor()); } if (getProject().exists()) { getProject().delete(true, new NullProgressMonitor()); } } } protected IProject getProject() { return myProject; } private URI prepareResources() { ResourceSet rs = new ResourceSetImpl(); prepareResource(rs, FILE_EXT_ECORE, getSetup().getDomainModel().getModel()); prepareResource(rs, FILE_EXT_GMFGRAPH, getSetup().getGraphDefModel().getCanvasDef()); prepareResource(rs, FILE_EXT_GMFTOOL, getSetup().getToolDefModel().getRegistry()); URI mapURI = prepareResource(rs, FILE_EXT_GMFMAP, getSetup().getMapModel().getMapping()); return mapURI; } private URI prepareDesignResources() { ResourceSet rs = new ResourceSetImpl(); DiaDefSource ddSource = getSetup().getGraphDefModel(); prepareResource(rs, FILE_EXT_GMFGRAPH, ddSource.getCanvasDef()); ToolDefSource toolDef = getSetup().getToolDefModel(); prepareResource(rs, FILE_EXT_GMFTOOL, toolDef.getRegistry()); URI mapURI = prepareResource(rs, FILE_EXT_GMFMAP, new DesignMapDefSource().init(ddSource, toolDef).getMapping()); return mapURI; } private URI prepareResource(ResourceSet rs, String extension, EObject root) { URI uri = createURI(extension); Resource resource = rs.createResource(uri, ContentHandler.UNSPECIFIED_CONTENT_TYPE); resource.getContents().add(root); try { resource.save(Collections.EMPTY_MAP); } catch (IOException e) { fail("Failed to save " + uri.toFileString() + " :" + e.getMessage()); } return uri; } private URI createURI(String extension) { String pathName = getProject().getName() + IPath.SEPARATOR + FOLDER_MODELS + IPath.SEPARATOR + FILE_BASE + "." + extension; //$NON-NLS-1$ URI uri = URI.createPlatformResourceURI(pathName, true); return uri; } private void assertIllegalArgument(CoreException e) { Throwable cause = e.getStatus().getException(); if (!(cause instanceof IllegalArgumentException)) { fail(e.getMessage()); } } private void assertIllegalState(CoreException e) { Throwable cause = e.getStatus().getException(); if (!(cause instanceof IllegalStateException)) { fail(e.getMessage()); } } private class DesignMapDefSource implements MapDefSource { private Mapping myMap; private NodeMapping myNodeA; private NodeMapping myNodeB; private LinkMapping myClassLink; private LinkMapping myRefLink; public DesignMapDefSource() { // just create } public DesignMapDefSource init(DiaDefSource ddSource, ToolDefSource toolDef) { initCanvasMapping(ddSource.getCanvasDef()); if (toolDef.getMainMenu() != null) { myMap.getDiagram().getMenuContributions().add(toolDef.getMainMenu()); } myMap.getDiagram().setPalette(toolDef.getPalette()); initCommonMapping(ddSource, toolDef); return this; } private void initCanvasMapping(Canvas canvas) { Mapping m = GMFMapFactory.eINSTANCE.createMapping(); CanvasMapping cme = GMFMapFactory.eINSTANCE.createCanvasMapping(); cme.setDiagramCanvas(canvas); m.setDiagram(cme); myMap = m; } private void initCommonMapping(DiaDefSource ddSource, ToolDefSource toolDef) { myNodeA = createNodeMapping(ddSource.getNodeDef(), ddSource.getLabelDef(), true); myNodeA.setContextMenu(toolDef.getNodeContextMenu()); myNodeA.setTool(toolDef.getNodeCreationTool()); DiaDefSetup ddSetup = ddSource instanceof DiaDefSetup ? (DiaDefSetup) ddSource : null; Node graphNode = ddSetup != null ? ddSetup.getColoredNodeDef() : ddSource.getNodeDef(); DiagramLabel graphLabel = ddSetup != null ? ddSetup.getDecoratedLabelDef() : ddSource.getLabelDef(); myNodeB = createNodeMapping(graphNode, graphLabel, true); myClassLink = createLinkMapping(ddSource.getLinkDef()); myClassLink.setTool(toolDef.getLinkCreationTool()); myRefLink = createLinkMapping(ddSetup != null ? ddSetup.getColoredLinkDef() : ddSource.getLinkDef()); } private final NodeMapping createNodeMapping(Node nodeDef, DiagramLabel labelDef, boolean addTopNodeReference) { NodeMapping nme = GMFMapFactory.eINSTANCE.createNodeMapping(); nme.setDiagramNode(nodeDef); if (addTopNodeReference){ TopNodeReference tnr = GMFMapFactory.eINSTANCE.createTopNodeReference(); tnr.setOwnedChild(nme); myMap.getNodes().add(tnr); } return nme; } private LinkMapping createLinkMapping(Connection link) { LinkMapping lme = GMFMapFactory.eINSTANCE.createLinkMapping(); lme.setDiagramLink(link); myMap.getLinks().add(lme); return lme; } public final Mapping getMapping() { return myMap; } public NodeMapping getNodeA() { return myNodeA; } public NodeMapping getNodeB() { return myNodeB; } public LinkMapping getClassLink() { return myClassLink; } public LinkMapping getReferenceLink() { return myRefLink; } } }