/* * Copyright (c) 2006, 2007 Borland Software Corporation * * 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: * Dmitry Stadnik - initial API and implementation */ package org.eclipse.gmf.internal.bridge.wizards.pages.simple; import java.util.Iterator; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.gmf.gmfgraph.Canvas; import org.eclipse.gmf.gmfgraph.ChildAccess; import org.eclipse.gmf.gmfgraph.Connection; import org.eclipse.gmf.gmfgraph.DecorationFigure; import org.eclipse.gmf.gmfgraph.DiagramElement; import org.eclipse.gmf.gmfgraph.DiagramLabel; import org.eclipse.gmf.gmfgraph.FigureDescriptor; import org.eclipse.gmf.gmfgraph.FigureGallery; import org.eclipse.gmf.gmfgraph.GMFGraphFactory; import org.eclipse.gmf.gmfgraph.GMFGraphPackage; import org.eclipse.gmf.gmfgraph.Identity; import org.eclipse.gmf.gmfgraph.Label; import org.eclipse.gmf.gmfgraph.Node; import org.eclipse.gmf.gmfgraph.PolylineConnection; import org.eclipse.gmf.gmfgraph.RealFigure; import org.eclipse.gmf.gmfgraph.Rectangle; import org.eclipse.gmf.internal.bridge.wizards.WizardUtil; import org.eclipse.gmf.internal.bridge.wizards.pages.simple.ResolvedItem.Resolution; import org.eclipse.gmf.internal.common.IncrementalNamesDispenser; import org.eclipse.gmf.internal.common.NamesDispenser; /** * @author dstadnik */ public class GraphDefBuilder { protected final Canvas existingCanvas; protected final GMFGraphFactory gmfGraphFactory = GMFGraphPackage.eINSTANCE.getGMFGraphFactory(); protected final NamesDispenser namesDispenser = new IncrementalNamesDispenser(); protected Canvas canvas; protected FigureGallery fGallery; public GraphDefBuilder(Canvas existingCanvas) { this.existingCanvas = existingCanvas; } public static DiagramElement getDiagramElement(Iterator<EObject> source, EObject domainElement) { String name = WizardUtil.getCapName(domainElement); if (name == null) { return null; } return getDiagramElement(source, name); } public static DiagramElement getDiagramElement(Iterator<EObject> source, String domainObjectName) { while (source.hasNext()) { Object next = source.next(); if (next instanceof DiagramElement && domainObjectName.equals(((DiagramElement) next).getName())) { return (DiagramElement) next; } } return null; } protected String getUniqueName(String semanticPart) { return namesDispenser.get(semanticPart); } protected String getUniqueName(String semanticPart, String suffixPart) { return namesDispenser.get(semanticPart, suffixPart); } protected void addExistingName(String name) { if (name != null) { namesDispenser.add(name); } } protected void addExistingNames(Canvas canvas) { for (Iterator<EObject> it = canvas.eAllContents(); it.hasNext();) { EObject next = it.next(); if (next instanceof Identity) { addExistingName(((Identity) next).getName()); } } } public Canvas process(ResolvedItem item) { if (existingCanvas == null) { canvas = gmfGraphFactory.createCanvas(); } else { canvas = existingCanvas; addExistingNames(existingCanvas); } if (item != null) { if (canvas != existingCanvas) { EPackage ePackage = (EPackage) item.getDomainRef(); canvas.setName(getUniqueName(ePackage.getName())); } fGallery = null; for (Object figure : canvas.getFigures()) { if (figure instanceof FigureGallery) { fGallery = (FigureGallery) figure; } } if (fGallery == null) { fGallery = gmfGraphFactory.createFigureGallery(); fGallery.setName(getUniqueName(Messages.GraphDefBuilder0)); canvas.getFigures().add(fGallery); } for (ResolvedItem child : item.getChildren()) { process(child, null); } } return canvas; } protected void process(ResolvedItem item, DiagramElement parent) { DiagramElement newParent = getDiagramElement(canvas.eAllContents(), (EObject) item.getDomainRef()); if (item.isDisabled()) { assert newParent != null : "For disabled item there should be a diagram element with the appropriate name"; //$NON-NLS-1$ // Process child items since there may be new labels for existing node } else { if (item.getDomainRef() instanceof EClass) { EClass type = (EClass) item.getDomainRef(); if (item.getResolution() == Resolution.NODE) { newParent = createNode(type); } else if (item.getResolution() == Resolution.LINK) { newParent = createLink(type); } } else if (item.getDomainRef() instanceof EReference) { EReference ref = (EReference) item.getDomainRef(); if (item.getResolution() == Resolution.LINK) { EClass containingClass = (EClass) item.getParent().getDomainRef(); newParent = createLink(ref, containingClass); } } else if (item.getDomainRef() instanceof EAttribute) { EAttribute attr = (EAttribute) item.getDomainRef(); if (item.getResolution() == Resolution.LABEL) { EClass containingClass = (EClass) item.getParent().getDomainRef(); newParent = createLabel(attr, containingClass, parent); } } } for (ResolvedItem next : item.getChildren()) { process(next, newParent); } } protected Node createNode(EClass type) { String baseName = WizardUtil.getCapName(type); Rectangle figure = gmfGraphFactory.createRectangle(); figure.setName(getUniqueName(baseName, Messages.GraphDefBuilder1)); Node node = gmfGraphFactory.createNode(); node.setFigure(newDescriptor(figure.getName(), figure)); fGallery.getDescriptors().add(node.getFigure()); node.setName(getUniqueName(baseName, null)); canvas.getNodes().add(node); return node; } protected Connection createLink(EClass type) { String baseName = WizardUtil.getCapName(type); PolylineConnection figure = gmfGraphFactory.createPolylineConnection(); figure.setName(getUniqueName(baseName, Messages.GraphDefBuilder1)); Connection link = gmfGraphFactory.createConnection(); link.setFigure(newDescriptor(figure.getName(), figure)); fGallery.getDescriptors().add(link.getFigure()); link.setName(getUniqueName(baseName, null)); canvas.getConnections().add(link); return link; } protected Connection createLink(EReference ref, EClass containingClass) { String baseName = WizardUtil.getCapName(ref, containingClass); PolylineConnection figure = gmfGraphFactory.createPolylineConnection(); figure.setName(getUniqueName(baseName, Messages.GraphDefBuilder1)); DecorationFigure decoration = gmfGraphFactory.createPolylineDecoration(); decoration.setName(getUniqueName(baseName, Messages.GraphDefBuilder6)); figure.setTargetDecoration(decoration); fGallery.getFigures().add(decoration); Connection link = gmfGraphFactory.createConnection(); link.setFigure(newDescriptor(figure.getName(), figure)); fGallery.getDescriptors().add(link.getFigure()); link.setName(getUniqueName(baseName, null)); canvas.getConnections().add(link); return link; } protected DiagramLabel createLabel(EAttribute attr, EClass containingClass, DiagramElement parent) { if (parent == null) { return null; // makes no sense to define label without parent } String baseName = WizardUtil.getCapName(attr, containingClass); Label figure = gmfGraphFactory.createLabel(); figure.setName(getUniqueName(baseName, Messages.GraphDefBuilder1)); figure.setText(Messages.GraphDefBuilder5); assert parent.getFigure().getActualFigure() instanceof RealFigure : "We are creators of this gmfgraph; there should be nothing but figure"; //$NON-NLS-1$ final RealFigure realFigure = (RealFigure) parent.getFigure().getActualFigure(); if (parent instanceof Node) { // safety check, not sure whether labels for links are created here or not if (realFigure.getLayout() == null) { realFigure.setLayout(GMFGraphFactory.eINSTANCE.createFlowLayout()); } } realFigure.getChildren().add(figure); DiagramLabel label = gmfGraphFactory.createDiagramLabel(); label.setFigure(parent.getFigure()); label.setAccessor(newAccess(parent.getFigure(), figure)); label.setName(getUniqueName(baseName, null)); canvas.getLabels().add(label); return label; } private static FigureDescriptor newDescriptor(String name, RealFigure fig) { FigureDescriptor fd = GMFGraphFactory.eINSTANCE.createFigureDescriptor(); fd.setActualFigure(fig); fd.setName(name); return fd; } private static ChildAccess newAccess(FigureDescriptor fd, RealFigure child) { ChildAccess ca = GMFGraphFactory.eINSTANCE.createChildAccess(); ca.setFigure(child); fd.getAccessors().add(ca); return ca; } }