1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph;
14 import java.beans.PropertyChangeListener;
16 import org.simantics.scenegraph.utils.NodeUtil;
21 public abstract class Node implements INode {
23 private static final long serialVersionUID = -5540999051056414851L;
25 public transient static long IDCOUNTER = 1;
27 protected transient ParentNode<?> parent = null;
28 protected transient Location location = Location.LOCAL;
30 // This is for internal server communications. Do not touch.
31 // Support for only one listener should be enough, thus we don't need PropertyChangeSupport
32 protected transient PropertyChangeListener propertyChangeListener = null;
34 protected Long id = IDCOUNTER++;
37 * @see org.simantics.scenegraph.INode#getId()
44 * @see org.simantics.scenegraph.INode#getParent()
46 public ParentNode<?> getParent() {
51 * @see org.simantics.scenegraph.INode#setParent(org.simantics.scenegraph.ParentNode)
53 public void setParent(ParentNode<?> parent) {
58 * The default implementation of {@link #getRootNode()} always asks for the
59 * root node from the parent. Scene graph leaf nodes are never considered to
60 * be real scene graph root nodes, although they are can be thought of as
61 * such when they are not attached to any scene graph. This implementation
62 * prevents the need to have a separate rootNodeCache field in all nodes.
64 * @see org.simantics.scenegraph.INode#getRootNode()
66 public ParentNode<?> getRootNode() {
67 return parent != null ? parent.getRootNode() : null;
70 public void remove() {
72 parent.asyncRemoveNode(this);
77 * @see org.simantics.scenegraph.INode#init()
82 public void attach() {
87 * @see org.simantics.scenegraph.INode#cleanup()
89 public void cleanup() {
94 * @see org.simantics.scenegraph.INode#delete()
96 public void delete() {
97 // 1. Remove this node from parent
98 parent.asyncRemoveNode(this);
102 * Remove any ID<->Node mapping this node might have in the scene graph's
103 * {@link LookupService}.
105 protected void retractMapping() {
106 NodeUtil.tryUnmap(this);
109 public <TC> TC appendParent(String id, Class<TC> nc) {
110 assert(parent != null);
112 // 0. Find identifier from parent
113 String identifier = null;
114 for(String s : parent.children.keySet()) { // FIXME: should not be this complicated
115 if(parent.children.get(s) == this) { // Find this from parent child list
120 if (identifier == null)
121 identifier = "" + this.id;
123 // 1. Remove this node from original parent
124 parent.unlinkChild(this);
126 // 2. Add new node under parent
127 TC instance = parent.addNode(id, nc);
129 // 3. Add this node under new parent
130 ((ParentNode<?>)instance).appendChild(identifier, this);
136 public String toString() {
137 return getSimpleClassName() + " (" + id + ")";
140 public String getSimpleClassName() {
141 return getSimpleClassName(getClass());
144 public static String getSimpleClassName(Class<?> clazz) {
145 String name = clazz.getSimpleName();
146 int pos = name.indexOf("$$");
148 name = name.substring(0, pos);
153 * Associates this node with the specified ID in the {@link ILookupService}
154 * that must be offered by the scene graph root node. After this
155 * association, one can use {@link NodeUtil#lookup(INode, String)} to lookup
156 * this node from the scene graph by its ID.
159 * @throws UnsupportedOperationException if no ILookupService is available
163 public void setLookupId(String id) {
164 NodeUtil.getLookupService(this).map(id, this);
168 * A shorthand utility for {@link NodeUtil#lookup(INode, String, Class)}.
174 protected <T extends INode> T lookupNode(String id, Class<T> clazz) {
175 return NodeUtil.lookup(this, id, clazz);
179 * A shorthand utility for {@link NodeUtil#lookupId(INode)}).
184 protected String lookupId(INode node) {
185 return NodeUtil.lookupId(node);