X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fsynchronization%2Fgraph%2FAddElement.java;h=4edd471016fafe9efe9fa268fd77a8f1076e2d72;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=05d2d1e760e4983df4383cf7a33dec990bcb6a49;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/AddElement.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/AddElement.java index 05d2d1e76..4edd47101 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/AddElement.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/AddElement.java @@ -1,170 +1,170 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.diagram.synchronization.graph; - -import java.awt.geom.AffineTransform; - -import org.simantics.databoard.Bindings; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.utils.CommonDBUtils; -import org.simantics.db.common.utils.OrderedSetUtils; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.util.Layer0Utils; -import org.simantics.diagram.stubs.DiagramResource; -import org.simantics.diagram.synchronization.CopyAdvisor; -import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; -import org.simantics.diagram.synchronization.ModificationAdapter; -import org.simantics.diagram.synchronization.SynchronizationHints; -import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; -import org.simantics.diagram.ui.DiagramModelHints; -import org.simantics.g2d.diagram.DiagramHints; -import org.simantics.g2d.diagram.DiagramMutator; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.element.ElementHints; -import org.simantics.g2d.element.ElementUtils; -import org.simantics.g2d.element.IElement; -import org.simantics.layer0.Layer0; - -/** - * @author Tuukka Lehtonen - */ -public class AddElement extends ModificationAdapter { - - //private static final boolean DEBUG_ELEMENT_COPY = false; - - IModifiableSynchronizationContext context; - IDiagram diagram; - Resource diagramResource; - IElement element; - Resource copyOf; - - public AddElement(IModifiableSynchronizationContext context, IDiagram d, IElement element) { - super(ADD_NODE_PRIORITY); - - assert context != null; - assert d != null; - assert element != null; - - this.context = context; - this.diagram = d; - this.diagramResource = d.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); - assert this.diagramResource != null; - this.element = element; - this.copyOf = element.getHint(ElementHints.KEY_COPY_OF_OBJECT); - } - - @Override - public void perform(WriteGraph g) throws Exception { - BasicResources br = context.get(GraphSynchronizationHints.BASIC_RESOURCES); - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - - CommonDBUtils.selectClusterSet(g, diagramResource); - - // 1. Resolve the element class to instantiate the new element from. - Resource elementClass = ElementUtils.checkedAdapt(element.getElementClass(), Resource.class); - - // 2. Resolve custom element writer - ElementWriter writer = element.removeHint(DiagramModelHints.KEY_ELEMENT_WRITER); - if (writer == null) - writer = g.adapt(elementClass, ElementWriter.class); - - Resource resource = null; - - // 3. Try to copy the element from an existing element if requested. - if (copyOf instanceof Resource) { - CopyAdvisor ca = diagram.getHint(SynchronizationHints.COPY_ADVISOR); - if (ca != null) { - Resource sourceDiagram = g.getPossibleObject(copyOf, Layer0.getInstance(g).PartOf); - resource = CopyAdvisorUtil.copy(context, g, ca, copyOf, sourceDiagram, diagramResource); - } - } - - if (resource == null) { - // Copying either was not issued or couldn't be performed. - // Create target resource for the new element. - resource = g.newResource(); - g.claim(resource, br.L0.InstanceOf, null, elementClass); - } - - // Add comment to change set. -// CommentMetadata cm = g.getMetadata(CommentMetadata.class); -// g.addMetadata(cm.add("Added element " + resource)); - - // 4. add the new element to the diagram composite - OrderedSetUtils.add(g, diagramResource, resource); - - // 4.1. Give running name to element and increment the counter attached to the diagram. - String name = claimFreshElementName(g, diagramResource, resource); - - // Add comment to change set. - Layer0Utils.addCommentMetadata(g, "Added element " + name + " " + resource + " to composite " + diagramResource); - - // 4.2. Make the diagram consist of the new element - g.claim(diagramResource, br.L0.ConsistsOf, resource); - - // 5. Synchronize the transformation of the element - AffineTransform at = element.getHint(ElementHints.KEY_TRANSFORM); - if (at != null) - DiagramGraphUtil.setTransform(g, resource, at); - - // 6. Perform custom per element type synchronization to graph - writer.addToGraph(g, element, resource); - - // 7. Register the newly created element resource with mutator in case - // any other modification needs to reference it later on in the mutator - // commit process. - element.setHint(ElementHints.KEY_OBJECT, resource); - mutator.register(element, resource); - - // 7. Put the element on all the currently active layers if possible. - GraphLayerManager glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); - if (glm != null) { - glm.removeFromAllLayers(g, resource); - glm.putElementOnVisibleLayers(diagram, g, resource); - } - } - -// String findFreshName(ReadGraph graph, Resource container) throws DatabaseException { -// Set children = graph.syncRequest(new UnescapedChildMapOfResource(container)).keySet(); -// String id; -// for (int i = 0; children.contains(id = String.valueOf(i)); ++i); -// return id; -// } - - /** - * Names the specified element on the specified diagram based on a numeric - * ascending counter attached to the diagram. The purpose of the counter is - * to optimize name generation compared to always getting the names of each - * diagram element to make sure nothing collides. This method is much faster - * but obviously there is room for error. - * - * @param graph - * @param diagram - * @param element - * @return - * @throws DatabaseException - */ - public static final String claimFreshElementName(WriteGraph graph, Resource diagram, Resource element) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - DiagramResource DIA = DiagramResource.getInstance(graph); - // Give running name to element and increment the counter attached to the diagram. - Long l = graph.getPossibleRelatedValue(diagram, DIA.HasModCount, Bindings.LONG); - if (l == null) - l = Long.valueOf(0L); - String name = l.toString(); - graph.claimLiteral(element, L0.HasName, name, Bindings.STRING); - graph.claimLiteral(diagram, DIA.HasModCount, ++l, Bindings.LONG); - return name; - } - +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.diagram.synchronization.graph; + +import java.awt.geom.AffineTransform; + +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.synchronization.CopyAdvisor; +import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; +import org.simantics.diagram.synchronization.ModificationAdapter; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.layer0.Layer0; + +/** + * @author Tuukka Lehtonen + */ +public class AddElement extends ModificationAdapter { + + //private static final boolean DEBUG_ELEMENT_COPY = false; + + IModifiableSynchronizationContext context; + IDiagram diagram; + Resource diagramResource; + IElement element; + Resource copyOf; + + public AddElement(IModifiableSynchronizationContext context, IDiagram d, IElement element) { + super(ADD_NODE_PRIORITY); + + assert context != null; + assert d != null; + assert element != null; + + this.context = context; + this.diagram = d; + this.diagramResource = d.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); + assert this.diagramResource != null; + this.element = element; + this.copyOf = element.getHint(ElementHints.KEY_COPY_OF_OBJECT); + } + + @Override + public void perform(WriteGraph g) throws Exception { + BasicResources br = context.get(GraphSynchronizationHints.BASIC_RESOURCES); + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + + CommonDBUtils.selectClusterSet(g, diagramResource); + + // 1. Resolve the element class to instantiate the new element from. + Resource elementClass = ElementUtils.checkedAdapt(element.getElementClass(), Resource.class); + + // 2. Resolve custom element writer + ElementWriter writer = element.removeHint(DiagramModelHints.KEY_ELEMENT_WRITER); + if (writer == null) + writer = g.adapt(elementClass, ElementWriter.class); + + Resource resource = null; + + // 3. Try to copy the element from an existing element if requested. + if (copyOf instanceof Resource) { + CopyAdvisor ca = diagram.getHint(SynchronizationHints.COPY_ADVISOR); + if (ca != null) { + Resource sourceDiagram = g.getPossibleObject(copyOf, Layer0.getInstance(g).PartOf); + resource = CopyAdvisorUtil.copy(context, g, ca, copyOf, sourceDiagram, diagramResource); + } + } + + if (resource == null) { + // Copying either was not issued or couldn't be performed. + // Create target resource for the new element. + resource = g.newResource(); + g.claim(resource, br.L0.InstanceOf, null, elementClass); + } + + // Add comment to change set. +// CommentMetadata cm = g.getMetadata(CommentMetadata.class); +// g.addMetadata(cm.add("Added element " + resource)); + + // 4. add the new element to the diagram composite + OrderedSetUtils.add(g, diagramResource, resource); + + // 4.1. Give running name to element and increment the counter attached to the diagram. + String name = claimFreshElementName(g, diagramResource, resource); + + // Add comment to change set. + Layer0Utils.addCommentMetadata(g, "Added element " + name + " " + resource + " to composite " + diagramResource); + + // 4.2. Make the diagram consist of the new element + g.claim(diagramResource, br.L0.ConsistsOf, resource); + + // 5. Synchronize the transformation of the element + AffineTransform at = element.getHint(ElementHints.KEY_TRANSFORM); + if (at != null) + DiagramGraphUtil.setTransform(g, resource, at); + + // 6. Perform custom per element type synchronization to graph + writer.addToGraph(g, element, resource); + + // 7. Register the newly created element resource with mutator in case + // any other modification needs to reference it later on in the mutator + // commit process. + element.setHint(ElementHints.KEY_OBJECT, resource); + mutator.register(element, resource); + + // 7. Put the element on all the currently active layers if possible. + GraphLayerManager glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); + if (glm != null) { + glm.removeFromAllLayers(g, resource); + glm.putElementOnVisibleLayers(diagram, g, resource); + } + } + +// String findFreshName(ReadGraph graph, Resource container) throws DatabaseException { +// Set children = graph.syncRequest(new UnescapedChildMapOfResource(container)).keySet(); +// String id; +// for (int i = 0; children.contains(id = String.valueOf(i)); ++i); +// return id; +// } + + /** + * Names the specified element on the specified diagram based on a numeric + * ascending counter attached to the diagram. The purpose of the counter is + * to optimize name generation compared to always getting the names of each + * diagram element to make sure nothing collides. This method is much faster + * but obviously there is room for error. + * + * @param graph + * @param diagram + * @param element + * @return + * @throws DatabaseException + */ + public static final String claimFreshElementName(WriteGraph graph, Resource diagram, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + // Give running name to element and increment the counter attached to the diagram. + Long l = graph.getPossibleRelatedValue(diagram, DIA.HasModCount, Bindings.LONG); + if (l == null) + l = Long.valueOf(0L); + String name = l.toString(); + graph.claimLiteral(element, L0.HasName, name, Bindings.STRING); + graph.claimLiteral(diagram, DIA.HasModCount, ++l, Bindings.LONG); + return name; + } + } \ No newline at end of file