Save This Page
Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » store » [javadoc | source]
    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans.impl.store;
   17   
   18   import org.apache.xmlbeans.impl.common.ValidatorListener;
   19   import javax.xml.stream.Location;
   20   import org.apache.xmlbeans.XmlCursor;
   21   import javax.xml.namespace.QName;
   22   
   23   final class Validate implements ValidatorListener.Event
   24   {
   25       Validate ( Cur c, ValidatorListener sink )
   26       {
   27           if (!c.isUserNode())
   28               throw new IllegalStateException( "Inappropriate location to validate" );
   29   
   30           _sink = sink;
   31           _cur = c;
   32           _textCur = c.tempCur();
   33           _hasText = false;
   34   
   35           _cur.push();
   36   
   37           try
   38           {
   39               process();
   40           }
   41           finally
   42           {
   43               _cur.pop();
   44               _cur = null;
   45               
   46               _sink = null;
   47               
   48               _textCur.release();
   49           }
   50       }
   51   
   52       private void process ( )
   53       {
   54           emitEvent( ValidatorListener.BEGIN );
   55   
   56           if (_cur.isAttr())
   57           {
   58               // If validating an attr, I'm really validating the contents of that attr.  So, go to
   59               // any text value and shove it thru the validator.
   60               
   61               _cur.next();
   62   
   63               if (_cur.isText())
   64                   emitText();
   65           }
   66           else
   67           {
   68               assert _cur.isContainer();
   69   
   70               // Do the attrs of the top container
   71               
   72               doAttrs();
   73   
   74               for ( _cur.next() ; ! _cur.isAtEndOfLastPush() ; _cur.next() )
   75               {
   76                   switch ( _cur.kind() )
   77                   {
   78                   case Cur.ELEM :
   79                       emitEvent( ValidatorListener.BEGIN );
   80                       doAttrs();
   81                       break;
   82                   
   83                   case - Cur.ELEM :
   84                       emitEvent( ValidatorListener.END );
   85                       break;
   86                   
   87                   case Cur.TEXT :
   88                       emitText();
   89                       break;
   90                       
   91                   case Cur.COMMENT  :
   92                   case Cur.PROCINST :
   93                       _cur.toEnd();
   94                       break;
   95   
   96                   default :
   97                       throw new RuntimeException( "Unexpected kind: " + _cur.kind() );
   98                   }
   99               }
  100           }
  101           
  102           emitEvent( ValidatorListener.END );
  103       }
  104   
  105       private void doAttrs ( )
  106       {
  107           // When processing attrs, there can be no accumulated text because there would have been
  108           // a preceeding event which would have flushged the text.
  109           
  110           assert !_hasText;
  111           
  112           if (_cur.toFirstAttr())
  113           {
  114               do
  115               {
  116                   if (_cur.isNormalAttr() && !_cur.getUri().equals( Locale._xsi ))
  117                       _sink.nextEvent( ValidatorListener.ATTR, this );
  118               }
  119               while ( _cur.toNextAttr() );
  120   
  121               _cur.toParent();
  122           }
  123           
  124           _sink.nextEvent( ValidatorListener.ENDATTRS, this );
  125       }
  126   
  127       private void emitText ( )
  128       {
  129           assert _cur.isText();
  130   
  131           if (_hasText)
  132           {
  133               if (_oneChunk)
  134               {
  135                   if (_textSb == null)
  136                       _textSb = new StringBuffer();
  137                   else
  138                       _textSb.delete( 0, _textSb.length() );
  139   
  140                   assert _textCur.isText();
  141   
  142                   CharUtil.getString(
  143                       _textSb, _textCur.getChars( -1 ), _textCur._offSrc, _textCur._cchSrc );
  144   
  145                   _oneChunk = false;
  146               }
  147               
  148               assert _textSb != null && _textSb.length() > 0;
  149                   
  150               CharUtil.getString( _textSb, _cur.getChars( -1 ), _cur._offSrc, _cur._cchSrc );
  151           }
  152           else
  153           {
  154               _hasText = true;
  155               _oneChunk = true;
  156               _textCur.moveToCur( _cur );
  157           }
  158       }
  159   
  160       private void emitEvent ( int kind )
  161       {
  162           assert kind != ValidatorListener.TEXT;
  163           assert kind != ValidatorListener.ATTR     || !_hasText;
  164           assert kind != ValidatorListener.ENDATTRS || !_hasText;
  165   
  166           if (_hasText)
  167           {
  168               _sink.nextEvent( ValidatorListener.TEXT, this );
  169               _hasText = false;
  170           }
  171   
  172           _sink.nextEvent( kind, this );
  173       }
  174   
  175       public String getText ( )
  176       {
  177           if (_cur.isAttr())
  178               return _cur.getValueAsString();
  179   
  180           assert _hasText;
  181           assert _oneChunk || (_textSb != null && _textSb.length() > 0);
  182           assert !_oneChunk || _textCur.isText();
  183   
  184           return _oneChunk ? _textCur.getCharsAsString( -1 ) : _textSb.toString();
  185       }
  186   
  187       public String getText ( int wsr )
  188       {
  189           if (_cur.isAttr())
  190               return _cur.getValueAsString( wsr );
  191   
  192           assert _hasText;
  193           assert _oneChunk || (_textSb != null && _textSb.length() > 0);
  194           assert !_oneChunk || _textCur.isText();
  195   
  196           if (_oneChunk)
  197               return _textCur.getCharsAsString( -1, wsr );
  198   
  199           return Locale.applyWhiteSpaceRule( _textSb.toString(), wsr );
  200       }
  201   
  202       public boolean textIsWhitespace ( )
  203       {
  204           if (_cur.isAttr())
  205           {
  206               return
  207                   _cur._locale.getCharUtil().isWhiteSpace(
  208                       _cur.getFirstChars(), _cur._offSrc, _cur._cchSrc );
  209           }
  210           
  211           assert _hasText;
  212   
  213           if (_oneChunk)
  214           {
  215               return
  216                   _cur._locale.getCharUtil().isWhiteSpace(
  217                       _textCur.getChars( -1 ), _textCur._offSrc, _textCur._cchSrc );
  218           }
  219   
  220           String s = _textSb.toString();
  221           
  222           return _cur._locale.getCharUtil().isWhiteSpace( s, 0, s.length() );
  223       }
  224   
  225       public String getNamespaceForPrefix ( String prefix )
  226       {
  227           return _cur.namespaceForPrefix( prefix, true );
  228       }
  229   
  230       public XmlCursor getLocationAsCursor ( )
  231       {
  232           return new Cursor( _cur );
  233       }
  234   
  235       public Location getLocation ( )
  236       {
  237           return null;
  238       }
  239   
  240       public String getXsiType ( )
  241       {
  242           return _cur.getAttrValue( Locale._xsiType );
  243       }
  244   
  245       public String getXsiNil ( )
  246       {
  247           return _cur.getAttrValue( Locale._xsiNil );
  248       }
  249   
  250       public String getXsiLoc ( )
  251       {
  252           return _cur.getAttrValue( Locale._xsiLoc );
  253       }
  254   
  255       public String getXsiNoLoc ( )
  256       {
  257           return _cur.getAttrValue( Locale._xsiNoLoc );
  258       }
  259   
  260       public QName getName ( )
  261       {
  262           return _cur.isAtLastPush() ? null : _cur.getName();
  263       }
  264   
  265       //
  266       //
  267       //
  268   
  269       private ValidatorListener _sink;
  270   
  271       private Cur _cur;
  272   
  273       // Two ways to accumulate text.  First, I can have a Cur positioned at the text.  I do this
  274       // instead of getting the there there because white space rules are applied at a later point.
  275       // This way, when I turn the text into a String, I can cache the string.  If multiple chunks
  276       // of text exists for one event, then I accumulate all the text into a string buffer and I,
  277       // then, don't care about caching Strings.
  278       
  279       private boolean _hasText;
  280       private boolean _oneChunk;
  281   
  282       private Cur          _textCur;
  283       private StringBuffer _textSb;
  284   }

Save This Page
Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » store » [javadoc | source]