Source Code Cross Referenced for SymbolTable.java in  » 6.0-JDK-Modules » java-3d » com » sun » j3d » utils » scenegraph » io » retained » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » com.sun.j3d.utils.scenegraph.io.retained 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: SymbolTable.java,v $
003:         *
004:         * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions
008:         * are met:
009:         *
010:         * - Redistribution of source code must retain the above copyright
011:         *   notice, this list of conditions and the following disclaimer.
012:         *
013:         * - Redistribution in binary form must reproduce the above copyright
014:         *   notice, this list of conditions and the following disclaimer in
015:         *   the documentation and/or other materials provided with the
016:         *   distribution.
017:         *
018:         * Neither the name of Sun Microsystems, Inc. or the names of
019:         * contributors may be used to endorse or promote products derived
020:         * from this software without specific prior written permission.
021:         *
022:         * This software is provided "AS IS," without a warranty of any
023:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026:         * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034:         * POSSIBILITY OF SUCH DAMAGES.
035:         *
036:         * You acknowledge that this software is not designed, licensed or
037:         * intended for use in the design, construction, operation or
038:         * maintenance of any nuclear facility.
039:         *
040:         * $Revision: 1.5 $
041:         * $Date: 2007/02/09 17:20:29 $
042:         * $State: Exp $
043:         */
044:
045:        package com.sun.j3d.utils.scenegraph.io.retained;
046:
047:        import java.io.IOException;
048:        import java.io.DataOutput;
049:        import java.io.DataInput;
050:        import java.util.HashMap;
051:        import java.util.ArrayList;
052:        import java.util.ListIterator;
053:        import java.util.LinkedList;
054:        import java.util.Iterator;
055:        import java.util.HashSet;
056:        import java.util.Collection;
057:        import java.util.Stack;
058:
059:        import javax.media.j3d.SceneGraphObject;
060:
061:        import com.sun.j3d.utils.scenegraph.io.state.javax.media.j3d.SceneGraphObjectState;
062:        import com.sun.j3d.utils.scenegraph.io.state.javax.media.j3d.NullSceneGraphObjectState;
063:        import com.sun.j3d.utils.scenegraph.io.state.javax.media.j3d.NodeComponentState;
064:        import com.sun.j3d.utils.scenegraph.io.NamedObjectException;
065:        import com.sun.j3d.utils.scenegraph.io.ObjectNotLoadedException;
066:        import com.sun.j3d.utils.scenegraph.io.SceneGraphObjectReferenceControl;
067:
068:        /**
069:         * SymbolTable class for SceneGraph I/O.
070:         */
071:        public class SymbolTable extends java.lang.Object implements 
072:                SceneGraphObjectReferenceControl {
073:
074:            private int nodeID = 1; // ID of zero represents null
075:            private HashMap j3dNodeIndex; // Index by SceneGraphObject
076:            private ArrayList nodeIDIndex; // Index by NodeID of Nodes
077:            private HashMap danglingReferences; // Java3D objects without a current State object
078:            private Stack unsavedNodeComponentsStack;
079:            private LinkedList sharedNodes; // Nodes and NodeComponents referenced more than once
080:            private HashMap namedObjects;
081:            private ArrayList branchGraphs; // Root of each branch graph
082:            private ArrayList branchGraphDependencies; // Dependencies between the branchgraphs
083:            // For a graph branchGraphDep[graph] will contain a set of all nodes (in other graphs) on which the graph is dependent
084:
085:            private Controller control;
086:            private int currentBranchGraphID = -1; // ID's start at 0, -1 is null, -2 is during read, -3 is dangling
087:            private int nextBranchGraphID = 0;
088:
089:            /** Creates new SymbolTable */
090:            public SymbolTable(Controller control) {
091:                this .control = control;
092:                j3dNodeIndex = new HashMap();
093:                danglingReferences = new HashMap();
094:                nodeIDIndex = new ArrayList();
095:                nodeIDIndex.add(null); // Element zero is null 
096:                sharedNodes = new LinkedList();
097:                namedObjects = new HashMap();
098:                branchGraphs = new ArrayList();
099:                branchGraphDependencies = new ArrayList();
100:                unsavedNodeComponentsStack = new Stack();
101:            }
102:
103:            /**
104:             * At this stage their should be no dangling references
105:             * 
106:             */
107:            private void checkforDanglingReferences() {
108:                ListIterator list = sharedNodes.listIterator();
109:
110:                while (list.hasNext()) {
111:                    SymbolTableData data = (SymbolTableData) list.next();
112:                    if (data.branchGraphID == -3) {
113:                        System.err
114:                                .println("Warning : node "
115:                                        + data.j3dNode
116:                                        + " is referenced but is not attached to a BranchGraph");
117:                        System.err
118:                                .println("Setting reference to null. This scene may not look correct when loaded");
119:                    }
120:                }
121:            }
122:
123:            /** 
124:             * Remove dependencies on objects which are not attached to a
125:             * branchgraph
126:             */
127:            private void removeNullDependencies(HashSet set) {
128:                Iterator it = set.iterator();
129:                while (it.hasNext()) {
130:                    SymbolTableData symbol = (SymbolTableData) it.next();
131:                    if (symbol.branchGraphID == -3)
132:                        it.remove();
133:                }
134:            }
135:
136:            public void writeTable(DataOutput out) throws IOException {
137:
138:                // At this stage their should be no dangling references
139:                checkforDanglingReferences();
140:
141:                ListIterator list = sharedNodes.listIterator();
142:                out.writeInt(sharedNodes.size());
143:                out.writeInt(nodeID);
144:                while (list.hasNext()) {
145:                    SymbolTableData data = (SymbolTableData) list.next();
146:                    data.writeObject(out);
147:                }
148:
149:                // Write Named objects
150:                String[] names = getNames();
151:                out.writeInt(names.length);
152:                for (int i = 0; i < names.length; i++) {
153:                    out.writeUTF(names[i]);
154:                    SceneGraphObject node = (SceneGraphObject) namedObjects
155:                            .get(names[i]);
156:                    SymbolTableData symbol = getSymbol(node);
157:                    if (symbol != null)
158:                        out.writeInt(symbol.nodeID);
159:                    else
160:                        out.writeInt(0); // Null
161:                }
162:
163:                // Write BranchGraph roots
164:                out.writeInt(branchGraphs.size());
165:                for (int i = 0; i < branchGraphs.size(); i++)
166:                    ((SymbolTableData) branchGraphs.get(i)).writeObject(out);
167:
168:                for (int i = 0; i < branchGraphDependencies.size(); i++) {
169:                    HashSet set = (HashSet) branchGraphDependencies.get(i);
170:                    if (set == null) {
171:                        out.writeInt(0);
172:                    } else {
173:                        removeNullDependencies(set);
174:                        out.writeInt(set.size());
175:                        Iterator it = set.iterator();
176:                        while (it.hasNext()) {
177:                            SymbolTableData symbol = (SymbolTableData) it
178:                                    .next();
179:                            out.writeInt(symbol.nodeID);
180:                        }
181:                    }
182:                }
183:            }
184:
185:            /**
186:             * Read and store the entire symbol table
187:             *
188:             * @param streamRead - true if reading from a Stream in which case only the
189:             *                       branchGraphs and named objects are read.
190:             */
191:            public void readTable(java.io.DataInput in, boolean streamRead)
192:                    throws IOException {
193:                int size = in.readInt();
194:                nodeID = in.readInt();
195:                nodeIDIndexEnsureCapacity(nodeID);
196:                for (int i = 0; i < size; i++) {
197:                    SymbolTableData symbol = new SymbolTableData(0, null, null,
198:                            -1);
199:                    symbol.readObject(in);
200:
201:                    // If we are loading from a stream then the NodeComponents have
202:                    // already been loaded and their symbols created. Therefore 
203:                    // the symbols loaded here are discarded.
204:                    if (!streamRead) {
205:                        sharedNodes.add(symbol);
206:                        nodeIDIndex.set(symbol.nodeID, symbol);
207:                    }
208:                }
209:
210:                // Read Named objects
211:                size = in.readInt();
212:                for (int j = 0; j < size; j++) {
213:                    String name = in.readUTF();
214:                    int id = in.readInt();
215:                    namedObjects.put(name, new Integer(id));
216:                }
217:
218:                size = in.readInt();
219:                //System.out.println("Symbol table BranchGraph size "+size );
220:                for (int i = 0; i < size; i++)
221:                    branchGraphs.add(null);
222:
223:                // Read each branchgraph symbol and check that the symbol is not
224:                // already in the symbol table.
225:                for (int j = 0; j < size; j++) {
226:                    SymbolTableData tmp = new SymbolTableData(0, null, null, -1);
227:                    tmp.readObject(in);
228:
229:                    SymbolTableData symbol = getSymbol(tmp.nodeID);
230:
231:                    if (symbol == null) {
232:                        symbol = tmp;
233:                        if (symbol.referenceCount > 1)
234:                            sharedNodes.add(symbol);
235:                        nodeIDIndex.set(symbol.nodeID, symbol);
236:                    }
237:
238:                    branchGraphs.set(j, symbol);
239:                }
240:
241:                for (int i = 0; i < size; i++) {
242:                    int setSize = in.readInt();
243:
244:                    if (setSize == 0)
245:                        branchGraphDependencies.add(null);
246:                    else {
247:                        HashSet set = new HashSet();
248:                        branchGraphDependencies.add(set);
249:                        for (int j = 0; j < setSize; j++) {
250:                            set.add(getSymbol(in.readInt()));
251:                        }
252:                    }
253:                }
254:            }
255:
256:            /**
257:             * Mark the node referenced by this Symbol as a branch graph root
258:             *
259:             *The filePointer is the position of the BranchGraph in the file, this
260:             *is not the same as the BranchGroups position due to the extra  data stored
261:             *for a graph.
262:             */
263:            public void setBranchGraphRoot(SymbolTableData symbol,
264:                    long filePointer) {
265:                if (symbol.branchGraphID < 0) {
266:                    symbol.branchGraphID = nextBranchGraphID++;
267:                }
268:
269:                currentBranchGraphID = symbol.branchGraphID;
270:                for (int i = branchGraphs.size(); i < currentBranchGraphID + 1; i++) {
271:                    branchGraphs.add(null);
272:                    branchGraphDependencies.add(null);
273:                }
274:
275:                branchGraphs.set(currentBranchGraphID, symbol);
276:                symbol.branchGraphFilePointer = filePointer;
277:            }
278:
279:            public SymbolTableData getBranchGraphRoot(int graphID) {
280:                //System.out.println("BranchGraph root "+graphID+"  "+(SymbolTableData)branchGraphs.get(graphID) );
281:                return (SymbolTableData) branchGraphs.get(graphID);
282:            }
283:
284:            /**
285:             * Set the branchGraphID in the symbol to the current branch graph ID
286:             */
287:            public void setBranchGraphID(SymbolTableData symbol) {
288:                symbol.branchGraphID = currentBranchGraphID;
289:            }
290:
291:            /**
292:             * Return an array of each BranchGraph on which graphID is dependent for
293:             * closure of the graph
294:             *
295:             * Only Nodes (not node components) cause dependencies
296:             *
297:             * If there are no dependencies int[0] is returned
298:             */
299:            public int[] getBranchGraphDependencies(int graphID) {
300:                HashSet set = (HashSet) branchGraphDependencies.get(graphID);
301:                if (set == null)
302:                    return new int[0];
303:
304:                int[] ret = new int[set.size()];
305:                Iterator it = set.iterator();
306:                int i = 0;
307:                while (it.hasNext())
308:                    ret[i++] = ((SymbolTableData) it.next()).branchGraphID;
309:
310:                return ret;
311:            }
312:
313:            /**
314:             * Return true if the graph is dependent on nodes in
315:             * other graphs
316:             *
317:             * Only Nodes (not node components) cause dependencies
318:             *
319:             */
320:            public boolean branchGraphHasDependencies(int graphID) {
321:                HashSet set = (HashSet) branchGraphDependencies.get(graphID);
322:
323:                if (set == null || set.size() == 0)
324:                    return false;
325:                else
326:                    return true;
327:            }
328:
329:            public int getBranchGraphCount() {
330:                return branchGraphs.size();
331:            }
332:
333:            public long getBranchGraphFilePosition(int graphID) {
334:                SymbolTableData symbol = (SymbolTableData) branchGraphs
335:                        .get(graphID);
336:                return symbol.branchGraphFilePointer;
337:            }
338:
339:            /**
340:             * Create a new symbol and provide a new nodeID
341:             * This is used during the save process
342:             */
343:            public SymbolTableData createSymbol(SceneGraphObject node) {
344:
345:                // TODO : Remove this get, it's here to provide debug consistancy check
346:                SymbolTableData data = (SymbolTableData) j3dNodeIndex.get(node);
347:
348:                SymbolTableData dangling = (SymbolTableData) danglingReferences
349:                        .get(node);
350:
351:                //System.out.println("Checking for dangling "+dangling+"  "+node);
352:
353:                if (dangling != null) {
354:                    data = dangling;
355:                    data.branchGraphID = currentBranchGraphID;
356:                    danglingReferences.remove(dangling);
357:                    //System.out.println("Updating dangling ref count");      // TODO - remove
358:                } else if (data == null) {
359:                    data = new SymbolTableData(nodeID++, node, null,
360:                            currentBranchGraphID);
361:                    j3dNodeIndex.put(node, data);
362:                    nodeIDIndex.add(data);
363:                } else if (data.j3dNode instanceof  javax.media.j3d.Node) {
364:                    throw new RuntimeException(
365:                            "Object already in Symbol table " + node);
366:                }
367:
368:                return data;
369:            }
370:
371:            /**
372:             * Create a new symbol using the specified nodeID
373:             * This is used during the load process.
374:             */
375:            public SymbolTableData createSymbol(SceneGraphObjectState state,
376:                    SceneGraphObject node, int nodeID) {
377:
378:                // TODO : Remove this get, it's here to provide debug consistancy check
379:                SymbolTableData data = (SymbolTableData) j3dNodeIndex.get(node);
380:
381:                if (data == null) {
382:                    nodeIDIndexEnsureCapacity(nodeID);
383:                    data = (SymbolTableData) nodeIDIndex.get(nodeID);
384:                    if (data == null) {
385:                        data = new SymbolTableData(nodeID, node, state, -2);
386:                        j3dNodeIndex.put(node, data);
387:                        nodeIDIndex.set(data.getNodeID(), data);
388:                    } else if (data.getJ3dNode() == null) { // Only use state and node if
389:                        data.j3dNode = node; // this is the first instantiation
390:                        data.nodeState = state; // of the node
391:                        j3dNodeIndex.put(node, data);
392:                    }
393:                } else
394:                    throw new SGIORuntimeException(
395:                            "Object already in Symbol table ");
396:
397:                return data;
398:            }
399:
400:            private void nodeIDIndexEnsureCapacity(int size) {
401:                nodeIDIndex.ensureCapacity(size);
402:                int adjust = size - nodeIDIndex.size();
403:                for (int i = 0; i <= adjust; i++)
404:                    nodeIDIndex.add(null);
405:            }
406:
407:            /**
408:             * Create or return the SymbolTableData for a node which does not
409:             * necessary have a State object yet
410:             *
411:             */
412:            private SymbolTableData createDanglingSymbol(SceneGraphObject node) {
413:                SymbolTableData data = (SymbolTableData) j3dNodeIndex.get(node);
414:
415:                if (data == null) {
416:                    data = new SymbolTableData(nodeID++, node, null, -3);
417:                    j3dNodeIndex.put(node, data);
418:                    nodeIDIndex.add(data);
419:                    danglingReferences.put(node, data);
420:                } else if (data.nodeState == null) {
421:                    if (data.referenceCount == 1)
422:                        sharedNodes.add(data);
423:                    data.referenceCount++;
424:                } else
425:                    throw new SGIORuntimeException(
426:                            "Object already in Symbol table ");
427:
428:                return data;
429:            }
430:
431:            private SymbolTableData createNodeComponentSymbol(
432:                    SceneGraphObject node) {
433:                SymbolTableData symbol = new SymbolTableData(nodeID++, node,
434:                        null, currentBranchGraphID);
435:                symbol.isNodeComponent = true;
436:                j3dNodeIndex.put(node, symbol);
437:                nodeIDIndex.add(symbol);
438:
439:                ((LinkedList) unsavedNodeComponentsStack.peek()).add(symbol);
440:
441:                control.createState(symbol);
442:
443:                return symbol;
444:            }
445:
446:            public int getUnsavedNodeComponentsSize() {
447:                return ((LinkedList) unsavedNodeComponentsStack.peek()).size();
448:            }
449:
450:            public ListIterator getUnsavedNodeComponents() {
451:                return ((LinkedList) unsavedNodeComponentsStack.peek())
452:                        .listIterator(0);
453:            }
454:
455:            public void startUnsavedNodeComponentFrame() {
456:                unsavedNodeComponentsStack.push(new LinkedList());
457:            }
458:
459:            public void endUnsavedNodeComponentFrame() {
460:                unsavedNodeComponentsStack.pop();
461:                confirmInterGraphDependency();
462:            }
463:
464:            /**
465:             * Check for and remove any inter graph dependency
466:             * labels that have been resolved to the current graph
467:             */
468:            private void confirmInterGraphDependency() {
469:                HashSet set = (HashSet) branchGraphDependencies
470:                        .get(currentBranchGraphID);
471:                if (set == null)
472:                    return;
473:
474:                Iterator it = set.iterator();
475:                while (it.hasNext()) {
476:                    SymbolTableData symbol = (SymbolTableData) it.next();
477:                    if (symbol.branchGraphID == currentBranchGraphID)
478:                        it.remove();
479:                }
480:
481:            }
482:
483:            /** 
484:             * Add a dependency to the current branchgraph on <code>symbol</code>
485:             *
486:             * Only nodes (not nodeComponents) affect intergraph dependencies
487:             */
488:            private void addInterGraphDependency(SymbolTableData symbol) {
489:                HashSet set = (HashSet) branchGraphDependencies
490:                        .get(currentBranchGraphID);
491:                if (set == null) {
492:                    set = new HashSet();
493:                    branchGraphDependencies.set(currentBranchGraphID, set);
494:                }
495:
496:                set.add(symbol);
497:            }
498:
499:            /**
500:             * Update the reference count for the node component.
501:             *
502:             * Called during NodeComponentState.addSubReference()
503:             */
504:            public void incNodeComponentRefCount(int nodeID) {
505:                if (nodeID == 0)
506:                    return;
507:
508:                SymbolTableData symbol = getSymbol(nodeID);
509:
510:                ((NodeComponentState) symbol.nodeState).addSubReference();
511:
512:                if (symbol.referenceCount == 1)
513:                    sharedNodes.add(symbol);
514:                symbol.referenceCount++;
515:            }
516:
517:            /**
518:             * Add a refernce to the specified node
519:             * Also returns the nodes id
520:             */
521:            public int addReference(SceneGraphObject node) {
522:                if (node == null)
523:                    return 0;
524:
525:                SymbolTableData symbol = getSymbol(node);
526:
527:                if (symbol == null) {
528:                    if (node instanceof  javax.media.j3d.Node) {
529:                        symbol = createDanglingSymbol(node);
530:                        if (symbol.branchGraphID != currentBranchGraphID) {
531:                            //System.out.println("------------- Adding Reference "+symbol.nodeID+" "+node );  // TODO - remove
532:                            addInterGraphDependency(symbol);
533:                            sharedNodes.add(symbol);
534:                        }
535:                    } else {
536:                        symbol = createNodeComponentSymbol(node);
537:                    }
538:                    return symbol.nodeID;
539:                } else {
540:                    return addReference(symbol);
541:                }
542:            }
543:
544:            /**
545:             * Add a refernce to the specified node
546:             * Also returns the nodes id
547:             */
548:            public int addReference(SymbolTableData symbol) {
549:
550:                if (symbol != null) {
551:                    if (symbol.referenceCount == 1)
552:                        sharedNodes.add(symbol);
553:                    symbol.referenceCount++;
554:
555:                    if (symbol.j3dNode instanceof  javax.media.j3d.NodeComponent
556:                            && symbol.referenceCount > 1) {
557:                        ((NodeComponentState) symbol.nodeState)
558:                                .addSubReference();
559:                    }
560:
561:                    if (symbol.branchGraphID != currentBranchGraphID
562:                            && symbol.j3dNode instanceof  javax.media.j3d.Node) {
563:                        // System.out.println("------------- Adding Reference "+symbol.nodeID+" "+symbol.j3dNode );    // TODO - remove
564:                        addInterGraphDependency(symbol);
565:                    }
566:                } else {
567:                    throw new SGIORuntimeException("Null Symbol");
568:                }
569:
570:                return symbol.nodeID;
571:            }
572:
573:            /**
574:             * Add a refernce to the BranchGraph root
575:             * Also returns the nodes id
576:             *
577:             * Used to associate graphs with a locale without storing the graph at the
578:             * current time.
579:             */
580:            public int addBranchGraphReference(SceneGraphObject node,
581:                    int branchGraphID) {
582:                if (node == null)
583:                    return 0;
584:
585:                SymbolTableData symbol = getSymbol(node);
586:
587:                if (symbol != null) {
588:                    if (symbol.referenceCount == 1)
589:                        sharedNodes.add(symbol);
590:                    symbol.referenceCount++;
591:                } else {
592:                    symbol = new SymbolTableData(nodeID++, node, null, -3);
593:                    j3dNodeIndex.put(node, symbol);
594:                    nodeIDIndex.add(symbol);
595:                    danglingReferences.put(node, symbol);
596:                }
597:
598:                symbol.branchGraphID = branchGraphID;
599:                for (int i = branchGraphs.size(); i < branchGraphID + 1; i++) {
600:                    branchGraphs.add(null);
601:                    branchGraphDependencies.add(null);
602:                }
603:
604:                branchGraphs.set(symbol.branchGraphID, symbol);
605:
606:                return symbol.nodeID;
607:            }
608:
609:            /**
610:             * Return true if this node has already been loaded
611:             */
612:            public boolean isLoaded(int nodeID) {
613:                SymbolTableData symbol = getSymbol(nodeID);
614:
615:                if (symbol == null)
616:                    return false;
617:
618:                if (symbol.j3dNode == null)
619:                    return false;
620:
621:                return true;
622:            }
623:
624:            /**
625:             * Return the Java3D node associated with the nodeID.
626:             *
627:             * The method will call buildGraph() on the node if necessary
628:             */
629:            public SceneGraphObject getJ3dNode(int nodeID) {
630:                if (nodeID == 0)
631:                    return null;
632:
633:                SymbolTableData symbol = getSymbol(nodeID);
634:
635:                // Although referenced this node was not attached to the
636:                // scenegraph, so return null
637:                if (symbol.branchGraphID == -3)
638:                    return null;
639:
640:                if (symbol != null && symbol.j3dNode == null) {
641:                    if (symbol.isNodeComponent
642:                            && (control instanceof  RandomAccessFileControl)) {
643:                        try {
644:                            ((RandomAccessFileControl) control)
645:                                    .loadNodeComponent(symbol);
646:                        } catch (IOException e) {
647:                            System.out
648:                                    .println("FAILED to seek and load NodeComponent");
649:                            return null;
650:                        }
651:                    } else {
652:                        System.out
653:                                .println("WARNING - Object has not been loaded "
654:                                        + nodeID);
655:                        System.out.println("Need to load branchgraph "
656:                                + symbol.branchGraphID);
657:                        return null;
658:                    }
659:                } else if (symbol == null) {
660:                    throw new SGIORuntimeException("Missing Symbol " + nodeID);
661:                }
662:
663:                if (!symbol.graphBuilt) {
664:                    symbol.graphBuilt = true;
665:                    symbol.nodeState.buildGraph();
666:                }
667:
668:                return symbol.j3dNode;
669:            }
670:
671:            /**
672:             * Get the table entry for node
673:             */
674:            public SymbolTableData getSymbol(SceneGraphObject node) {
675:                //System.out.println("getSymbol "+node+"  "+j3dNodeIndex.get( node ));
676:                return (SymbolTableData) j3dNodeIndex.get(node);
677:            }
678:
679:            /**
680:             * Return the node with the give ID
681:             */
682:            public SymbolTableData getSymbol(int nodeID) {
683:                // nodeID's start at 1
684:
685:                if (nodeID == 0 || nodeID > nodeIDIndex.size())
686:                    return null;
687:                else
688:                    return (SymbolTableData) nodeIDIndex.get(nodeID);
689:            }
690:
691:            /** Get the symbol for the shared group
692:             *  If the sharedgroup has not been loaded then load it before
693:             *  returning (if we are using RandomAccessFileControl
694:             */
695:            public SymbolTableData getSharedGroup(int nodeID) {
696:                SymbolTableData symbol = getSymbol(nodeID);
697:
698:                if (symbol.nodeState == null
699:                        && control instanceof  RandomAccessFileControl) {
700:                    try {
701:                        ((RandomAccessFileControl) control)
702:                                .loadSharedGroup(symbol);
703:                    } catch (java.io.IOException e) {
704:                        e.printStackTrace();
705:                        throw new SGIORuntimeException(
706:                                "Internal error in getSharedGroup");
707:                    }
708:                }
709:
710:                return symbol;
711:            }
712:
713:            /** 
714:             * Set the position of the object referenced by state
715:             */
716:            public void setFilePosition(long ptr, SceneGraphObjectState state) {
717:                if (state instanceof  NullSceneGraphObjectState)
718:                    return;
719:
720:                SymbolTableData symbol = getSymbol(state.getNodeID());
721:
722:                symbol.filePosition = ptr;
723:            }
724:
725:            /**
726:             * Associate the name with the scene graph object 
727:             */
728:            public void addNamedObject(String name, SceneGraphObject object) {
729:                namedObjects.put(name, object);
730:            }
731:
732:            /**
733:             * Add all the named objects in <code>map</code>
734:             */
735:            public void addNamedObjects(HashMap map) {
736:                if (map != null)
737:                    namedObjects.putAll(map);
738:            }
739:
740:            /**
741:             * Return the SceneGraphObject associated with the name
742:             */
743:            public SceneGraphObject getNamedObject(String name)
744:                    throws NamedObjectException, ObjectNotLoadedException {
745:                Object obj = namedObjects.get(name);
746:                if (obj == null)
747:                    throw new NamedObjectException("Unknown name :" + name);
748:
749:                if (obj instanceof  SceneGraphObject)
750:                    return (SceneGraphObject) obj;
751:                else {
752:                    SymbolTableData symbol = getSymbol(((Integer) obj)
753:                            .intValue());
754:                    if (symbol == null || symbol.j3dNode == null)
755:                        throw new ObjectNotLoadedException(((Integer) obj)
756:                                .toString());
757:                    return symbol.j3dNode;
758:                }
759:            }
760:
761:            /**
762:             * Get all the names of the named objects
763:             */
764:            public String[] getNames() {
765:                return (String[]) namedObjects.keySet()
766:                        .toArray(new String[] {});
767:            }
768:
769:            /**
770:             * Add the namedObject mappings to <code>map</code>
771:             */
772:            public void getNamedObjectMap(HashMap map) {
773:                map.putAll(namedObjects);
774:            }
775:
776:            public String toString() {
777:                StringBuffer buf = new StringBuffer();
778:
779:                for (int i = 0; i < nodeIDIndex.size(); i++) {
780:                    SymbolTableData data = (SymbolTableData) nodeIDIndex.get(i);
781:                    if (data != null)
782:                        buf.append(data.nodeID + " " + data.referenceCount
783:                                + " " + data.filePosition + "  "
784:                                + data.branchGraphID + "  " + data.nodeState
785:                                + "\n");
786:                }
787:
788:                buf.append("\nShared Objects\n");
789:
790:                ListIterator l = sharedNodes.listIterator();
791:                while (l.hasNext()) {
792:                    SymbolTableData data = (SymbolTableData) l.next();
793:                    buf.append(data.nodeID + " " + data.referenceCount + " "
794:                            + data.filePosition + "  " + data.branchGraphID
795:                            + "  " + data.j3dNode + "\n");
796:                }
797:
798:                buf.append("\nNamed Objects\n");
799:
800:                String[] names = getNames();
801:                for (int i = 0; i < names.length; i++)
802:                    buf.append(names[i] + "  " + namedObjects.get(names[i]));
803:
804:                buf.append("\nBranch Graphs\n");
805:                for (int i = 0; i < branchGraphs.size(); i++) {
806:                    SymbolTableData data = (SymbolTableData) branchGraphs
807:                            .get(i);
808:                    if (data == null)
809:                        System.out.println("Data is null " + i + "  "
810:                                + branchGraphs.size());
811:                    buf
812:                            .append(data.nodeID + " " + data.referenceCount
813:                                    + " " + data.filePosition + "  "
814:                                    + data.branchGraphID + "  " + data.j3dNode
815:                                    + " " + data.nodeState + "\n");
816:                }
817:
818:                buf.append("\nBranch Graph Dependencies\n");
819:                for (int i = 0; i < branchGraphDependencies.size(); i++) {
820:                    buf.append("Graph " + i + " - ");
821:                    HashSet set = (HashSet) branchGraphDependencies.get(i);
822:                    if (set != null) {
823:                        Iterator it = set.iterator();
824:                        while (it.hasNext())
825:                            buf.append(((SymbolTableData) it.next()).nodeID
826:                                    + " ");
827:                    }
828:                    buf.append("\n");
829:                }
830:
831:                buf.append("------------------");
832:
833:                return buf.toString();
834:            }
835:
836:            /**
837:             * Clear all elements from the symbol table
838:             */
839:            public void clear() {
840:                j3dNodeIndex.clear();
841:                nodeIDIndex.clear();
842:                while (!unsavedNodeComponentsStack.empty())
843:                    unsavedNodeComponentsStack.pop();
844:                danglingReferences.clear();
845:                sharedNodes.clear();
846:                namedObjects.clear();
847:                nodeID = 1;
848:            }
849:
850:            /**
851:             * Clear all the Symbols that are not shared with other Graphs in the file
852:             *
853:             * Remove all Symbols from all structures with referenceCounts=1
854:             */
855:            public void clearUnshared() {
856:                // Convert as many named objects as possible to reference to j3dNode
857:                String[] names = getNames();
858:                for (int i = 0; i < names.length; i++) {
859:                    try {
860:                        Object obj = namedObjects.get(names[i]);
861:                        if (obj instanceof  Integer) {
862:                            SymbolTableData symbol = getSymbol(((Integer) obj)
863:                                    .intValue());
864:                            if (symbol != null && symbol.j3dNode != null)
865:                                namedObjects.put(names[i], symbol.j3dNode);
866:                        }
867:                    } catch (Exception e) {
868:                        e.printStackTrace();
869:                    }
870:                }
871:
872:                j3dNodeIndex.clear();
873:                nodeIDIndex.clear();
874:                while (!unsavedNodeComponentsStack.empty())
875:                    unsavedNodeComponentsStack.pop();
876:
877:                nodeIDIndexEnsureCapacity(nodeID);
878:
879:                // Add the shared and dangling Symbols back into the other structures
880:                ListIterator list = sharedNodes.listIterator();
881:                while (list.hasNext()) {
882:                    SymbolTableData symbol = (SymbolTableData) list.next();
883:                    nodeIDIndex.set(symbol.nodeID, symbol);
884:                    j3dNodeIndex.put(symbol.j3dNode, symbol);
885:                }
886:
887:                Iterator it = danglingReferences.values().iterator();
888:                while (it.hasNext()) {
889:                    SymbolTableData symbol = (SymbolTableData) it.next();
890:                    nodeIDIndex.set(symbol.nodeID, symbol);
891:                    j3dNodeIndex.put(symbol.j3dNode, symbol);
892:                }
893:
894:            }
895:
896:            /**
897:             * Given a nodeID return the corresponding scene graph object.
898:             *
899:             * Use only during the load cycle
900:             */
901:            public javax.media.j3d.SceneGraphObject resolveReference(int nodeID) {
902:                return getJ3dNode(nodeID);
903:            }
904:
905:        }
w___w__w_.j___a___va_2__s__.__c___o__m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.