Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/trapezium/vrml/grammar/BuiltInNodeRule.java


1   /*
2    * @(#)BuiltInNodeRule.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.Node;
19  import com.trapezium.vrml.node.NodeType;
20  import com.trapezium.vrml.node.DEFUSENode;
21  import com.trapezium.vrml.node.PROTO;
22  import com.trapezium.vrml.fields.Field;
23  import com.trapezium.vrml.fields.FieldValue;
24  import com.trapezium.vrml.fields.MFNodeValue;
25  
26  
27  /**
28   *  Creates built in VRML node scene graph components.
29   *
30   *  Grammar handled by "Build" method:
31   *  <PRE>
32   *    builtInNodeTypeId { builtInNodeGuts }
33   *  </PRE>
34   *  Grammar handled by "BuildNodeGuts" method:
35   *  <PRE>
36   *    builtInNodeGuts ::=
37   *       nodeBodyElement |
38   *       nodeBodyElement nodeBody |
39   *       empty ;
40   *  </PRE>
41   *  @author          Johannes N. Johannsen
42   *  @version         1.12, 24 April 1998, added DEFNameFactory control
43   *  @version         1.1, 8 Jan 1998
44   *
45   *  @since           1.0
46   */
47  class BuiltInNodeRule {
48      NodeBodyRule nodeBodyRule;
49      DEFNameFactory defNameFactory;
50  
51      /** class constructor */
52      BuiltInNodeRule( NodeRule nodeRule ) {
53          nodeBodyRule = new NodeBodyRule( nodeRule );
54          defNameFactory = nodeRule.getDEFNameFactory();
55      }
56  
57      /** Set the DEFNameFactory, used when scene factory overrides parser factory */
58      void setDEFNameFactory( DEFNameFactory defNameFactory ) {
59          this.defNameFactory = defNameFactory;
60      }
61  
62      /** Create a built in node and add to Scene graph.
63       *
64       *  @param  nodeType  built in node type
65       *  @param  tokenOffset  first token of node
66       *  @param  v  TokenEnumerator containing file text
67       *  @param  scene  Scene containing the resulting node
68       *  @param  parent immediate parent of resulting node
69       */
70    void Build( String nodeType, int tokenOffset, TokenEnumerator v, Scene scene, VrmlElement parent ) {
71      GrammarRule.Enter( "BuiltInNodeRule.Build" );
72      try {
73          Node node = VRML97.NodeFactory( nodeType );
74          VrmlElement parentElement = parent;
75  
76          // three conditions required for auto DEFfing:
77          // 1. defNameFactory non-null
78          // 2. parent not already a DEF
79          // 3. defNameFactory returns non-null
80          if (( defNameFactory != null ) && !( parent instanceof DEFUSENode )) {
81              String defName = defNameFactory.createDEFName( node.getNodeName() );
82              // we assume factory handles details of generating unique name
83              if ( defName != null ) {
84                  v.insert( tokenOffset, "DEF", defName );
85                  DEFUSENode d = new DEFUSENode( tokenOffset, v, DEFUSENode.DEF );
86                  tokenOffset = v.getNextToken();
87                  parent.addChild( d );
88                  parentElement = d;
89                  scene.registerDEF( d );
90                }
91              }
92  
93          node.setFirstTokenOffset( tokenOffset );
94          parentElement.addChild( node );
95          BuildNodeGuts( node, tokenOffset, v, scene );
96          if ( parentElement instanceof DEFUSENode ) {
97              parentElement.setLastTokenOffset( node.getLastTokenOffset() );
98          }
99          if ( parent instanceof DEFUSENode ) {
100             parent = parent.getParent();
101         }
102         if ( parent instanceof Scene ) {
103             parent = parent.getParent();
104             if ( !( parent instanceof PROTO ) && NodeType.isBadChild( nodeType )) {
105                 node.setError( "Invalid child node" );
106             }
107         } 
108         if ( NodeType.isGroupingNode( nodeType )) {
109             Field children = node.getField( "children" );
110             if ( children == null ) {
111                 if ( nodeType.compareTo( "Switch" ) == 0 ) {
112                     children = node.getField( "choice" );
113                 }
114             }
115             if ( children != null ) {
116                 FieldValue childnodes = children.getFieldValue();
117                 if ( childnodes instanceof MFNodeValue ) {
118                     MFNodeValue mfn = (MFNodeValue)childnodes;
119                     mfn.validateChildren();
120                 }
121             }
122         }
123       } catch ( Exception e ) {
124           System.out.println( "Exception " + e.toString() );
125           e.printStackTrace();
126       }
127         GrammarRule.Exit( "BuiltInNodeRule.Build" );
128     }
129 
130   /**
131    *  Create node body, and add to node.
132    *  <P>
133    *  Node body is assumed to be:  "{  ..node body.. }"
134    *  <P>
135    *  If left brace is missing, record the error, then continue parsing
136    *  as if it were there.
137    *  <P>
138    *  If right bracket encountered where right brace might be expected,
139    *  report the error, keep token enumerator pointing to right bracket.
140    *
141    *  @param  node  Node that is being created, either a PROTOInstance or built in node
142    *  @param  tokenOffset  first token of the node guts, should be a "{"
143    *  @param  v     TokenEnumerator containing file text
144    *  @param  scene Scene containing the node
145    */
146     void BuildNodeGuts( Node node, int tokenOffset, TokenEnumerator v, Scene scene ) {
147     int state = v.getState();
148     tokenOffset = v.getNextToken();
149     boolean leftBraceError = false;
150     if ( !LeftBrace.isValid( tokenOffset, v )) {
151         node.addChild( new LeftBrace( tokenOffset, v ));
152         leftBraceError = true;
153       }
154 
155     while ( true ) {
156       if ( !leftBraceError ) {
157         state = v.getState();
158         tokenOffset = v.getNextToken();
159       }
160       leftBraceError = false;
161       if ( tokenOffset == -1 ) {
162         node.setError( "Did not find matching right brace" );
163         break;
164       }
165       // If we get "]", add it and report as error, but leave enumerator on it as well
166       if ( v.isRightBracket( tokenOffset )) {
167         v.setState( state );
168         break;
169       }
170       if ( v.isRightBrace( tokenOffset)) {
171         break;
172       }
173       nodeBodyRule.Build( tokenOffset, v, scene, node );
174     }
175     if ( !RightBrace.isValid( tokenOffset, v )) {
176         node.addChild( new RightBrace( tokenOffset, v ));
177       }
178     node.setLastTokenOffset( tokenOffset );
179 
180     // have to preserve state of token enumerator, verify may change it
181     int vstate = v.getState();
182     NodeType.verify( node, node.getNodeName(), scene );
183     v.setState( vstate );
184   }
185 }