001: /*
002: * $RCSfile: TextfileParser.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.4 $
041: * $Date: 2007/02/09 17:20:09 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.loaders.lw3d;
046:
047: import java.io.*;
048: import com.sun.j3d.loaders.ParsingErrorException;
049:
050: /**
051: * This class is a superclass for most of the Lws* Scene-file parsing
052: * classes. It provides some debugging utilities, as well as utilities for
053: * reading the types of data common to this loader.
054: */
055:
056: class TextfileParser {
057:
058: // class variables
059: static int WORD = StreamTokenizer.TT_WORD;
060: static int NUMBER = StreamTokenizer.TT_NUMBER;
061: int currentLevel = 3;
062: final static int TRACE = DebugOutput.TRACE,
063: VALUES = DebugOutput.VALUES;
064: final static int MISC = DebugOutput.MISC,
065: LINE_TRACE = DebugOutput.LINE_TRACE;
066: final static int NONE = DebugOutput.NONE,
067: EXCEPTION = DebugOutput.EXCEPTION;
068: final static int TIME = DebugOutput.TIME;
069: protected DebugOutput debugPrinter;
070: char lineSeparatorChar = 0;
071:
072: TextfileParser() {
073: debugPrinter = new DebugOutput(EXCEPTION);
074: String lineSeparator = System.getProperty("line.separator");
075: lineSeparatorChar = lineSeparator.charAt(0);
076: debugOutputLn(VALUES, "lineSeparatorChar = "
077: + (int) lineSeparatorChar);
078: }
079:
080: protected void debugOutputLn(int outputType, String theOutput) {
081: if (theOutput.equals(""))
082: debugPrinter.println(outputType, theOutput);
083: else {
084: debugPrinter.println(outputType, getClass().getName()
085: + "::" + theOutput);
086: }
087: }
088:
089: protected void debugOutput(int outputType, String theOutput) {
090: debugPrinter.print(outputType, theOutput);
091: }
092:
093: /**
094: * Utility method to advance the tokenizer until we see the given
095: * string. This is used to skip by various parameters that we
096: * currently ignore in the loader.
097: */
098: void skipUntilString(StreamTokenizer st, String theString)
099: throws ParsingErrorException {
100: boolean done = false;
101: try {
102: while (!done) {
103: st.nextToken();
104: if (st.ttype == WORD && st.sval.equals(theString))
105: done = true;
106: }
107: } catch (IOException e) {
108: throw new ParsingErrorException(e.getMessage());
109: }
110: }
111:
112: /**
113: * Returns number from the tokenizer. Note that we don't recognize
114: * numbers in the tokenizer automatically because numbers might be in
115: * scientific notation, which isn't processed correctly by
116: * StreamTokenizer
117: */
118: double getNumber(StreamTokenizer st) throws ParsingErrorException,
119: NumberFormatException {
120: try {
121: int token = st.nextToken();
122: } catch (IOException e) {
123: throw new ParsingErrorException(e.getMessage());
124: }
125: checkType(st, WORD);
126: return ((Double.valueOf(st.sval)).doubleValue());
127: }
128:
129: /**
130: * Returns String from the tokenizer
131: */
132: String getString(StreamTokenizer st) throws ParsingErrorException {
133: try {
134: st.nextToken();
135: } catch (IOException e) {
136: throw new ParsingErrorException(e.getMessage());
137: }
138: checkType(st, WORD);
139: return (st.sval);
140: }
141:
142: /**
143: * Returns a "name" from the stream. This is different from simply a
144: * String because the name could contain whitespace characters
145: * (such as "object 1" or "objectname (sequence)") that would confuse
146: * the string parser. So we just grab all characters until EOL and
147: * concatenate them together to form the name
148: */
149: String getName(StreamTokenizer st) throws ParsingErrorException {
150: String theName = "";
151: st.ordinaryChar(lineSeparatorChar);
152: st.ordinaryChar('\n');
153: st.ordinaryChar('\r');
154: try {
155: st.nextToken();
156: while (st.ttype != lineSeparatorChar && st.ttype != '\r'
157: && st.ttype != '\n') {
158: if (st.ttype != '(' && st.ttype != ')')
159: theName += st.sval;
160: st.nextToken();
161: }
162: } catch (IOException e) {
163: throw new ParsingErrorException(e.getMessage());
164: }
165: st.whitespaceChars(lineSeparatorChar, lineSeparatorChar);
166: st.whitespaceChars('\n', '\n');
167: st.whitespaceChars('\r', '\r');
168: debugOutputLn(VALUES, "name = " + theName);
169: return theName;
170: }
171:
172: /**
173: * Gets the next token and ensures that it is the string we were
174: * expecting to see
175: */
176: void getAndCheckString(StreamTokenizer st, String expectedValue)
177: throws ParsingErrorException {
178: try {
179: st.nextToken();
180: checkString(st, expectedValue);
181: } catch (IOException e) {
182: throw new ParsingErrorException(e.getMessage());
183: }
184: }
185:
186: /**
187: * Error checking routine - makes sure the current token is the string
188: * we were expecting
189: */
190: void checkString(StreamTokenizer st, String theString)
191: throws ParsingErrorException {
192: if (!(st.ttype == StreamTokenizer.TT_WORD)
193: || !st.sval.equals(theString))
194: throw new ParsingErrorException("Bad String Token (wanted "
195: + theString + ", got " + st.sval + ": "
196: + st.toString());
197: }
198:
199: /**
200: * Error checking routine - makes sure the current token is of the right
201: * type
202: */
203: void checkType(StreamTokenizer st, int theType)
204: throws ParsingErrorException {
205: if (!(st.ttype == theType))
206: throw new ParsingErrorException("Bad Type Token, Expected "
207: + theType + " and received" + st.ttype);
208: }
209:
210: /**
211: * Utility routine - gets next token, checks it against our expectation,
212: * then skips a given number of tokens. This can be used to parse
213: * through (and ignore) certain parameter/value sets in the files
214: */
215: void skip(StreamTokenizer st, String tokenString, int skipVals)
216: throws ParsingErrorException {
217: try {
218: st.nextToken();
219: checkString(st, tokenString);
220: for (int i = 0; i < skipVals; ++i) {
221: st.nextToken();
222: }
223: } catch (IOException e) {
224: throw new ParsingErrorException(e.getMessage());
225: }
226: }
227:
228: /**
229: * Utility method- used to check whether the current token is equal
230: * to the given string
231: */
232: boolean isCurrentToken(StreamTokenizer st, String tokenString) {
233: if (st.ttype == WORD)
234: return (st.sval.equals(tokenString));
235: return false;
236: }
237: }
|