KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > cypress > CssParser


1 /*
2 ** Cypress - CSS Parser
3 ** Copyright (c) 2001, 2002, 2003 by Gerald Bauer
4 **
5 ** This program is free software.
6 **
7 ** You may redistribute it and/or modify it under the terms of the GNU
8 ** Lesser General Public License as published by the Free Software Foundation.
9 ** Version 2.1 of the license should be included with this distribution in
10 ** the file LICENSE, as well as License.html. If the license is not
11 ** included with this distribution, you may find a copy at the FSF web
12 ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
13 ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
14 **
15 ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
16 ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
17 ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
18 ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
19 ** REDISTRIBUTION OF THIS SOFTWARE.
20 **
21 */

22
23 package cypress;
24
25 import java.io.*;
26 import java.net.*;
27 import java.util.*;
28 import cypress.spi.*;
29
30 public class CssParser
31 {
32    protected ConditionFactory _conditionFactory;
33
34    /**
35     * The current token.
36     */

37    protected int _current;
38
39    protected DocumentHandler _documentHandler;
40
41    protected String JavaDoc _documentUri;
42    protected ErrorHandler _errorHandler;
43    /**
44     * The lexer used to break the input source into tokens.
45     */

46    protected CssLexer _lexer;
47
48    protected SelectorFactory _selectorFactory;
49
50    public void setConditionFactory( ConditionFactory factory )
51    {
52       _conditionFactory = factory;
53    }
54
55    public void setDocumentHandler( DocumentHandler handler )
56    {
57       _documentHandler = handler;
58    }
59
60    public void setErrorHandler( ErrorHandler handler )
61    {
62       _errorHandler = handler;
63    }
64
65    public void setSelectorFactory( SelectorFactory factory )
66    {
67       _selectorFactory = factory;
68    }
69
70
71    public String JavaDoc formatMessage( String JavaDoc key, Object JavaDoc[] args )
72    {
73       return key;
74    }
75
76    public CssValue parsePropertyValue( InputSource source )
77           throws CssParseException, IOException
78    {
79       _lexer = new CssLexer( characterStream( source ) );
80       return parsePropertyValueInternal();
81    }
82
83    public CssValue parsePropertyValue( String JavaDoc source )
84           throws CssParseException, IOException
85    {
86       _lexer = new CssLexer( source );
87       return parsePropertyValueInternal();
88    }
89
90    public void parseRule( InputSource source )
91           throws CssParseException, IOException
92    {
93       _lexer = new CssLexer( characterStream( source ) );
94       parseRuleInternal();
95    }
96
97    public void parseRule( String JavaDoc source )
98           throws CssParseException, IOException
99    {
100       _lexer = new CssLexer( source );
101       parseRuleInternal();
102    }
103
104    public List parseSelectors( InputSource source )
105           throws CssParseException, IOException
106    {
107       _lexer = new CssLexer( characterStream( source ) );
108       return parseSelectorsInternal();
109    }
110
111    public List parseSelectors( String JavaDoc source )
112           throws CssParseException, IOException
113    {
114       _lexer = new CssLexer( source );
115       return parseSelectorsInternal();
116    }
117
118    public void parseStyleDeclaration( InputSource source )
119           throws CssParseException, IOException
120    {
121       _lexer = new CssLexer( characterStream( source ) );
122       parseStyleDeclarationInternal();
123    }
124
125    public void parseStyleDeclaration( String JavaDoc source )
126           throws CssParseException, IOException
127    {
128       _lexer = new CssLexer( source );
129       parseStyleDeclarationInternal();
130    }
131
132    public void parseStyleSheet( InputSource source )
133           throws CssParseException, IOException
134    {
135       _lexer = new CssLexer( characterStream( source ) );
136
137       try
138       {
139          _documentHandler.startDocument( source );
140
141          _current = _lexer.next();
142          switch ( _current )
143          {
144             case Css.Token.COMMENT:
145                _documentHandler.comment( _lexer.getStringValue() );
146          }
147
148          skipSpacesAndCDOCDC();
149
150          loop :
151          for( ; ; )
152          {
153             switch ( _current )
154             {
155                case Css.Token.EOF:
156                   break loop;
157                default:
158                   parseRuleSet();
159             }
160             skipSpacesAndCDOCDC();
161          }
162       }
163       finally
164       {
165          _documentHandler.endDocument( source );
166          _lexer = null;
167       }
168    }
169
170
171    public void parseStyleSheet( String JavaDoc uri )
172           throws CssParseException, IOException
173    {
174       parseStyleSheet( new InputSource( uri ) );
175    }
176
177    /**
178     * Converts the given input source into a Reader.
179     */

180    protected Reader characterStream( InputSource source ) throws CssParseException
181    {
182       Reader r = source.getCharacterStream();
183       if( r == null )
184       {
185          InputStream is = source.getByteStream();
186          if( is != null )
187          {
188             r = characterStream( source, is );
189          }
190          else
191          {
192             String JavaDoc uri = source.getUri();
193             if( uri != null )
194             {
195                try
196                {
197                   URL url = new URL( uri );
198                   is = url.openStream();
199                   r = characterStream( source, is );
200                }
201                catch( IOException e )
202                {
203                   throw new CssParseException( e );
204                }
205             }
206             else
207             {
208                throw new CssParseException( formatMessage( "empty.source", null ) );
209             }
210          }
211       }
212       return r;
213    }
214
215    /**
216     * Converts the given input stream into a Reader.
217     */

218    protected Reader characterStream( InputSource source, InputStream is )
219    {
220       _documentUri = source.getUri();
221       if( _documentUri == null )
222          _documentUri = "";
223
224       return new InputStreamReader( is );
225    }
226
227    protected CssParseException createCssParseException( String JavaDoc key )
228    {
229       return createCssParseException( key, null );
230    }
231
232    protected CssParseException createCssParseException( String JavaDoc key, Object JavaDoc[] params )
233    {
234       /*
235        * return new CssParseException(formatMessage(key, params),
236        * _documentURI,
237        * _lexer.getLine(),
238        * _lexer.getColumn());
239        */

240       return new CssParseException( formatMessage( key, params ),
241             _lexer.getLine(),
242             _lexer.getColumn() );
243    }
244
245    /**
246     * Converts the current lexical unit to a dimension.
247     */

248    protected CssValue dimension( boolean positive, CssValue prev ) throws CssParseException
249    {
250       try
251       {
252          float sgn = ( positive ) ? 1 : -1;
253          String JavaDoc val = _lexer.getStringValue();
254          int i;
255          loop :
256          for( i = 0; i < val.length(); i++ )
257          {
258             switch ( val.charAt( i ) )
259             {
260                default:
261                   break loop;
262                case '0':
263                case '1':
264                case '2':
265                case '3':
266                case '4':
267                case '5':
268                case '6':
269                case '7':
270                case '8':
271                case '9':
272                case '.':
273             }
274          }
275          nextIgnoreSpaces();
276          return CssDimension.createDimension(
277                ( sgn * Float.parseFloat( val.substring( 0, i ) ) ),
278                val.substring( i ),
279                prev );
280       }
281       catch( NumberFormatException JavaDoc e )
282       {
283          throw createCssParseException( "number.format" );
284       }
285    }
286
287    /**
288     * Converts a hash unit to a RGB color.
289     */

290    protected CssValue hexcolor( CssValue prev ) throws CssParseException
291    {
292       String JavaDoc val = _lexer.getStringValue();
293       int len = val.length();
294       CssValue params = null;
295       switch ( len )
296       {
297          case 3:
298             char rc = Character.toLowerCase( val.charAt( 0 ) );
299             char gc = Character.toLowerCase( val.charAt( 1 ) );
300             char bc = Character.toLowerCase( val.charAt( 2 ) );
301             if( !CssCharUtils.isHexadecimal( rc ) ||
302                   !CssCharUtils.isHexadecimal( gc ) ||
303                   !CssCharUtils.isHexadecimal( bc ) )
304             {
305                throw createCssParseException( "rgb.color", new Object JavaDoc[]{val} );
306             }
307             int t;
308             int r = t = ( rc >= '0' && rc <= '9' ) ? rc - '0' : rc - 'a' + 10;
309             t <<= 4;
310             r |= t;
311             int g = t = ( gc >= '0' && gc <= '9' ) ? gc - '0' : gc - 'a' + 10;
312             t <<= 4;
313             g |= t;
314             int b = t = ( bc >= '0' && bc <= '9' ) ? bc - '0' : bc - 'a' + 10;
315             t <<= 4;
316             b |= t;
317             params = CssInteger.createInteger( r, null );
318             CssValue tmp;
319             tmp = CssOperator.createComma( params );
320             tmp = CssInteger.createInteger( g, tmp );
321             tmp = CssOperator.createComma( tmp );
322             tmp = CssInteger.createInteger( b, tmp );
323             break;
324          case 6:
325             char rc1 = Character.toLowerCase( val.charAt( 0 ) );
326             char rc2 = Character.toLowerCase( val.charAt( 1 ) );
327             char gc1 = Character.toLowerCase( val.charAt( 2 ) );
328             char gc2 = Character.toLowerCase( val.charAt( 3 ) );
329             char bc1 = Character.toLowerCase( val.charAt( 4 ) );
330             char bc2 = Character.toLowerCase( val.charAt( 5 ) );
331             if( !CssCharUtils.isHexadecimal( rc1 ) ||
332                   !CssCharUtils.isHexadecimal( rc2 ) ||
333                   !CssCharUtils.isHexadecimal( gc1 ) ||
334                   !CssCharUtils.isHexadecimal( gc2 ) ||
335                   !CssCharUtils.isHexadecimal( bc1 ) ||
336                   !CssCharUtils.isHexadecimal( bc2 ) )
337             {
338                throw createCssParseException( "rgb.color" );
339             }
340             r = ( rc1 >= '0' && rc1 <= '9' ) ? rc1 - '0' : rc1 - 'a' + 10;
341             r <<= 4;
342             r |= ( rc2 >= '0' && rc2 <= '9' ) ? rc2 - '0' : rc2 - 'a' + 10;
343             g = ( gc1 >= '0' && gc1 <= '9' ) ? gc1 - '0' : gc1 - 'a' + 10;
344             g <<= 4;
345             g |= ( gc2 >= '0' && gc2 <= '9' ) ? gc2 - '0' : gc2 - 'a' + 10;
346             b = ( bc1 >= '0' && bc1 <= '9' ) ? bc1 - '0' : bc1 - 'a' + 10;
347             b <<= 4;
348             b |= ( bc2 >= '0' && bc2 <= '9' ) ? bc2 - '0' : bc2 - 'a' + 10;
349             params = CssInteger.createInteger( r, null );
350             tmp = CssOperator.createComma( params );
351             tmp = CssInteger.createInteger( g, tmp );
352             tmp = CssOperator.createComma( tmp );
353             tmp = CssInteger.createInteger( b, tmp );
354             break;
355          default:
356             throw createCssParseException( "rgb.color", new Object JavaDoc[]{val} );
357       }
358       nextIgnoreSpaces();
359       return CssBuiltInFunction.createRgb( params, prev );
360    }
361
362    /**
363     * Advances to the next token, ignoring comments.
364     */

365    protected int next()
366    {
367       try
368       {
369          for( ; ; )
370          {
371             _lexer.clearBuffer();
372             _current = _lexer.next();
373             if( _current == Css.Token.COMMENT )
374                _documentHandler.comment( _lexer.getStringValue() );
375             else
376                break;
377          }
378          return _current;
379       }
380       catch( CssParseException e )
381       {
382          reportError( e );
383          return _current;
384       }
385    }
386
387    /**
388     * Advances to the next token and skip the spaces, ignoring comments.
389     */

390    protected int nextIgnoreSpaces()
391    {
392       try
393       {
394          loop :
395          for( ; ; )
396          {
397             _lexer.clearBuffer();
398             _current = _lexer.next();
399             switch ( _current )
400             {
401                case Css.Token.COMMENT:
402                   _documentHandler.comment( _lexer.getStringValue() );
403                   break;
404                default:
405                   break loop;
406                case Css.Token.SPACE:
407             }
408          }
409          return _current;
410       }
411       catch( CssParseException e )
412       {
413          _errorHandler.error( createCssParseException( e.getMessage() ) );
414          return _current;
415       }
416    }
417
418    /**
419     * Converts the current lexical unit to a float.
420     */

421    protected float number( boolean positive ) throws CssParseException
422    {
423       try
424       {
425          float sgn = ( positive ) ? 1 : -1;
426          String JavaDoc val = _lexer.getStringValue();
427          nextIgnoreSpaces();
428          return sgn * Float.parseFloat( val );
429       }
430       catch( NumberFormatException JavaDoc e )
431       {
432          throw createCssParseException( "number.format" );
433       }
434    }
435
436    /**
437     * Parses a CSS2 expression.
438     *
439     *@param lex The type of the current lexical unit.
440     */

441    protected CssValue parseExpression( boolean param ) throws CssParseException
442    {
443       CssValue result = parseTerm( null );
444       CssValue curr = result;
445
446       for( ; ; )
447       {
448          boolean op = false;
449          switch ( _current )
450          {
451             case Css.Token.COMMA:
452                op = true;
453                curr = CssOperator.createComma( curr );
454                nextIgnoreSpaces();
455                break;
456             case Css.Token.DIVIDE:
457                op = true;
458                curr = CssOperator.createSlash( curr );
459                nextIgnoreSpaces();
460          }
461          if( param )
462          {
463             if( _current == Css.Token.RIGHT_BRACE )
464             {
465                if( op )
466                   throw createCssParseException( "token", new Object JavaDoc[]{new Integer JavaDoc( _current )} );
467
468                return result;
469             }
470             curr = parseTerm( curr );
471          }
472          else
473          {
474             switch ( _current )
475             {
476                case Css.Token.IMPORTANT_SYMBOL:
477                case Css.Token.SEMI_COLON:
478                case Css.Token.RIGHT_CURLY_BRACE:
479                case Css.Token.EOF:
480                   if( op )
481                      throw createCssParseException( "token", new Object JavaDoc[]{new Integer JavaDoc( _current )} );
482
483                   return result;
484                default:
485                   curr = parseTerm( curr );
486             }
487          }
488       }
489    }
490
491    /**
492     * Parses a CSS2 function.
493     */

494    protected CssValue parseFunction( boolean positive, CssValue prev ) throws CssParseException
495    {
496       String JavaDoc name = _lexer.getStringValue();
497       nextIgnoreSpaces();
498
499       CssValue params = parseExpression( true );
500
501       if( _current != Css.Token.RIGHT_BRACE )
502          throw createCssParseException( "token", new Object JavaDoc[]{new Integer JavaDoc( _current )} );
503
504       nextIgnoreSpaces();
505
506       predefined :
507       switch ( name.charAt( 0 ) )
508       {
509          case 'r':
510          case 'R':
511             CssValue lu;
512             if( name.equalsIgnoreCase( "rgb" ) )
513             {
514                lu = params;
515                if( lu == null )
516                   break;
517
518                switch ( lu.getType() )
519                {
520                   default:
521                      break predefined;
522                   case CssValue.INTEGER:
523                   case CssValue.PERCENTAGE:
524                      lu = lu.getNext();
525                }
526                if( lu == null )
527                   break;
528
529                switch ( lu.getType() )
530                {
531                   default:
532                      break predefined;
533                   case CssValue.OPERATOR_COMMA:
534                      lu = lu.getNext();
535                }
536                if( lu == null )
537                   break;
538
539                switch ( lu.getType() )
540                {
541                   default:
542                      break predefined;
543                   case CssValue.INTEGER:
544                   case CssValue.PERCENTAGE:
545                      lu = lu.getNext();
546                }
547                if( lu == null )
548                   break;
549
550                switch ( lu.getType() )
551                {
552                   default:
553                      break predefined;
554                   case CssValue.OPERATOR_COMMA:
555                      lu = lu.getNext();
556                }
557                if( lu == null )
558                   break;
559
560                switch ( lu.getType() )
561                {
562                   default:
563                      break predefined;
564                   case CssValue.INTEGER:
565                   case CssValue.PERCENTAGE:
566                      lu = lu.getNext();
567                }
568                if( lu != null )
569                   break;
570
571                return CssBuiltInFunction.createRgb( params, prev );
572             }
573       }
574
575       return CssUserFunction.createFunction( name, params, prev );
576    }
577
578    /**
579     * Parses property value using the current scanner.
580     */

581    protected CssValue parsePropertyValueInternal()
582           throws CssParseException, IOException
583    {
584       nextIgnoreSpaces();
585
586       CssValue exp = null;
587
588       try
589       {
590          exp = parseExpression( false );
591       }
592       catch( CssParseException e )
593       {
594          reportError( e );
595          throw e;
596       }
597
598       _lexer = null;
599
600       if( _current != Css.Token.EOF )
601          _errorHandler.fatal( createCssParseException( "eof.expected" ) );
602
603       return exp;
604    }
605
606    /**
607     * Parses a rule.
608     */

609    protected void parseRule()
610    {
611       parseRuleSet();
612    }
613
614    /**
615     * Parses a rule using the current scanner.
616     */

617    protected void parseRuleInternal()
618           throws CssParseException, IOException
619    {
620       nextIgnoreSpaces();
621       parseRule();
622       _lexer = null;
623    }
624
625    /**
626     * Parses a ruleset.
627     */

628    protected void parseRuleSet()
629    {
630       List sl = null;
631
632       try
633       {
634          sl = parseSelectorList();
635       }
636       catch( CssParseException e )
637       {
638          reportError( e );
639          return;
640       }
641
642       try
643       {
644          _documentHandler.startSelector( sl );
645
646          if( _current != Css.Token.LEFT_CURLY_BRACE )
647          {
648             reportError( "left.curly.brace" );
649             if( _current == Css.Token.RIGHT_CURLY_BRACE )
650                nextIgnoreSpaces();
651
652          }
653          else
654          {
655             nextIgnoreSpaces();
656
657             try
658             {
659                parseStyleDeclaration( true );
660             }
661             catch( CssParseException e )
662             {
663                reportError( e );
664             }
665          }
666       }
667       finally
668       {
669          _documentHandler.endSelector( sl );
670       }
671    }
672
673    /**
674     * Parses a selector.
675     */

676    protected Selector parseSelector() throws CssParseException
677    {
678       return parseSimpleSelector();
679    }
680
681    /**
682     * Parses a selector list
683     */

684    protected List parseSelectorList() throws CssParseException
685    {
686       ArrayList selectors = new ArrayList();
687       selectors.add( parseSelector() );
688
689       for( ; ; )
690       {
691          if( _current != Css.Token.COMMA )
692             return selectors;
693
694          nextIgnoreSpaces();
695          selectors.add( parseSelector() );
696       }
697    }
698
699    /**
700     * Parses selectors using the current scanner.
701     */

702    protected List parseSelectorsInternal()
703           throws CssParseException, IOException
704    {
705       nextIgnoreSpaces();
706       List ret = parseSelectorList();
707       _lexer = null;
708       return ret;
709    }
710
711    /**
712     * Parses a simple selector.
713     */

714    protected Selector parseSimpleSelector() throws CssParseException
715    {
716       Selector result;
717
718       switch ( _current )
719       {
720          case Css.Token.IDENTIFIER:
721             result = _selectorFactory.createElementSelector( _lexer.getStringValue() );
722             next();
723             break;
724          case Css.Token.ANY:
725             next();
726          // fall through to default branch; no break
727
default:
728             result = _selectorFactory.createAnySelector();
729       }
730
731       Condition cond = null;
732
733       switch ( _current )
734       {
735          case Css.Token.HASH:
736             cond = _conditionFactory.createIdCondition( _lexer.getStringValue() );
737             next();
738             break;
739          case Css.Token.DOT:
740             if( next() != Css.Token.IDENTIFIER )
741                throw createCssParseException( "identifier" );
742
743             cond = _conditionFactory.createClassCondition( _lexer.getStringValue() );
744             next();
745             break;
746       }
747
748       skipSpaces();
749
750       if( cond != null )
751          result = _selectorFactory.createConditionalSelector( result, cond );
752
753       return result;
754    }
755
756    /**
757     * Parses the given reader.
758     */

759    protected void parseStyleDeclaration( boolean inSheet )
760           throws CssParseException
761    {
762       for( ; ; )
763       {
764          switch ( _current )
765          {
766             case Css.Token.EOF:
767                if( inSheet )
768                   throw createCssParseException( "eof" );
769                return;
770             case Css.Token.RIGHT_CURLY_BRACE:
771                if( !inSheet )
772                   throw createCssParseException( "eof.expected" );
773                nextIgnoreSpaces();
774                return;
775             case Css.Token.SEMI_COLON:
776                nextIgnoreSpaces();
777                continue;
778             default:
779                throw createCssParseException( "identifier" );
780             case Css.Token.IDENTIFIER:
781          }
782
783          String JavaDoc name = _lexer.getStringValue();
784
785          if( nextIgnoreSpaces() != Css.Token.COLON )
786             throw createCssParseException( "colon" );
787
788          nextIgnoreSpaces();
789
790          CssValue exp = null;
791
792          try
793          {
794             exp = parseExpression( false );
795          }
796          catch( CssParseException e )
797          {
798             reportError( e );
799          }
800
801          if( exp != null )
802          {
803             boolean important = false;
804             if( _current == Css.Token.IMPORTANT_SYMBOL )
805             {
806                important = true;
807                nextIgnoreSpaces();
808             }
809             _documentHandler.property( name, exp, important );
810          }
811       }
812    }
813
814    /**
815     * Parses a style declaration using the current scanner.
816     */

817    protected void parseStyleDeclarationInternal()
818           throws CssParseException, IOException
819    {
820       nextIgnoreSpaces();
821       try
822       {
823          parseStyleDeclaration( false );
824       }
825       catch( CssParseException e )
826       {
827          reportError( e );
828       }
829       finally
830       {
831          _lexer = null;
832       }
833    }
834
835    /**
836     * Parses a CSS2 term.
837     */

838    protected CssValue parseTerm( CssValue prev ) throws CssParseException
839    {
840       boolean plus = true;
841       boolean sgn = false;
842
843       switch ( _current )
844       {
845          case Css.Token.MINUS:
846             plus = false;
847          case Css.Token.PLUS:
848             next();
849             sgn = true;
850          default:
851             switch ( _current )
852             {
853                case Css.Token.INTEGER:
854                   int s = ( plus ) ? 1 : -1;
855                   int val = s * Integer.parseInt( _lexer.getStringValue() );
856                   nextIgnoreSpaces();
857                   return CssInteger.createInteger( val, prev );
858                case Css.Token.REAL:
859                   return CssFloat.createReal( number( plus ), prev );
860                case Css.Token.PERCENTAGE:
861                   return CssFloat.createPercentage( number( plus ), prev );
862                case Css.Token.PT:
863                   return CssFloat.createPoint( number( plus ), prev );
864                case Css.Token.PC:
865                   return CssFloat.createPica( number( plus ), prev );
866                case Css.Token.PX:
867                   return CssFloat.createPixel( number( plus ), prev );
868                case Css.Token.CM:
869                   return CssFloat.createCentimeter( number( plus ), prev );
870                case Css.Token.MM:
871                   return CssFloat.createMillimeter( number( plus ), prev );
872                case Css.Token.IN:
873                   return CssFloat.createInch( number( plus ), prev );
874                case Css.Token.EM:
875                   return CssFloat.createEm( number( plus ), prev );
876                case Css.Token.EX:
877                   return CssFloat.createEx( number( plus ), prev );
878                case Css.Token.DIMENSION:
879                   return dimension( plus, prev );
880                case Css.Token.FUNCTION:
881                   return parseFunction( plus, prev );
882             }
883             if( sgn )
884                throw createCssParseException( "token", new Object JavaDoc[]{new Integer JavaDoc( _current )} );
885       }
886       switch ( _current )
887       {
888          case Css.Token.STRING:
889             String JavaDoc val = _lexer.getStringValue();
890             nextIgnoreSpaces();
891             return CssString.createString( val, prev );
892          case Css.Token.IDENTIFIER:
893             val = _lexer.getStringValue();
894             nextIgnoreSpaces();
895
896             if( val.equalsIgnoreCase( "inherit" ) )
897                return CssOperator.createInherit( prev );
898             else
899                return CssString.createIdent( val, prev );
900          case Css.Token.URI:
901             val = _lexer.getStringValue();
902             nextIgnoreSpaces();
903             return CssString.createUri( val, prev );
904          case Css.Token.HASH:
905             return hexcolor( prev );
906          default:
907             throw createCssParseException( "token", new Object JavaDoc[]{new Integer JavaDoc( _current )} );
908       }
909    }
910
911    /**
912     * Reports a parsing error.
913     */

914    protected void reportError( String JavaDoc key )
915    {
916       reportError( key, null );
917    }
918
919    /**
920     * Reports a parsing error.
921     */

922    protected void reportError( String JavaDoc key, Object JavaDoc[] params )
923    {
924       reportError( createCssParseException( key, params ) );
925    }
926
927    /**
928     * Reports a parsing error.
929     */

930    protected void reportError( CssParseException e )
931    {
932       _errorHandler.error( e );
933
934       int cbraces = 1;
935       for( ; ; )
936       {
937          switch ( _current )
938          {
939             case Css.Token.EOF:
940                return;
941             case Css.Token.SEMI_COLON:
942             case Css.Token.RIGHT_CURLY_BRACE:
943                if( --cbraces == 0 )
944                {
945                   nextIgnoreSpaces();
946                   return;
947                }
948             case Css.Token.LEFT_CURLY_BRACE:
949                cbraces++;
950          }
951          nextIgnoreSpaces();
952       }
953    }
954
955    /**
956     * Skips the white spaces.
957     */

958    protected int skipSpaces()
959    {
960       int lex = _lexer.getType();
961       while( lex == Css.Token.SPACE )
962       {
963          lex = next();
964       }
965       return lex;
966    }
967
968    /**
969     * Skips the white spaces and CDO/CDC untis.
970     */

971    protected int skipSpacesAndCDOCDC()
972    {
973       loop :
974       for( ; ; )
975       {
976          switch ( _current )
977          {
978             default:
979                break loop;
980             case Css.Token.COMMENT:
981             case Css.Token.SPACE:
982             case Css.Token.CDO:
983             case Css.Token.CDC:
984          }
985          _lexer.clearBuffer();
986          next();
987       }
988       return _current;
989    }
990 }
991
Popular Tags