Save This Page
Home » openjdk-7 » javax » swing » text » html » parser » [javadoc | source]
    1   /*
    2    * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.swing.text.html.parser;
   27   
   28   import java.util.Vector;
   29   import java.util.Enumeration;
   30   import java.io;
   31   
   32   
   33   /**
   34    * A representation of a content model. A content model is
   35    * basically a restricted BNF expression. It is restricted in
   36    * the sense that it must be deterministic. This means that you
   37    * don't have to represent it as a finite state automata.<p>
   38    * See Annex H on page 556 of the SGML handbook for more information.
   39    *
   40    * @author   Arthur van Hoff
   41    *
   42    */
   43   public final class ContentModel implements Serializable {
   44       /**
   45        * Type. Either '*', '?', '+', ',', '|', '&'.
   46        */
   47       public int type;
   48   
   49       /**
   50        * The content. Either an Element or a ContentModel.
   51        */
   52       public Object content;
   53   
   54       /**
   55        * The next content model (in a ',', '|' or '&' expression).
   56        */
   57       public ContentModel next;
   58   
   59       public ContentModel() {
   60       }
   61   
   62       /**
   63        * Create a content model for an element.
   64        */
   65       public ContentModel(Element content) {
   66           this(0, content, null);
   67       }
   68   
   69       /**
   70        * Create a content model of a particular type.
   71        */
   72       public ContentModel(int type, ContentModel content) {
   73           this(type, content, null);
   74       }
   75   
   76       /**
   77        * Create a content model of a particular type.
   78        */
   79       public ContentModel(int type, Object content, ContentModel next) {
   80           this.type = type;
   81           this.content = content;
   82           this.next = next;
   83       }
   84   
   85       /**
   86        * Return true if the content model could
   87        * match an empty input stream.
   88        */
   89       public boolean empty() {
   90           switch (type) {
   91             case '*':
   92             case '?':
   93               return true;
   94   
   95             case '+':
   96             case '|':
   97               for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
   98                   if (m.empty()) {
   99                       return true;
  100                   }
  101               }
  102               return false;
  103   
  104             case ',':
  105             case '&':
  106               for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
  107                   if (!m.empty()) {
  108                       return false;
  109                   }
  110               }
  111               return true;
  112   
  113             default:
  114               return false;
  115           }
  116       }
  117   
  118       /**
  119        * Update elemVec with the list of elements that are
  120        * part of the this contentModel.
  121        */
  122        public void getElements(Vector<Element> elemVec) {
  123            switch (type) {
  124            case '*':
  125            case '?':
  126            case '+':
  127                ((ContentModel)content).getElements(elemVec);
  128                break;
  129            case ',':
  130            case '|':
  131            case '&':
  132                for (ContentModel m=(ContentModel)content; m != null; m=m.next){
  133                    m.getElements(elemVec);
  134                }
  135                break;
  136            default:
  137                elemVec.addElement((Element)content);
  138            }
  139        }
  140   
  141        private boolean valSet[];
  142        private boolean val[];
  143        // A cache used by first().  This cache was found to speed parsing
  144        // by about 10% (based on measurements of the 4-12 code base after
  145        // buffering was fixed).
  146   
  147       /**
  148        * Return true if the token could potentially be the
  149        * first token in the input stream.
  150        */
  151       public boolean first(Object token) {
  152           switch (type) {
  153             case '*':
  154             case '?':
  155             case '+':
  156               return ((ContentModel)content).first(token);
  157   
  158             case ',':
  159               for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
  160                   if (m.first(token)) {
  161                       return true;
  162                   }
  163                   if (!m.empty()) {
  164                       return false;
  165                   }
  166               }
  167               return false;
  168   
  169             case '|':
  170             case '&': {
  171               Element e = (Element) token;
  172               if (valSet == null) {
  173                   valSet = new boolean[Element.maxIndex + 1];
  174                   val = new boolean[Element.maxIndex + 1];
  175                   // All Element instances are created before this ever executes
  176               }
  177               if (valSet[e.index]) {
  178                   return val[e.index];
  179               }
  180               for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
  181                   if (m.first(token)) {
  182                       val[e.index] = true;
  183                       break;
  184                   }
  185               }
  186               valSet[e.index] = true;
  187               return val[e.index];
  188             }
  189   
  190             default:
  191               return (content == token);
  192               // PENDING: refer to comment in ContentModelState
  193   /*
  194                 if (content == token) {
  195                     return true;
  196                 }
  197                 Element e = (Element)content;
  198                 if (e.omitStart() && e.content != null) {
  199                     return e.content.first(token);
  200                 }
  201                 return false;
  202   */
  203           }
  204       }
  205   
  206       /**
  207        * Return the element that must be next.
  208        */
  209       public Element first() {
  210           switch (type) {
  211             case '&':
  212             case '|':
  213             case '*':
  214             case '?':
  215               return null;
  216   
  217             case '+':
  218             case ',':
  219               return ((ContentModel)content).first();
  220   
  221             default:
  222               return (Element)content;
  223           }
  224       }
  225   
  226       /**
  227        * Convert to a string.
  228        */
  229       public String toString() {
  230           switch (type) {
  231             case '*':
  232               return content + "*";
  233             case '?':
  234               return content + "?";
  235             case '+':
  236               return content + "+";
  237   
  238             case ',':
  239             case '|':
  240             case '&':
  241               char data[] = {' ', (char)type, ' '};
  242               String str = "";
  243               for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
  244                   str = str + m;
  245                   if (m.next != null) {
  246                       str += new String(data);
  247                   }
  248               }
  249               return "(" + str + ")";
  250   
  251             default:
  252               return content.toString();
  253           }
  254       }
  255   }

Save This Page
Home » openjdk-7 » javax » swing » text » html » parser » [javadoc | source]