001: /*
002: * $RCSfile: NodeComponent.java,v $
003: *
004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.7 $
028: * $Date: 2008/02/28 20:17:26 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.Hashtable;
035:
036: /**
037: * NodeComponent is a common superclass for all scene graph node
038: * component objects such as: Geometry, Appearance, Material, Texture, etc.
039: *
040: * <p>
041: * For more information, see the
042: * <a href="doc-files/intro.html">Introduction to the Java 3D API</a>.
043: */
044: public abstract class NodeComponent extends SceneGraphObject {
045:
046: // This is use for cloneTree only, set to false after the operation
047: boolean forceDuplicate = false;
048:
049: /**
050: * Constructs a NodeComponent object with default parameters.
051: * The default values are as follows:
052: * <ul>
053: * duplicate on clone tree : false<br>
054: * </ul>
055: */
056: public NodeComponent() {
057: }
058:
059: /**
060: * Sets this node's duplicateOnCloneTree value. The
061: * <i>duplicateOnCloneTree</i> value is used to determine if NodeComponent
062: * objects are to be duplicated or referenced during a
063: * <code>cloneTree</code> operation. A value of <code>true</code> means
064: * that this NodeComponent object should be duplicated, while a value
065: * of <code>false</code> indicates that this NodeComponent object's
066: * reference will be copied into the newly cloned object. This value
067: * can be overriden via the <code>forceDuplicate</code> parameter of
068: * the <code>cloneTree</code> method.
069: * @param duplicate the value to set.
070: * @see Node#cloneTree
071: */
072: public void setDuplicateOnCloneTree(boolean duplicate) {
073: ((NodeComponentRetained) retained)
074: .setDuplicateOnCloneTree(duplicate);
075: }
076:
077: /**
078: * Returns this node's duplicateOnCloneTree value. The
079: * <i>duplicateOnCloneTree</i> value is used to determine if NodeComponent
080: * objects are to be duplicated or referenced during a
081: * <code>cloneTree</code> operation. A value of <code>true</code> means
082: * that this NodeComponent object should be duplicated, while a value
083: * of <code>false</code> indicates that this NodeComponent object's
084: * reference will be copied into the newly cloned object. This value
085: * can be overriden via the <code>forceDuplicate</code> parameter of
086: * the <code>cloneTree</code> method.
087: * @return the value of this node's duplicateOnCloneTree
088: * @see Node#cloneTree
089: */
090: public boolean getDuplicateOnCloneTree() {
091: return ((NodeComponentRetained) retained)
092: .getDuplicateOnCloneTree();
093: }
094:
095: /**
096: * @deprecated As of Java 3D version 1.2, replaced by
097: * <code>cloneNodeComponent(boolean forceDuplicate)</code>
098: */
099: public NodeComponent cloneNodeComponent() {
100: throw new RuntimeException(J3dI18N.getString("NodeComponent0"));
101: }
102:
103: /**
104: * NOTE: Applications should <i>not</i> call this method directly.
105: * It should only be called by the cloneNode method.
106: *
107: * @deprecated As of Java 3D version 1.2, replaced by
108: * <code>duplicateNodeComponent(NodeComponent
109: * originalNodeComponent, boolean forceDuplicate)</code>
110: */
111: public void duplicateNodeComponent(
112: NodeComponent originalNodeComponent) {
113: duplicateAttributes(originalNodeComponent,
114: originalNodeComponent.forceDuplicate);
115: }
116:
117: /**
118: * Copies all node information from <code>originalNodeComponent</code> into
119: * the current node component. This method is called from subclass of
120: * <code>duplicateNodeComponent</code> method which is, in turn, called by the
121: * <code>cloneNodeComponent</code> method.
122: *
123: * For any <i>NodeComponent</i> objects
124: * contained by the object being duplicated, each <i>NodeComponent</i>
125: * object's <code>duplicateOnCloneTree</code> value is used to determine
126: * whether the <i>NodeComponent<i> should be duplicated in the new node
127: * or if just a reference to the current node should be placed in the
128: * new node. This flag can be overridden by setting the
129: * <code>forceDuplicate</code> parameter in the <code>cloneTree</code>
130: * method to <code>true</code>.
131: *
132: * @param originalNodeComponent the original node component to duplicate.
133: */
134: final void checkDuplicateNodeComponent(
135: NodeComponent originalNodeComponent) {
136:
137: if (originalNodeComponent.nodeHashtable != null) {
138: duplicateAttributes(originalNodeComponent,
139: originalNodeComponent.forceDuplicate);
140: } else {
141: // user call cloneNodeComponent() or duplicateNodeComponent()
142: // directly instead of via cloneTree()
143: originalNodeComponent.nodeHashtable = new Hashtable();
144: duplicateAttributes(originalNodeComponent,
145: originalNodeComponent.forceDuplicate);
146: originalNodeComponent.nodeHashtable = null;
147: }
148: }
149:
150: /**
151: * Copies all node information from <code>originalNodeComponent</code>
152: * into the current node. This method is called from the
153: * <code>cloneNodeComponent</code> method which is, in turn, called
154: * by the <code>cloneNode</code> method.
155: * <br>
156: * NOTE: Applications should <i>not</i> call this method directly.
157: * It should only be called by the cloneNode method.
158: *
159: * @param originalNodeComponent the node to duplicate.
160: * @param forceDuplicate when set to <code>true</code>, causes the
161: * <code>duplicateOnCloneTree</code> flag to be ignored. When
162: * <code>false</code>, the value of each node's
163: * <code>duplicateOnCloneTree</code> variable determines whether
164: * NodeComponent data is duplicated or copied.
165: *
166: * @exception RestrictedAccessException if forceDuplicate is set and
167: * this object is part of a compiled scenegraph
168: *
169: * @see NodeComponent#cloneNodeComponent
170: * @see Node#cloneNode
171: * @see Node#cloneTree
172: *
173: * @since Java 3D 1.2
174: */
175: public void duplicateNodeComponent(
176: NodeComponent originalNodeComponent, boolean forceDuplicate) {
177: originalNodeComponent.forceDuplicate = forceDuplicate;
178: try {
179: duplicateNodeComponent(originalNodeComponent);
180: } catch (RuntimeException e) {
181: originalNodeComponent.forceDuplicate = false;
182: throw e;
183: }
184: originalNodeComponent.forceDuplicate = false;
185: }
186:
187: /**
188: * Used to create a new instance of a NodeComponent object. This
189: * routine is called by <code>cloneNode</code> to duplicate the
190: * current node. <br>
191: *
192: * <code>cloneNodeComponent</code> should be overridden by any user
193: * subclassed <i>NodeComponent</i> objects. All subclasses must have their
194: * <code>cloneNodeComponent</code>
195: * method consist of the following lines:
196: * <P><blockquote><pre>
197: * public NodeComponent cloneNodeComponent(boolean forceDuplicate) {
198: * UserNodeComponent unc = new UserNodeComponent();
199: * unc.duplicateNodeComponent(this, forceDuplicate);
200: * return unc;
201: * }
202: * </pre></blockquote>
203: *
204: * @param forceDuplicate when set to <code>true</code>, causes the
205: * <code>duplicateOnCloneTree</code> flag to be ignored. When
206: * <code>false</code>, the value of each node's
207: * <code>duplicateOnCloneTree</code> variable determines whether
208: * NodeComponent data is duplicated or copied.
209: *
210: * @exception RestrictedAccessException if forceDuplicate is set and
211: * this object is part of a compiled scenegraph
212: *
213: * @see NodeComponent#duplicateNodeComponent
214: * @see Node#cloneNode
215: * @see Node#cloneTree
216: *
217: * @since Java 3D 1.2
218: */
219: public NodeComponent cloneNodeComponent(boolean forceDuplicate) {
220: // For backward compatibility !
221: //
222: // If user did not overwrite this procedure, it will fall back
223: // to call cloneNodeComponent()
224: // So for core API,
225: // don't implement cloneNodeComponent(boolean forceDuplicate)
226: // otherwise this prcedure will not call and the user
227: // cloneNodeComponent() will not invoke.
228: NodeComponent nc;
229: this .forceDuplicate = forceDuplicate;
230: try {
231: nc = cloneNodeComponent();
232: } catch (RuntimeException e) {
233: this .forceDuplicate = false;
234: throw e;
235: }
236: this .forceDuplicate = false;
237: return nc;
238: }
239:
240: /**
241: * Copies all NodeComponent information from
242: * <code>originalNode</code> into
243: * the current node. This method is called from the
244: * <code>cloneNode</code> method which is, in turn, called by the
245: * <code>cloneTree</code> method.<P>
246: *
247: * @param originalNode the original node to duplicate.
248: * @param forceDuplicate when set to <code>true</code>, causes the
249: * <code>duplicateOnCloneTree</code> flag to be ignored. When
250: * <code>false</code>, the value of each node's
251: * <code>duplicateOnCloneTree</code> variable determines whether
252: * NodeComponent data is duplicated or copied.
253: *
254: * @see Group#cloneNode
255: * @see Node#duplicateNode
256: * @see Node#cloneTree
257: * @see NodeComponent#setDuplicateOnCloneTree
258: */
259: void duplicateAttributes(NodeComponent originalNode,
260: boolean forceDuplicate) {
261:
262: if (forceDuplicate && originalNode.isCompiled()) {
263: throw new RestrictedAccessException(J3dI18N
264: .getString("NodeComponent1"));
265: }
266:
267: super .duplicateSceneGraphObject(originalNode);
268: setDuplicateOnCloneTree(originalNode.getDuplicateOnCloneTree());
269: }
270:
271: /**
272: * Creates the retained mode NodeComponentRetained object that this
273: * NodeComponent object will point to.
274: */
275: void createRetained() {
276: this .retained = new NodeComponentRetained();
277: this .retained.setSource(this );
278: }
279:
280: /**
281: * This function is called from getNodeComponent() to see if any of
282: * the sub-NodeComponents duplicateOnCloneTree flag is true.
283: * If it is the case, current NodeComponent needs to
284: * duplicate also even though current duplicateOnCloneTree flag is false.
285: * This should be overwrite by NodeComponent which contains sub-NodeComponent.
286: */
287: boolean duplicateChild() {
288: return getDuplicateOnCloneTree();
289: }
290:
291: /*
292: * @exception IllegalSharingException if this NodeComponent is live and
293: * the specified image is being used by a Canvas3D as an off-screen buffer.
294: *
295: * @exception IllegalSharingException if this NodeComponent is
296: * being used by an immediate mode context and
297: * the specified image is being used by a Canvas3D as an off-screen buffer.
298: */
299: void validateImageIllegalSharing(ImageComponent image) {
300: // Do illegal sharing check
301: if (image != null) {
302: ImageComponentRetained imageRetained = (ImageComponentRetained) image.retained;
303: NodeComponentRetained ncRetained = (NodeComponentRetained) this .retained;
304: if (imageRetained.getUsedByOffScreen()) {
305: if (isLive()) {
306: throw new IllegalSharingException(J3dI18N
307: .getString("NodeComponent2"));
308: }
309: if (ncRetained.getInImmCtx()) {
310: throw new IllegalSharingException(J3dI18N
311: .getString("NodeComponent3"));
312: }
313: }
314: }
315: }
316:
317: }
|