Coverage Report - org.apache.tapestry.json.XMLTokener
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLTokener
0%
0/85
0%
0/76
18.2
 
 1  
 package org.apache.tapestry.json;
 2  
 
 3  
 /*
 4  
 Copyright (c) 2002 JSON.org
 5  
 
 6  
 Permission is hereby granted, free of charge, to any person obtaining a copy
 7  
 of this software and associated documentation files (the "Software"), to deal
 8  
 in the Software without restriction, including without limitation the rights
 9  
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  
 copies of the Software, and to permit persons to whom the Software is
 11  
 furnished to do so, subject to the following conditions:
 12  
 
 13  
 The above copyright notice and this permission notice shall be included in all
 14  
 copies or substantial portions of the Software.
 15  
 
 16  
 The Software shall be used for Good, not Evil.
 17  
 
 18  
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 24  
 SOFTWARE.
 25  
 */
 26  
 
 27  
 import java.text.ParseException;
 28  
 
 29  
 /**
 30  
  * The XMLTokener extends the JSONTokener to provide additional methods
 31  
  * for the parsing of XML texts.
 32  
  * @author JSON.org
 33  
  * @version 0.1
 34  
  */
 35  
 public class XMLTokener extends JSONTokener {
 36  
 
 37  
 
 38  
    /** The table of entity values. It initially contains Character values for
 39  
     * amp, apos, gt, lt, quot.
 40  
     */
 41  
    public static final java.util.HashMap entity;
 42  
 
 43  
    static {
 44  0
        entity = new java.util.HashMap(8);
 45  0
        entity.put("amp",  XML.AMP);
 46  0
        entity.put("apos", XML.APOS);
 47  0
        entity.put("gt",   XML.GT);
 48  0
        entity.put("lt",   XML.LT);
 49  0
        entity.put("quot", XML.QUOT);
 50  0
    }
 51  
 
 52  
     /**
 53  
      * Construct an XMLTokener from a string.
 54  
      * @param s A source string.
 55  
      */
 56  
     public XMLTokener(String s) {
 57  0
         super(s);
 58  0
     }
 59  
 
 60  
 
 61  
     /**
 62  
      * Get the next XML outer token, trimming whitespace. There are two kinds
 63  
      * of tokens: the '<' character which begins a markup tag, and the content
 64  
      * text between markup tags.
 65  
      *
 66  
      * @return  A string, or a '<' Character, or null if there is no more
 67  
      * source text.
 68  
      * @throws ParseException
 69  
      */
 70  
     public Object nextContent() throws ParseException {
 71  
         char         c;
 72  
         StringBuffer sb;
 73  
         do {
 74  0
             c = next();
 75  0
         } while (Character.isWhitespace(c));
 76  0
         if (c == 0) {
 77  0
             return null;
 78  
         }
 79  0
         if (c == '<') {
 80  0
             return XML.LT;
 81  
         }
 82  0
         sb = new StringBuffer();
 83  
         while (true) {
 84  0
             if (c == '<' || c == 0) {
 85  0
                 back();
 86  0
                 return sb.toString().trim();
 87  
             }
 88  0
             if (c == '&') {
 89  0
                 sb.append(nextEntity(c));
 90  
             } else {
 91  0
                 sb.append(c);
 92  
             }
 93  0
             c = next();
 94  
         }
 95  
     }
 96  
 
 97  
 
 98  
     /**
 99  
      * Return the next entity. These entities are translated to Characters:
 100  
      *     &amp;  &apos;  &gt;  &lt;  &quot;
 101  
      * @param a An ampersand character.
 102  
      * @return  A Character or an entity String if the entity is not recognized.
 103  
      * @throws ParseException Missing ';' in XML entity
 104  
      */
 105  
     public Object nextEntity(char a) throws ParseException {
 106  0
         StringBuffer sb = new StringBuffer();
 107  
         while (true) {
 108  0
             char c = next();
 109  0
             if (Character.isLetter(c)) {
 110  0
                 sb.append(Character.toLowerCase(c));
 111  0
             } else if (c == ';') {
 112  0
                 break;
 113  
             } else {
 114  0
                 throw syntaxError("Missing ';' in XML entity: &" + sb);
 115  
             }
 116  0
         }
 117  0
         String s = sb.toString();
 118  0
         Object e = entity.get(s);
 119  0
         return e != null ? e : a + s + ";";
 120  
     }
 121  
 
 122  
 
 123  
     /**
 124  
      * Returns the next XML meta token. This is used for skipping over <!...>
 125  
      * and <?...?> structures.
 126  
      * @return Syntax characters (< > / = ! ?) are returned as Character, and
 127  
      * strings and names are returned as Boolean. We don't care what the
 128  
      * values actually are.
 129  
      * @throws ParseException
 130  
      */
 131  
     public Object nextMeta() throws ParseException {
 132  
         char c;
 133  
         char q;
 134  
         do {
 135  0
             c = next();
 136  0
         } while (Character.isWhitespace(c));
 137  0
         switch (c) {
 138  
         case 0:
 139  0
             throw syntaxError("Misshaped meta tag.");
 140  
         case '<':
 141  0
             return XML.LT;
 142  
         case '>':
 143  0
             return XML.GT;
 144  
         case '/':
 145  0
             return XML.SLASH;
 146  
         case '=':
 147  0
             return XML.EQ;
 148  
         case '!':
 149  0
             return XML.BANG;
 150  
         case '?':
 151  0
             return XML.QUEST;
 152  
         case '"':
 153  
         case '\'':
 154  0
             q = c;
 155  
             while (true) {
 156  0
                 c = next();
 157  0
                 if (c == 0) {
 158  0
                     throw syntaxError("Unterminated string.");
 159  
                 }
 160  0
                 if (c == q) {
 161  0
                     return Boolean.TRUE;
 162  
                 }
 163  
             }
 164  
         default:
 165  
             while (true) {
 166  0
                 c = next();
 167  0
                 if (Character.isWhitespace(c)) {
 168  0
                     return Boolean.TRUE;
 169  
                 }
 170  0
                 switch (c) {
 171  
                 case 0:
 172  
                 case '<':
 173  
                 case '>':
 174  
                 case '/':
 175  
                 case '=':
 176  
                 case '!':
 177  
                 case '?':
 178  
                 case '"':
 179  
                 case '\'':
 180  0
                     back();
 181  0
                     return Boolean.TRUE;
 182  
                 }
 183  
             }
 184  
         }
 185  
     }
 186  
 
 187  
 
 188  
     /**
 189  
      * Get the next XML Token. These tokens are found inside of angle
 190  
      * brackets. It may be one of these characters: / > = ! ? or it may be a
 191  
      * string wrapped in single quotes or double quotes, or it may be a name.
 192  
      * @return a String or a Character.
 193  
      * @throws ParseException
 194  
      */
 195  
     public Object nextToken() throws ParseException {
 196  
         char c;
 197  
         char q;
 198  
         StringBuffer sb;
 199  
         do {
 200  0
             c = next();
 201  0
         } while (Character.isWhitespace(c));
 202  0
         switch (c) {
 203  
         case 0:
 204  0
             throw syntaxError("Misshaped element.");
 205  
         case '<':
 206  0
             throw syntaxError("Misplaced '<'.");
 207  
         case '>':
 208  0
             return XML.GT;
 209  
         case '/':
 210  0
             return XML.SLASH;
 211  
         case '=':
 212  0
             return XML.EQ;
 213  
         case '!':
 214  0
             return XML.BANG;
 215  
         case '?':
 216  0
             return XML.QUEST;
 217  
 
 218  
 // Quoted string
 219  
 
 220  
         case '"':
 221  
         case '\'':
 222  0
             q = c;
 223  0
             sb = new StringBuffer();
 224  
             while (true) {
 225  0
                 c = next();
 226  0
                 if (c == 0) {
 227  0
                     throw syntaxError("Unterminated string.");
 228  
                 }
 229  0
                 if (c == q) {
 230  0
                     return sb.toString();
 231  
                 }
 232  0
                 if (c == '&') {
 233  0
                     sb.append(nextEntity(c));
 234  
                 } else {
 235  0
                     sb.append(c);
 236  
                 }
 237  
             }
 238  
         default:
 239  
 
 240  
 // Name
 241  
 
 242  0
             sb = new StringBuffer();
 243  
             while (true) {
 244  0
                 sb.append(c);
 245  0
                 c = next();
 246  0
                 if (Character.isWhitespace(c)) {
 247  0
                     return sb.toString();
 248  
                 }
 249  0
                 switch (c) {
 250  
                 case 0:
 251  
                 case '>':
 252  
                 case '/':
 253  
                 case '=':
 254  
                 case '!':
 255  
                 case '?':
 256  0
                     back();
 257  0
                     return sb.toString();
 258  
                 case '<':
 259  
                 case '"':
 260  
                 case '\'':
 261  0
                     throw syntaxError("Bad character in a name.");
 262  
                 }
 263  
             }
 264  
         }
 265  
     }
 266  
 }