/* * Copyright 2003-2011 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.nodeEditor; import jetbrains.mps.nodeEditor.memory.MemoryAnalyzer; import jetbrains.mps.util.EqualUtil; import org.jetbrains.mps.openapi.model.SNode; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; // TODO: move to jetbrains.mps.nodeEditor.updater package, make package-local public class ReferencedNodeContext { // Both collections are used to identify "path" to the specified node via number of references. // To distinguish between editor cells created as a part of referenced node cell in-place // editor and cells created as a part of target node "main" editor or another in-place // referenced cell editor. // // Important information for update process here is: // - myNode (current context node) // - sourceNode (the node where chain of references was started) // - unique identities of each reference in this chain (roles/cellIDs/..) // // TODO: Simplify information persisted in this context object private List<String> myContextRoles = null; private List<SNode> myContextRefererNodes = null; private SNode myNode = null; private boolean myIsNodeAttribute = false; private ReferencedNodeContext(SNode node) { assert node != null; myNode = node; } private ReferencedNodeContext(SNode node, ReferencedNodeContext prototype) { this(node); if (prototype.myContextRoles != null) { myContextRoles = new ArrayList<String>(prototype.myContextRoles); } if (prototype.myContextRefererNodes != null) { myContextRefererNodes = new ArrayList<SNode>(prototype.myContextRefererNodes); } } public static ReferencedNodeContext createNodeContext(SNode node) { return new ReferencedNodeContext(node); } public static ReferencedNodeContext createNodeAttributeContext(SNode nodeAttribute) { ReferencedNodeContext result = new ReferencedNodeContext(nodeAttribute); result.myIsNodeAttribute = true; return result; } public ReferencedNodeContext sameContextButAnotherNode(SNode newNode) { return new ReferencedNodeContext(newNode, this); } public ReferencedNodeContext contextWithOneMoreReference(SNode node, SNode contextRefererNode, String contextRole) { ReferencedNodeContext result = new ReferencedNodeContext(node, this); result.addContextRole(contextRole); result.addContextRefererNode(contextRefererNode); return result; } public boolean hasRoles() { return myContextRoles != null; } public SNode getNode() { return myNode; } public boolean isNodeAttribute() { return myIsNodeAttribute; } private void addContextRole(String contextRole) { if (myContextRoles == null) { myContextRoles = new LinkedList<String>(); } myContextRoles.add(contextRole); } private void addContextRefererNode(SNode contextRefererNode) { if (myContextRefererNodes == null) { myContextRefererNodes = new LinkedList<SNode>(); } myContextRefererNodes.add(contextRefererNode); } public int hashCode() { return EqualUtil.hashCode(myNode) + 31 * (EqualUtil.hashCode(myContextRefererNodes) + 31 * EqualUtil.hashCode(myContextRoles)); } public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof ReferencedNodeContext) { ReferencedNodeContext o = (ReferencedNodeContext) obj; return EqualUtil.equals(myNode, o.myNode) && EqualUtil.equals(myContextRoles, o.myContextRoles) && EqualUtil.equals(myContextRefererNodes, o.myContextRefererNodes) && myIsNodeAttribute == o.myIsNodeAttribute; } else { return false; } } @Override public String toString() { String result = (myIsNodeAttribute ? "NodeAttribute: " : "Node: ") + myNode.toString(); if (myContextRoles != null) { for (String contextRole : myContextRoles) { result += ", context role: " + contextRole; } } if (myContextRefererNodes != null) { for (SNode contextReferer : myContextRefererNodes) { result += ", context referer: " + contextReferer.toString(); } } return result; } public void calculateSize(MemoryAnalyzer analyzer) { analyzer.appendObject(this); if (myContextRoles != null) { analyzer.appendCollection(myContextRoles); for (String contextRole : myContextRoles) { analyzer.appendObject(contextRole); } } if (myContextRefererNodes != null) { analyzer.appendCollection(myContextRefererNodes); } } }