Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / javax / swing / text / html / CSSParser.java
blob0bf76eb809f00e170b29ede64bfb73e70b3b5bb4
1 /* CSSParser.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.text.html;
41 import java.io.*;
43 /**
44 * Parses a CSS document. This works by way of a delegate that implements the
45 * CSSParserCallback interface. The delegate is notified of the following
46 * events:
47 * - Import statement: handleImport
48 * - Selectors handleSelector. This is invoked for each string. For example if
49 * the Reader contained p, bar , a {}, the delegate would be notified 4 times,
50 * for 'p,' 'bar' ',' and 'a'.
51 * - When a rule starts, startRule
52 * - Properties in the rule via the handleProperty. This
53 * is invoked one per property/value key, eg font size: foo;, would cause the
54 * delegate to be notified once with a value of 'font size'.
55 * - Values in the rule via the handleValue, this is notified for the total value.
56 * - When a rule ends, endRule
58 * @author Lillian Angel (langel@redhat.com)
60 class CSSParser
63 /**
64 * Receives all information about the CSS document structure while parsing it.
65 * The methods are invoked by parser.
67 static interface CSSParserCallback
69 /**
70 * Handles the import statment in the document.
72 * @param imp - the import string
74 public abstract void handleImport(String imp);
76 /**
77 * Called when the start of a rule is encountered.
79 public abstract void startRule();
81 /**
82 * Called when the end of a rule is encountered.
84 public abstract void endRule();
86 /**
87 * Handles the selector of a rule.
89 * @param selector - the selector in the rule
91 public abstract void handleSelector(String selector);
93 /**
94 * Handles the properties in the document.
96 * @param property - the property in the document.
98 public abstract void handleProperty(String property);
101 * Handles the values in the document.
103 * @param value - the value to handle.
105 public abstract void handleValue(String value);
110 * The identifier of the rule.
112 private static final int IDENTIFIER = 1;
115 * The open bracket.
117 private static final int BRACKET_OPEN = 2;
120 * The close bracket.
122 private static final int BRACKET_CLOSE = 3;
125 * The open brace.
127 private static final int BRACE_OPEN = 4;
130 * The close brace.
132 private static final int BRACE_CLOSE = 5;
135 * The open parentheses.
137 private static final int PAREN_OPEN = 6;
140 * The close parentheses.
142 private static final int PAREN_CLOSE = 7;
145 * The end of the document.
147 private static final int END = -1;
150 * The character mapping in the document.
152 // FIXME: What is this used for?
153 private static final char[] charMapping = null;
156 * Set to true if one character has been read ahead.
158 private boolean didPushChar;
161 * The read ahead character.
163 private int pushedChar;
166 * Temporary place to hold identifiers.
168 private StringBuffer unitBuffer;
171 * Used to indicate blocks.
173 private int[] unitStack;
176 * Number of valid blocks.
178 private int stackCount;
181 * Holds the incoming CSS rules.
183 private Reader reader;
186 * Set to true when the first non @ rule is encountered.
188 private boolean encounteredRuleSet;
191 * The call back used to parse.
193 private CSSParser.CSSParserCallback callback;
196 * nextToken() inserts the string here.
198 private char[] tokenBuffer;
201 * Current number of chars in tokenBufferLength.
203 private int tokenBufferLength;
206 * Set to true if any whitespace is read.
208 private boolean readWS;
211 * Constructor
213 CSSParser()
215 unitBuffer = new StringBuffer();
216 tokenBuffer = new char[10];
220 * Appends a character to the token buffer.
222 * @param c - the character to append
224 private void append(char c)
226 if (tokenBuffer.length >= tokenBufferLength)
228 char[] temp = new char[tokenBufferLength * 2];
229 if (tokenBuffer != null)
230 System.arraycopy(tokenBuffer, 0, temp, 0, tokenBufferLength);
232 temp[tokenBufferLength] = c;
233 tokenBuffer = temp;
235 else
236 tokenBuffer[tokenBufferLength] = c;
237 tokenBufferLength++;
241 * Fetches the next token.
243 * @param c - the character to fetch.
244 * @return the location
245 * @throws IOException - any i/o error encountered while reading
247 private int nextToken(char c) throws IOException
249 readWS = false;
250 int next = readWS();
252 switch (next)
254 case '\"':
255 if (tokenBufferLength > 0)
256 tokenBufferLength--;
257 return IDENTIFIER;
258 case '\'':
259 if (tokenBufferLength > 0)
260 tokenBufferLength--;
261 return IDENTIFIER;
262 case '(':
263 return PAREN_OPEN;
264 case ')':
265 return PAREN_CLOSE;
266 case '{':
267 return BRACE_OPEN;
268 case '}':
269 return BRACE_CLOSE;
270 case '[':
271 return BRACKET_OPEN;
272 case ']':
273 return BRACKET_CLOSE;
274 case -1:
275 return END;
276 default:
277 pushChar(next);
278 getIdentifier(c);
279 return IDENTIFIER;
284 * Reads a character from the stream.
286 * @return the number of characters read or -1 if end of stream is reached.
287 * @throws IOException - any i/o encountered while reading
289 private int readChar() throws IOException
291 if (didPushChar)
293 didPushChar = false;
294 return pushedChar;
296 return reader.read();
300 * Parses the the contents of the reader using the
301 * callback.
303 * @param reader - the reader to read from
304 * @param callback - the callback instance
305 * @param parsingDeclaration - true if parsing a declaration
306 * @throws IOException - any i/o error from the reader
308 void parse(Reader reader, CSSParser.CSSParserCallback callback,
309 boolean parsingDeclaration)
310 throws IOException
312 this.reader = reader;
313 this.callback = callback;
317 if (!parsingDeclaration)
318 while(getNextStatement());
319 else
320 parseDeclarationBlock();
322 catch (IOException ioe)
324 // Nothing to do here.
329 * Skips any white space, returning the character after the white space.
331 * @return the character after the whitespace
332 * @throws IOException - any i/o error from the reader
334 private int readWS() throws IOException
336 int next = readChar();
337 while (Character.isWhitespace((char) next))
339 readWS = true;
340 int tempNext = readChar();
341 if (tempNext == END)
342 return next;
343 next = tempNext;
346 // Its all whitespace
347 return END;
351 * Gets the next statement, returning false if the end is reached.
352 * A statement is either an At-rule, or a ruleset.
354 * @return false if the end is reached
355 * @throws IOException - any i/o error from the reader
357 private boolean getNextStatement() throws IOException
359 int c = nextToken((char) 0);
360 switch (c)
362 case PAREN_OPEN:
363 case BRACE_OPEN:
364 case BRACKET_OPEN:
365 parseTillClosed(c);
366 break;
367 case BRACKET_CLOSE:
368 case BRACE_CLOSE:
369 case PAREN_CLOSE:
370 throw new IOException("Not a proper statement.");
371 case IDENTIFIER:
372 if (tokenBuffer[0] == ('@'))
373 parseAtRule();
374 else
375 parseRuleSet();
376 break;
377 case END:
378 return false;
380 return true;
384 * Parses an @ rule, stopping at a matching brace pair, or ;.
386 * @throws IOException - any i/o error from the reader
388 private void parseAtRule() throws IOException
390 // An At-Rule begins with the "@" character followed immediately by a keyword.
391 // Following the keyword separated by a space is an At-rule statement appropriate
392 // to the At-keyword used. If the At-Rule is a simple declarative statement
393 // (charset, import, fontdef), it is terminated by a semi-colon (";".)
394 // If the At-Rule is a conditional or informative statement (media, page, font-face),
395 // it is followed by optional arguments and then a style declaration block inside matching
396 // curly braces ("{", "}".) At-Rules are sometimes nestable, depending on the context.
397 // If any part of an At-Rule is not understood, it should be ignored.
399 // FIXME: Not Implemented
400 // call handleimport
404 * Parses the next rule set, which is a selector followed by a declaration
405 * block.
407 * @throws IOException - any i/o error from the reader
409 private void parseRuleSet() throws IOException
411 // call parseDeclarationBlock
412 // call parse selectors
413 // call parse identifiers
414 // call startrule/endrule
415 // FIXME: Not Implemented
419 * Parses a set of selectors, returning false if the end of the stream is
420 * reached.
422 * @return false if the end of stream is reached
423 * @throws IOException - any i/o error from the reader
425 private boolean parseSelectors() throws IOException
427 // FIXME: Not Implemented
428 // call handleselector
429 return false;
433 * Parses a declaration block. Which a number of declarations followed by a
434 * })].
436 * @throws IOException - any i/o error from the reader
438 private void parseDeclarationBlock() throws IOException
440 // call parseDeclaration
441 // FIXME: Not Implemented
445 * Parses a single declaration, which is an identifier a : and another identifier.
446 * This returns the last token seen.
448 * @returns the last token
449 * @throws IOException - any i/o error from the reader
451 private int parseDeclaration() throws IOException
453 // call handleValue
454 // FIXME: Not Implemented
455 return 0;
459 * Parses identifiers until c is encountered, returning the ending token,
460 * which will be IDENTIFIER if c is found.
462 * @param c - the stop character
463 * @param wantsBlocks - true if blocks are wanted
464 * @return the ending token
465 * @throws IOException - any i/o error from the reader
467 private int parseIdentifiers(char c, boolean wantsBlocks) throws IOException
469 // FIXME: Not implemented
470 // call handleproperty?
471 return 0;
475 * Parses till a matching block close is encountered. This is only appropriate
476 * to be called at the top level (no nesting).
478 * @param i - FIXME
479 * @throws IOException - any i/o error from the reader
481 private void parseTillClosed(int i) throws IOException
483 // FIXME: Not Implemented
487 * Gets an identifier, returning true if the length of the string is greater
488 * than 0, stopping when c, whitespace, or one of {}()[] is hit.
490 * @param c - the stop character
491 * @return returns true if the length of the string > 0
492 * @throws IOException - any i/o error from the reader
494 private boolean getIdentifier(char c) throws IOException
496 // FIXME: Not Implemented
497 return false;
501 * Reads till c is encountered, escaping characters as necessary.
503 * @param c - the stop character
504 * @throws IOException - any i/o error from the reader
506 private void readTill(char c) throws IOException
508 // FIXME: Not Implemented
512 * Parses a comment block.
514 * @throws IOException - any i/o error from the reader
516 private void readComment() throws IOException
518 // Should ignore comments. Read until end of comment.
519 // FIXME: Not implemented
523 * Called when a block start is encountered ({[.
525 * @param start of block
527 private void startBlock(int start)
529 // FIXME: Not Implemented
533 * Called when an end block is encountered )]}
535 * @param end of block
537 private void endBlock(int end)
539 // FIXME: Not Implemented
543 * Checks if currently in a block.
545 * @return true if currently in a block.
547 private boolean inBlock()
549 // FIXME: Not Implemented
550 return false;
554 * Supports one character look ahead, this will throw if called twice in a row.
556 * @param c - the character to push.
557 * @throws IOException - if called twice in a row
559 private void pushChar(int c) throws IOException
561 if (didPushChar)
562 throw new IOException("pushChar called twice.");
563 didPushChar = true;
564 pushedChar = c;