Source code: com/trapezium/vrml/grammar/PROTONodeRule.java
1 /*
2 * @(#)PROTONodeRule.java
3 *
4 * Copyright (c) 1998 by Trapezium Development LLC. All Rights Reserved.
5 *
6 * The information in this file is the property of Trapezium Development LLC
7 * and may be used only in accordance with the terms of the license granted
8 * by Trapezium.
9 *
10 */
11 package com.trapezium.vrml.grammar;
12
13 import com.trapezium.parse.TokenEnumerator;
14 import com.trapezium.vrml.Scene;
15 import com.trapezium.vrml.VrmlElement;
16 import com.trapezium.vrml.LeftBrace;
17 import com.trapezium.vrml.RightBrace;
18 import com.trapezium.vrml.node.PROTOInstance;
19 import com.trapezium.vrml.node.NodeType;
20 import com.trapezium.vrml.node.DEFUSENode;
21
22 /**
23 * Creates the scene graph component for a PROTO instance.
24 *
25 * Grammar handled by "Build" method:
26 * <PRE>
27 * protoNodeTypeId { nodeGuts }
28 * </PRE>
29 * Note: the PROTOInstance "copyBaseNodeInfo" method does not copy
30 * all nodes in the PROTO declaration body, and substitute values as
31 * indicated by IS. When this is done, PROTO checking can be done
32 * for PROTO interface fields passed through IS.
33 *
34 * @author Johannes N. Johannsen
35 * @version 1.12, 24 April 1998, added autoDEF
36 * @version 1.12, 6 Mar 1998, added Table 7 limits
37 * @version 1.1, 6 Jan 1998
38 *
39 * @since 1.0
40 */
41 class PROTONodeRule extends BuiltInNodeRule {
42 DEFNameFactory defNameFactory;
43
44 /** class constructor */
45 PROTONodeRule( NodeRule nodeRule ) {
46 super( nodeRule );
47 defNameFactory = nodeRule.getDEFNameFactory();
48 }
49
50 /** Set DEFNameFactory, used when scene factory overrides parser factory */
51 void setDEFNameFactory( DEFNameFactory defNameFactory ) {
52 this.defNameFactory = defNameFactory;
53 }
54
55 /**
56 * Create a PROTO instance and add it to the scene graph.
57 *
58 * @param nodeType type of PROTO to create
59 * @param tokenOffset first token of the PROTO instance
60 * @param v contains text of VRML file
61 * @param scene scene containing PROTO
62 * @param parent immediate parent of PROTO
63 */
64 void Build( String nodeType, int tokenOffset, TokenEnumerator v, Scene scene, VrmlElement parent ) {
65 GrammarRule.Enter( "PROTONodeRule.Build" );
66 try {
67 PROTOInstance pi = scene.PROTOFactory( nodeType );
68
69 // three conditions required for auto DEFfing:
70 // 1. defNameFactory non-null
71 // 2. parent not already a DEF
72 // 3. defNameFactory returns non-null
73 VrmlElement parentElement = parent;
74 if (( defNameFactory != null ) && !( parent instanceof DEFUSENode )) {
75 String defName = defNameFactory.createDEFName( pi.getPROTOname() );
76 // we assume factory handles details of generating unique name
77 if ( defName != null ) {
78 v.insert( tokenOffset, "DEF", defName );
79 DEFUSENode d = new DEFUSENode( tokenOffset, v, DEFUSENode.DEF );
80 tokenOffset = v.getNextToken();
81 parent.addChild( d );
82 parentElement = d;
83 scene.registerDEF( d );
84 }
85 }
86
87 pi.setFirstTokenOffset( tokenOffset );
88 parentElement.addChild( pi );
89 BuildNodeGuts( pi, tokenOffset, v, scene );
90 pi.copyBaseNodeInfo();
91 pi.verify( v );
92 if ( parentElement instanceof DEFUSENode ) {
93 parentElement.setLastTokenOffset( pi.getLastTokenOffset() );
94 }
95 pi.checkInUse();
96 } catch ( Exception e ) {
97 System.out.println( "Exception " + e );
98 e.printStackTrace();
99 }
100 GrammarRule.Exit( "PROTONodeRule.Build" );
101 }
102 }