/** | |
* <copyright> | |
* | |
* Copyright (c) 2014 Thales Corporate Services S.A.S. | |
* This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/legal/epl-v2.0 | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Thales Corporate Services S.A.S - initial API and implementation | |
* | |
* </copyright> | |
*/ | |
package org.eclipse.egf.portfolio.genchain.ecoretools.command; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import org.eclipse.emf.common.util.BasicEList; | |
import org.eclipse.emf.common.util.EList; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.transaction.RecordingCommand; | |
import org.eclipse.emf.transaction.TransactionalEditingDomain; | |
import org.eclipse.sirius.business.api.session.Session; | |
import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException; | |
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; | |
import org.eclipse.sirius.diagram.AbstractDNode; | |
import org.eclipse.sirius.diagram.DDiagram; | |
import org.eclipse.sirius.diagram.DSemanticDiagram; | |
import org.eclipse.sirius.diagram.DragAndDropTarget; | |
import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager; | |
import org.eclipse.sirius.diagram.business.api.query.AbstractNodeMappingQuery; | |
import org.eclipse.sirius.diagram.business.internal.componentization.mappings.DiagramMappingsManagerRegistryImpl; | |
import org.eclipse.sirius.diagram.business.internal.experimental.sync.AbstractDNodeCandidate; | |
import org.eclipse.sirius.diagram.business.internal.experimental.sync.DDiagramSynchronizer; | |
import org.eclipse.sirius.diagram.description.AbstractNodeMapping; | |
import org.eclipse.sirius.diagram.description.ContainerMapping; | |
import org.eclipse.sirius.diagram.description.DiagramElementMapping; | |
import org.eclipse.sirius.diagram.description.NodeMapping; | |
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor; | |
//import org.eclipse.sirius.business.internal.componentization.mappings.DiagramMappingsManagerRegistryImpl; | |
//import org.eclipse.sirius.business.internal.experimental.sync.AbstractDNodeCandidate; | |
//import org.eclipse.sirius.business.internal.experimental.sync.DDiagramSynchronizer; | |
//import org.eclipse.sirius.business.api.componentization.DiagramMappingsManager; | |
//import org.eclipse.sirius.business.api.query.AbstractNodeMappingQuery; | |
/** | |
* Recording command allowing to create a node in a diagram | |
* | |
* @see CreateEdgeCommand | |
* | |
* @author Boubekeur Zendagui | |
*/ | |
@SuppressWarnings("restriction") | |
public class CreateNodeCommand extends RecordingCommand { | |
/** Command properties **/ | |
private DDiagram _diagram; | |
private Session _session; | |
private AbstractNodeMapping _mapping; | |
private EObject _target; | |
/** Internal properties **/ | |
private DDiagramSynchronizer diagramSynchronizer; | |
private DiagramMappingsManager diagramMappingsManager; | |
private IInterpreter interpreter; | |
private ModelAccessor modelAccessor; | |
/** | |
* Default constructor | |
* @param session used {@link Session} to create representations | |
* @param diagram {@link DDiagram} wherein the node will be created | |
* @param mapping an {@link AbstractNodeMapping} used to create the node | |
* @param target semantic element | |
*/ | |
public CreateNodeCommand(Session session, DDiagram diagram, AbstractNodeMapping mapping, EObject target ) { | |
this(session.getTransactionalEditingDomain()); | |
this._diagram = diagram; | |
this._session = session; | |
this._mapping = mapping; | |
this._target = target; | |
/* This properties are set as class properties because they are used in a recursive method #createOneNode(). | |
* This allows to control created instance number. */ | |
this.interpreter = _session.getInterpreter(); | |
this.diagramSynchronizer = new DDiagramSynchronizer(this.interpreter, _diagram.getDescription(), _session.getModelAccessor()); | |
this.diagramSynchronizer.setDiagram((DSemanticDiagram)_diagram); | |
this.diagramMappingsManager = DiagramMappingsManagerRegistryImpl.INSTANCE.getDiagramMappingsManager(_session, _diagram); | |
this.modelAccessor = _session.getModelAccessor(); | |
} | |
/** | |
* Hidden constructor | |
* @param domain {@link TransactionalEditingDomain} | |
*/ | |
private CreateNodeCommand(TransactionalEditingDomain domain) { | |
super(domain); | |
} | |
@Override | |
protected void doExecute() { | |
AbstractNodeMappingQuery abstractNodeMappingQuery = new AbstractNodeMappingQuery(_mapping); | |
boolean preCondition = abstractNodeMappingQuery.evaluatePrecondition((DSemanticDiagram)_diagram, _diagram, interpreter, _target); | |
if (preCondition) | |
{ | |
createNodeAndItChildrenNodes(_target, _mapping, _diagram); | |
} | |
} | |
/** | |
* Create node and its sub nodes if there is sub mappings defined in it description | |
* @param nodeMapping current {@link AbstractNodeMapping} which can be a {@link NodeMapping} or a {@link ContainerMapping} | |
* @param semantic current root semantic element | |
* @param parent a {@link DragAndDropTarget} element wherein the node will be created | |
*/ | |
private void createNodeAndItChildrenNodes(EObject semantic, AbstractNodeMapping nodeMapping, DragAndDropTarget parent){ | |
// create concerned node | |
AbstractDNode parentNode = createOneNode(semantic, nodeMapping, parent); | |
// create it sub nodes | |
EList<AbstractNodeMapping> childrenNodeMapping = new BasicEList<AbstractNodeMapping>(); | |
for (DiagramElementMapping iDiagramElementMapping : nodeMapping.getAllMappings()) | |
{ | |
if (iDiagramElementMapping instanceof AbstractNodeMapping) | |
childrenNodeMapping.add((AbstractNodeMapping) iDiagramElementMapping); | |
} | |
for (AbstractNodeMapping childNodeMapping : childrenNodeMapping) | |
{ | |
Collection<EObject> candidatesSemanticChildren = new ArrayList<EObject>(); | |
try { | |
candidatesSemanticChildren = interpreter.evaluateCollection(semantic, childNodeMapping.getSemanticCandidatesExpression()); | |
} catch (EvaluationException e) { | |
e.printStackTrace(); | |
} | |
for (EObject childSemantic : candidatesSemanticChildren) | |
{ | |
if (modelAccessor.eInstanceOf(childSemantic, childNodeMapping.getDomainClass())) | |
createNodeAndItChildrenNodes(childSemantic, childNodeMapping, (DragAndDropTarget) parentNode); | |
} | |
} | |
} | |
/** | |
* Create one node in the current {@link DDiagram} | |
* @param mapping {@link AbstractNodeMapping} describing the node to create | |
* @param target {@link EObject} used to create the node | |
* @param parent a {@link DragAndDropTarget} element wherein the node will be created | |
*/ | |
private AbstractDNode createOneNode(EObject target, AbstractNodeMapping mapping, DragAndDropTarget parent){ | |
final AbstractDNodeCandidate abstractDNodeCandidate = new AbstractDNodeCandidate(mapping, target, parent); | |
return diagramSynchronizer.getElementSynchronizer().createNewNode(diagramMappingsManager, abstractDNodeCandidate, false); | |
} | |
} |