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

Quick Search    Search Deep

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


1   /*
2    * @(#)ScriptGutRule.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.node.Node;
15  import com.trapezium.vrml.node.PROTO;
16  import com.trapezium.vrml.Scene;
17  import com.trapezium.vrml.FieldId;
18  import com.trapezium.vrml.fields.Field;
19  import com.trapezium.vrml.fields.ISField;
20  
21  /**
22   *  Creates the scene graph component for the internals of a Script node.
23   *
24   *  This is much different than other built in nodes because Script
25   *  nodes allow user defined interface (field) extensions.
26   *  
27   *  Grammar handled by "Build" method:
28   *  <PRE>
29   *  scriptGut:
30   *    nodeGut
31   *    restrictedInterfaceDeclaration
32   *    eventIn fieldType eventInId IS eventInId
33   *    eventOut fieldType eventOutId IS eventOutId
34   *    field fieldType fieldId IS fieldId
35   *  </PRE>    
36   *  @author          Johannes N. Johannsen
37   *  @version         1.12, 9 April 1998, made public
38   *  @version         1.1, 19 Jan 1998
39   *
40   *  @since           1.0
41   */
42  public class ScriptGutRule {
43      PROTORule protoRule;
44      ROUTERule routeRule = new ROUTERule();
45      RestrictedInterfaceDeclarationRule restrictedInterfaceDeclarationRule;
46      FieldFactory fieldFactory;
47      NodeBodyRule nodeBodyRule;
48      
49      /** Constructor for grammar rule that creates a Script field */
50      public ScriptGutRule( NodeRule nodeRule ) {
51          fieldFactory = new FieldFactory( nodeRule );
52          restrictedInterfaceDeclarationRule = new ScriptRestrictedInterfaceDeclarationRule( nodeRule );
53          nodeBodyRule = new NodeBodyRule( nodeRule );
54          protoRule = nodeRule.getPROTORule();
55      }
56      
57    /** Build onto a Node by adding on individual NodeGuts */
58    public void Build( int tokenOffset, TokenEnumerator v, Scene scene, Node parent,
59      PROTO protoParent ) {
60      GrammarRule.Enter( "ScriptGutRule.Build" );
61      if ( v.sameAs( tokenOffset, "PROTO" )) {
62        protoRule.Build( tokenOffset, v, scene, parent );
63      } else if ( v.sameAs( tokenOffset, "ROUTE" )) {
64        routeRule.Build( tokenOffset, v, scene, parent );
65      } else {
66        String fieldName = v.toString( tokenOffset );
67        if (( fieldName.compareTo( "eventIn" ) == 0 ) || 
68          ( fieldName.compareTo( "eventOut" ) == 0 ) || 
69          ( fieldName.compareTo( "field" ) == 0 )) {
70          restrictedInterfaceDeclarationRule.Build( tokenOffset, v, scene, parent );
71        } else if ( fieldName.compareTo( "exposedField" ) == 0 ) {
72            FieldId fieldId = new FieldId( tokenOffset, v );
73          parent.addChild( fieldId );
74          fieldId.setError( "Script nodes cannot have exposedFields." );
75        } else {
76            nodeBodyRule.Build( tokenOffset, v, scene, parent );
77          if ( fieldName.compareTo( "url" ) == 0 ) {
78            if ( javascript( tokenOffset, v )) {
79              addScriptFunctions( parent, tokenOffset, v );
80            }
81          }
82        }
83      }
84      GrammarRule.Exit( "ScriptGutRule.Build" );
85    }
86  
87      //
88      //  This needs some work, not detecting javascript correctly.
89      //  Bug is when url [ "url1", "url2" ]
90      //  In this case, have to check each url for javascript functions.
91      //  Similarly "addScriptFunctions" has to handle this case.
92      //  UrlVisitor probably has to deal with this as well.  Need a different design 
93      //  in this case.
94      //
95    boolean javascript( int tokenOffset, TokenEnumerator v ) {
96          int state = v.getState();
97          v.setState( tokenOffset );
98      tokenOffset = v.getNextToken();
99      if ( tokenOffset != -1 ) {
100         if ( v.isLeftBracket( tokenOffset )) {
101             // partial fix, if we have:  url [ "url1", ... ] 
102             // here we just check "url1" for javascript
103             tokenOffset = v.getNextToken();
104             if ( tokenOffset != -1 ) {
105                 if ( v.isQuotedString( tokenOffset )) {
106                     String tokString = v.toString( tokenOffset );
107                     if ( tokString.indexOf( "javascript: " ) > 0 ) {
108                         v.setState( state );
109                         return( true );
110                     } else if ( tokString.indexOf( "vrmlscript:" ) > 0 ) {
111                         v.setState( state );
112                         return( true );
113                     }
114                 }
115             }
116         } else {
117             String qs = v.toString( tokenOffset );
118             if ( v.isQuotedString( tokenOffset )) {
119               String tokString = v.toString( tokenOffset );
120               if ( tokString.indexOf( "javascript:" ) > 0 ) {
121                   v.setState( state );
122                 return( true );
123               } else if ( tokString.indexOf( "vrmlscript:" ) > 0 ) {
124                   v.setState( state );
125                 return( true );
126               }
127             }
128            }
129          }
130     v.setState( state );
131     return( false );
132   }
133 
134 
135   /** add Javascript functions direcly from token stream.
136    *
137    *  This is used when the Javascript is embedded directly in the VRML file
138    *  as part of the url string, using the "javascript: ..." format.
139    *
140    *  The tokens are examined one by noe until a token is found that
141    *  is not part of a quoted string.  As tokens are examined, any functions
142    *  fuond are added to the parent node.
143    *
144    *  @param  parent  script node parent
145    *  @param  firstTokenOffset  start of the javascript url
146    */
147   void addScriptFunctions( Node parent, int firstTokenOffset, TokenEnumerator v ) {
148       int state = v.getState();
149       v.setState( firstTokenOffset );
150     int scannerOffset = v.getNextToken();
151     while ( scannerOffset != -1 ) {
152       if ( v.isQuotedString( scannerOffset ) || v.isContinuationString( scannerOffset )) {
153         String s = v.toString( scannerOffset );
154         VRML97.addFunction( s, parent );
155       } else {
156         break;
157       }
158       scannerOffset = v.getNextToken();
159     }
160     v.setState( state );
161   }
162 }