Source code: com/trapezium/chisel/reorganizers/Uninline.java
1 /*
2 * @(#)Uninline.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.chisel.reorganizers;
12
13 import com.trapezium.chisel.*;
14
15 //
16 // The Uninline chisel takes all Inlined files and merges them with
17 // the current file. It will only un-inline the first url listed in
18 // the url field. If no urls are listed, does nothing.
19 //
20
21 import java.io.PrintStream;
22 import com.trapezium.parse.TokenEnumerator;
23 import com.trapezium.vrml.node.Node;
24 import com.trapezium.vrml.fields.ExposedField;
25 import com.trapezium.vrml.fields.Field;
26 import com.trapezium.vrml.fields.MFFieldValue;
27 import com.trapezium.vrml.fields.FieldValue;
28 import com.trapezium.vrml.VrmlElement;
29 import com.trapezium.vrml.visitor.PROTOcollector;
30 import com.trapezium.vrml.Scene;
31 import com.trapezium.vrml.ROUTE;
32 import com.trapezium.vrml.node.PROTObase;
33 import com.trapezium.util.StringUtil;
34
35 import java.util.Vector;
36
37 public class Uninline extends Optimizer {
38 class SceneProtoCollector {
39 PROTOcollector pc;
40 SceneProtoCollector( PROTOcollector pc ) {
41 this.pc = pc;
42 }
43 PROTOcollector getPROTOcollector() {
44 return( pc );
45 }
46 Scene getScene() {
47 return( pc.getScene() );
48 }
49 }
50 int filesMerged = 0;
51 Vector pcList;
52
53 public Uninline() {
54 super( "Inline", "Moving inline files into main file..." );
55 reset();
56 }
57
58 public void reset() {
59 pcList = new Vector();
60 }
61
62 /** Called for each Inline encountered */
63 public void attemptOptimization( Node n ) {
64 Field urlField = n.getField( "url" );
65 if ( urlField instanceof ExposedField ) {
66 MFFieldValue urls = (MFFieldValue)urlField.getFieldValue();
67 if ( urls != null ) {
68 FieldValue f = urls.getFieldValueAt( 0 );
69 if ( f != null ) {
70 String url = dataSource.toString( f.getFirstTokenOffset() );
71 if ( url != null ) {
72 if (( baseFilePath != null ) && ( url.indexOf( ":" ) < 0)) {
73 url = StringUtil.stripQuotes( url );
74 if ( url.charAt( 0 ) != '/' ) {
75 url = baseFilePath + "/" + url;
76 } else {
77 url = baseFilePath + url;
78 }
79 } else {
80 url = StringUtil.stripQuotes( url );
81 }
82 if ( url != null ) {
83 // here we need to create a Scene,
84 // if it has PROTOs, print them at start of
85 // optimize, renaming to avoid namespace
86 // collisions
87 Scene s = new Scene( url );
88 if ( s.getTokenEnumerator() != null ) {
89 PROTOcollector protoCollector = new PROTOcollector( s, (Scene)n.getScene() );
90 s.traverse( protoCollector );
91 if ( protoCollector.hasPROTOs() ) {
92 replaceRange( 1, 1, protoCollector );
93 }
94 if ( s.getTokenEnumerator() != null ) {
95 replaceRange( n.getFirstTokenOffset(),
96 n.getLastTokenOffset(), new SceneProtoCollector( protoCollector ));
97 }
98 if ( protoCollector.hasROUTEs() ) {
99 pcList.addElement( protoCollector );
100 }
101 }
102 }
103 }
104 }
105 }
106 }
107 }
108
109 // Replace an Inline node with the actual file
110 // First gets a prefix that is does not exist in the file. This prefix
111 // is placed in front of every DEF/USE in the file being merged, to
112 // prevent name space conflicts.
113 //
114 public void optimize( TokenPrinter tp, Object param, int startTokenOffset, int endTokenOffset ) {
115 if ( param instanceof SceneProtoCollector ) {
116 SceneProtoCollector spc = (SceneProtoCollector)param;
117 printScene( tp, spc.getScene(), spc.getPROTOcollector() );
118 } else if ( param instanceof PROTOcollector ) {
119 PROTOcollector pc = (PROTOcollector)param;
120 int numberPROTOs = pc.getNumberPROTOs();
121 for ( int i = 0; i < numberPROTOs; i++ ) {
122 printPROTO( tp, pc.getPROTO( i ));
123 }
124 tp.printRange( startTokenOffset, endTokenOffset, false );
125 }
126 }
127
128 /** Print a Scene into the current Scene */
129 void printScene( TokenPrinter tp, Scene s, PROTOcollector pc ) {
130 tp.flush();
131 TokenEnumerator save = tp.getDataSource();
132 if ( s != null ) {
133 TokenEnumerator newDataSource = s.getTokenEnumerator();
134 if ( newDataSource != null ) {
135 if ( s.numberChildren() > 1 ) {
136 tp.print( "Group { children [" );
137 }
138 tp.setDataSource( newDataSource );
139 pc.scanTokens();
140 while ( pc.hasMoreTokens() ) {
141 int token = pc.getNextToken();
142 if ( token != -1 ) {
143 if ( pc.protoIsRemapped( token )) {
144 tp.print( pc.remapProto( token ));
145 } else if ( pc.useIsRemapped( token )) {
146 tp.print( pc.remapUse( token ));
147 } else {
148 tp.print( newDataSource, token );
149 }
150 }
151 }
152 if ( s.numberChildren() > 1 ) {
153 tp.print( "] }" );
154 }
155 }
156 tp.setDataSource( save );
157 }
158 }
159
160 /** Print a PROTO from another Scene */
161 void printPROTO( TokenPrinter tp, PROTObase proto ) {
162 tp.flush();
163 TokenEnumerator save = tp.getDataSource();
164 Scene s = (Scene)proto.getRoot();
165 if ( s != null ) {
166 TokenEnumerator newDataSource = s.getTokenEnumerator();
167 if ( newDataSource != null ) {
168 tp.setDataSource( newDataSource );
169 tp.printRange( proto.getFirstTokenOffset(),
170 proto.getLastTokenOffset(), false );
171 tp.setDataSource( save );
172 }
173 }
174 }
175
176 /** summary used by command line version */
177 public void summarize( PrintStream ps ) {
178 System.out.println( filesMerged + " files merged" );
179 }
180
181 public boolean hasFinalCode() {
182 return( pcList.size() > 0 );
183 }
184
185 public void printFinalCode( TokenPrinter tp ) {
186 tp.flush();
187 int pcCount = pcList.size();
188 TokenEnumerator save = tp.getDataSource();
189 for ( int i = 0; i < pcCount; i++ ) {
190 PROTOcollector pc = (PROTOcollector)pcList.elementAt( i );
191 int numberROUTEs = pc.getNumberROUTEs();
192 tp.setDataSource( pc.getDataSource() );
193 for ( int j = 0; j < numberROUTEs; j++ ) {
194 ROUTE r = pc.getROUTE( j );
195 tp.printRange( r.getFirstTokenOffset(), r.getLastTokenOffset(), false );
196 tp.flush();
197 }
198 }
199 tp.setDataSource( save );
200 }
201 }
202
203