/* * Copyright 2003-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.smodel.action; import jetbrains.mps.lang.smodel.generator.smodelAdapter.AttributeOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.IAttributeDescriptor; import jetbrains.mps.nodeEditor.SNodeEditorUtil; import jetbrains.mps.smodel.adapter.MetaAdapterByDeclaration; import jetbrains.mps.util.annotation.ToRemove; import org.jetbrains.mps.openapi.language.SAbstractConcept; import org.jetbrains.mps.openapi.language.SConcept; import org.jetbrains.mps.openapi.language.SContainmentLink; import org.jetbrains.mps.openapi.language.SInterfaceConcept; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.smodel.*; import org.jetbrains.mps.openapi.model.SNodeUtil; /** * Evgeny Gryaznov, 1/4/11 */ public class SNodeFactoryOperations { @Deprecated public static SConcept asInstanceConcept(SNode node) { if (node == null) { return null; } return MetaAdapterByDeclaration.getInstanceConcept(node); } @Deprecated public static SConcept asInstanceConcept(SAbstractConcept concept) { return MetaAdapterByDeclaration.asInstanceConcept(concept); } public static SNode createNewNode(SConcept concept, SNode prototypeNode) { if (concept == null) return null; return NodeFactoryManager.createNode(concept, prototypeNode, null, null); } public static SNode createNewNode(SModel model, SConcept concept, SNode prototypeNode) { SNode enclosingNode = null; if (prototypeNode != null) { enclosingNode = prototypeNode.getParent(); } return NodeFactoryManager.createNode(concept, prototypeNode, enclosingNode, model); } public static SNode createNewRootNode(SModel model, SConcept concept, SNode prototypeNode) { SNode newNode = NodeFactoryManager.createNode(concept, prototypeNode, null, model); model.addRootNode(newNode); return newNode; } public static SNode addNewChild(SNode node, SContainmentLink role, SConcept childConcept) { if (node != null) { SNode newChild = NodeFactoryManager.createNode(childConcept, null, node, node.getModel()); node.addChild(role, newChild); return newChild; } return null; } public static SNode addNewAttribute(SNode node, IAttributeDescriptor descriptor, SConcept childConcept) { if (node != null) { SNode newChild = NodeFactoryManager.createNode(childConcept, null, node, node.getModel()); AttributeOperations.addAttribute(node, descriptor, newChild); return newChild; } return null; } public static SNode setNewChild(SNode node, SContainmentLink role, SConcept childConcept) { if (node != null) { Iterable<? extends SNode> ch = node.getChildren(role); SNode prototypeNode = ch.iterator().hasNext() ? ch.iterator().next() : null; SNode newChild = NodeFactoryManager.createNode(childConcept, prototypeNode, node, node.getModel()); SNodeEditorUtil.setSingleChild(node, role, newChild); return newChild; } return null; } public static SNode setNewAttribute(SNode node, IAttributeDescriptor descriptor, SConcept childConcept) { if (node != null) { SNode prototypeNode = AttributeOperations.getAttribute(node, descriptor); SNode newChild = NodeFactoryManager.createNode(childConcept, prototypeNode, node, node.getModel()); AttributeOperations.setAttribute(node, descriptor, newChild); return newChild; } return null; } public static SNode replaceWithNewChild(SNode oldChild, SConcept concept) { assert oldChild != null : "can't replace node. node is NULL"; SNode oldChildParent = oldChild.getParent(); if (oldChildParent == null && !(oldChild.getModel() != null && oldChild.getParent() == null)) { return null; } SModel model = oldChild.getModel(); SNode newChild = NodeFactoryManager.createNode(concept, oldChild, oldChildParent, model); if (newChild == null) return null; if (oldChildParent == null) { model.addRootNode(newChild); model.removeRootNode(oldChild); } else { SNodeUtil.replaceWithAnother(oldChild, newChild); } copyAllAttributes(oldChild, newChild); return newChild; } private static void copyAllAttributes(SNode oldChild, SNode newChild) { for (SNode attribute : AttributeOperations.getAllAttributes(oldChild)) { // todo: should we create check like this? // no such property in new child : don't copy the attribute // LOG.error("couldn't copy attribute " + attribute.getOwner().getName() + " for property '" + propertyName + "' : so such property in concept " + newChild.getContainingConcept().getName(), newChild); // no such link in new child : don't copy the attribute // LOG.error("couldn't copy attribute " + attribute.getOwner().getName() + " for link '" + linkRole + "' : so such link in concept " + newChild.getContainingConcept().getName(), newChild); SNode newAttribute = CopyUtil.copy(attribute); newChild.addChild(attribute.getContainmentLink(), newAttribute); } } public static SNode insertNewNextSiblingChild(SNode node, SConcept concept) { if (node == null || node.getParent() == null) return null; SNode parent = node.getParent(); SNode newChild = NodeFactoryManager.createNode(concept, null, parent, node.getModel()); if (newChild == null) return null; SContainmentLink role = node.getContainmentLink(); parent.insertChildAfter(role, newChild, node); return newChild; } public static SNode insertNewPrevSiblingChild(SNode node, SConcept concept) { if (node == null) return null; SNode parent = node.getParent(); if (parent == null) return null; SNode newChild = NodeFactoryManager.createNode(concept, null, parent, node.getModel()); if (newChild == null) return null; SContainmentLink role = node.getContainmentLink(); parent.insertChildBefore(role, newChild, node); return newChild; } }