1 /* 2 3 Licensed to the Apache Software Foundation (ASF) under one or more 4 contributor license agreements. See the NOTICE file distributed with 5 this work for additional information regarding copyright ownership. 6 The ASF licenses this file to You under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with 8 the License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 18 */ 19 package com.mxgraph.util.svg; 20 21 import java.io.IOException; 22 import java.util.MissingResourceException; 23 24 /** 25 * This class is the superclass of all parsers. It provides localization 26 * and error handling methods. 27 * 28 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a> 29 */ 30 public abstract class AbstractParser implements Parser 31 { 32 33 /** 34 * The default resource bundle base name. 35 */ 36 public static final String BUNDLE_CLASSNAME = "org.apache.batik.parser.resources.Messages"; 37 38 /** 39 * The error handler. 40 */ 41 protected ErrorHandler errorHandler = new DefaultErrorHandler(); 42 43 /** 44 * The normalizing reader. 45 */ 46 protected NormalizingReader reader; 47 48 /** 49 * The current character. 50 */ 51 protected int current; 52 53 /** 54 * Returns the current character value. 55 */ getCurrent()56 public int getCurrent() 57 { 58 return current; 59 } 60 61 /** 62 * Allow an application to register an error event handler. 63 * 64 * <p>If the application does not register an error event handler, 65 * all error events reported by the parser will cause an exception 66 * to be thrown. 67 * 68 * <p>Applications may register a new or different handler in the 69 * middle of a parse, and the parser must begin using the new 70 * handler immediately.</p> 71 * @param handler The error handler. 72 */ setErrorHandler(ErrorHandler handler)73 public void setErrorHandler(ErrorHandler handler) 74 { 75 errorHandler = handler; 76 } 77 78 /** 79 * Parses the given string. 80 */ parse(String s)81 public void parse(String s) throws ParseException 82 { 83 try 84 { 85 reader = new StringNormalizingReader(s); 86 doParse(); 87 } 88 catch (IOException e) 89 { 90 errorHandler.error(new ParseException(createErrorMessage( 91 "io.exception", null), e)); 92 } 93 } 94 95 /** 96 * Method responsible for actually parsing data after AbstractParser 97 * has initialized itself. 98 */ doParse()99 protected abstract void doParse() throws ParseException, IOException; 100 101 /** 102 * Signals an error to the error handler. 103 * @param key The message key in the resource bundle. 104 * @param args The message arguments. 105 */ reportError(String key, Object[] args)106 protected void reportError(String key, Object[] args) throws ParseException 107 { 108 errorHandler.error(new ParseException(createErrorMessage(key, args), 109 reader.getLine(), reader.getColumn())); 110 } 111 112 /** 113 * simple api to call often reported error. 114 * Just a wrapper for reportError(). 115 * 116 * @param expectedChar what caller expected 117 * @param currentChar what caller found 118 */ reportCharacterExpectedError(char expectedChar, int currentChar)119 protected void reportCharacterExpectedError(char expectedChar, 120 int currentChar) 121 { 122 reportError("character.expected", new Object[] { 123 new Character(expectedChar), new Integer(currentChar) }); 124 125 } 126 127 /** 128 * simple api to call often reported error. 129 * Just a wrapper for reportError(). 130 * 131 * @param currentChar what the caller found and didnt expect 132 */ reportUnexpectedCharacterError(int currentChar)133 protected void reportUnexpectedCharacterError(int currentChar) 134 { 135 reportError("character.unexpected", new Object[] { new Integer( 136 currentChar) }); 137 138 } 139 140 /** 141 * Returns a localized error message. 142 * @param key The message key in the resource bundle. 143 * @param args The message arguments. 144 */ createErrorMessage(String key, Object[] args)145 protected String createErrorMessage(String key, Object[] args) 146 { 147 try 148 { 149 // TODO Replace with mx localisation 150 // return formatMessage(key, args); 151 return ""; 152 } 153 catch (MissingResourceException e) 154 { 155 return key; 156 } 157 } 158 159 /** 160 * Returns the resource bundle base name. 161 * @return BUNDLE_CLASSNAME. 162 */ getBundleClassName()163 protected String getBundleClassName() 164 { 165 return BUNDLE_CLASSNAME; 166 } 167 168 /** 169 * Skips the whitespaces in the current reader. 170 */ skipSpaces()171 protected void skipSpaces() throws IOException 172 { 173 for (;;) 174 { 175 switch (current) 176 { 177 default: 178 return; 179 case 0x20: 180 case 0x09: 181 case 0x0D: 182 case 0x0A: 183 } 184 current = reader.read(); 185 } 186 } 187 188 /** 189 * Skips the whitespaces and an optional comma. 190 */ skipCommaSpaces()191 protected void skipCommaSpaces() throws IOException 192 { 193 wsp1: for (;;) 194 { 195 switch (current) 196 { 197 default: 198 break wsp1; 199 case 0x20: 200 case 0x9: 201 case 0xD: 202 case 0xA: 203 } 204 current = reader.read(); 205 } 206 if (current == ',') 207 { 208 wsp2: for (;;) 209 { 210 switch (current = reader.read()) 211 { 212 default: 213 break wsp2; 214 case 0x20: 215 case 0x9: 216 case 0xD: 217 case 0xA: 218 } 219 } 220 } 221 } 222 } 223