1 51 package org.apache.fop.layout.hyphenation; 52 53 import org.xml.sax.XMLReader ; 55 import org.xml.sax.InputSource ; 56 import org.xml.sax.SAXException ; 57 import org.xml.sax.SAXParseException ; 58 import org.xml.sax.helpers.DefaultHandler ; 59 import org.xml.sax.Attributes ; 60 61 import java.io.File ; 63 import java.io.IOException ; 64 import java.util.ArrayList ; 65 import java.net.URL ; 66 67 73 public class PatternParser extends DefaultHandler implements PatternConsumer { 74 75 XMLReader parser; 76 int currElement; 77 PatternConsumer consumer; 78 StringBuffer token; 79 ArrayList exception; 80 char hyphenChar; 81 String errMsg; 82 83 static final int ELEM_CLASSES = 1; 84 static final int ELEM_EXCEPTIONS = 2; 85 static final int ELEM_PATTERNS = 3; 86 static final int ELEM_HYPHEN = 4; 87 88 public PatternParser() throws HyphenationException { 89 token = new StringBuffer (); 90 parser = createParser(); 91 parser.setContentHandler(this); 92 parser.setErrorHandler(this); 93 hyphenChar = '-'; 95 } 96 97 public PatternParser(PatternConsumer consumer) 98 throws HyphenationException { 99 this(); 100 this.consumer = consumer; 101 } 102 103 public void setConsumer(PatternConsumer consumer) { 104 this.consumer = consumer; 105 } 106 107 public void parse(String filename) throws HyphenationException { 108 InputSource uri = fileInputSource(filename); 109 110 try { 111 parser.parse(uri); 112 } catch (SAXException e) { 113 throw new HyphenationException(errMsg); 114 } catch (IOException e) { 115 throw new HyphenationException(e.getMessage()); 116 } catch (NullPointerException e) { 117 throw new HyphenationException("SAX parser not available"); 118 } 119 } 120 121 127 static XMLReader createParser() throws HyphenationException { 128 String parserClassName = System.getProperty("org.xml.sax.parser"); 129 if (parserClassName == null) { 130 parserClassName = "org.apache.xerces.parsers.SAXParser"; 131 } 132 134 try { 135 return (XMLReader )Class.forName(parserClassName).newInstance(); 136 } catch (ClassNotFoundException e) { 137 throw new HyphenationException("Could not find " 138 + parserClassName); 139 } catch (InstantiationException e) { 140 throw new HyphenationException("Could not instantiate " 141 + parserClassName); 142 } catch (IllegalAccessException e) { 143 throw new HyphenationException("Could not access " 144 + parserClassName); 145 } catch (ClassCastException e) { 146 throw new HyphenationException(parserClassName 147 + " is not a SAX driver"); 148 } 149 } 150 151 157 protected static InputSource fileInputSource(String filename) 158 throws HyphenationException { 159 160 161 File file = new File (filename); 162 String path = file.getAbsolutePath(); 163 String fSep = System.getProperty("file.separator"); 164 if (fSep != null && fSep.length() == 1) 165 path = path.replace(fSep.charAt(0), '/'); 166 if (path.length() > 0 && path.charAt(0) != '/') 167 path = '/' + path; 168 try { 169 return new InputSource (new URL ("file", null, path).toString()); 170 } catch (java.net.MalformedURLException e) { 171 throw new HyphenationException("unexpected MalformedURLException"); 172 } 173 } 174 175 protected String readToken(StringBuffer chars) { 176 String word; 177 boolean space = false; 178 int i; 179 for (i = 0; i < chars.length(); i++) 180 if (Character.isWhitespace(chars.charAt(i))) 181 space = true; 182 else 183 break; 184 if (space) { 185 for (int countr = i; countr < chars.length(); countr++) 187 chars.setCharAt(countr - i, chars.charAt(countr)); 188 chars.setLength(chars.length() - i); 189 if (token.length() > 0) { 190 word = token.toString(); 191 token.setLength(0); 192 return word; 193 } 194 } 195 space = false; 196 for (i = 0; i < chars.length(); i++) { 197 if (Character.isWhitespace(chars.charAt(i))) { 198 space = true; 199 break; 200 } 201 } 202 token.append(chars.toString().substring(0, i)); 203 for (int countr = i; countr < chars.length(); countr++) 205 chars.setCharAt(countr - i, chars.charAt(countr)); 206 chars.setLength(chars.length() - i); 207 if (space) { 208 word = token.toString(); 209 token.setLength(0); 210 return word; 211 } 212 token.append(chars); 213 return null; 214 } 215 216 protected static String getPattern(String word) { 217 StringBuffer pat = new StringBuffer (); 218 int len = word.length(); 219 for (int i = 0; i < len; i++) 220 if (!Character.isDigit(word.charAt(i))) 221 pat.append(word.charAt(i)); 222 return pat.toString(); 223 } 224 225 protected ArrayList normalizeException(ArrayList ex) { 226 ArrayList res = new ArrayList (); 227 for (int i = 0; i < ex.size(); i++) { 228 Object item = ex.get(i); 229 if (item instanceof String ) { 230 String str = (String )item; 231 StringBuffer buf = new StringBuffer (); 232 for (int j = 0; j < str.length(); j++) { 233 char c = str.charAt(j); 234 if (c != hyphenChar) 235 buf.append(c); 236 else { 237 res.add(buf.toString()); 238 buf.setLength(0); 239 char[] h = new char[1]; 240 h[0] = hyphenChar; 241 res.add(new Hyphen(new String (h), null, null)); 244 } 245 } 246 if (buf.length() > 0) 247 res.add(buf.toString()); 248 } else 249 res.add(item); 250 } 251 return res; 252 } 253 254 protected String getExceptionWord(ArrayList ex) { 255 StringBuffer res = new StringBuffer (); 256 for (int i = 0; i < ex.size(); i++) { 257 Object item = ex.get(i); 258 if (item instanceof String ) 259 res.append((String )item); 260 else { 261 if (((Hyphen)item).noBreak != null) 262 res.append(((Hyphen)item).noBreak); 263 } 264 } 265 return res.toString(); 266 } 267 268 protected static String getInterletterValues(String pat) { 269 StringBuffer il = new StringBuffer (); 270 String word = pat + "a"; int len = word.length(); 272 for (int i = 0; i < len; i++) { 273 char c = word.charAt(i); 274 if (Character.isDigit(c)) { 275 il.append(c); 276 i++; 277 } else 278 il.append('0'); 279 } 280 return il.toString(); 281 } 282 283 287 290 public void startElement(String uri, String local, String raw, 291 Attributes attrs) { 292 if (local.equals("hyphen-char")) { 293 String h = attrs.getValue("value"); 294 if (h != null && h.length() == 1) 295 hyphenChar = h.charAt(0); 296 } else if (local.equals("classes")) 297 currElement = ELEM_CLASSES; 298 else if (local.equals("patterns")) 299 currElement = ELEM_PATTERNS; 300 else if (local.equals("exceptions")) { 301 currElement = ELEM_EXCEPTIONS; 302 exception = new ArrayList (); 303 } else if (local.equals("hyphen")) { 304 if (token.length() > 0) { 305 exception.add(token.toString()); 306 } 307 exception.add(new Hyphen(attrs.getValue("pre"), 308 attrs.getValue("no"), 309 attrs.getValue("post"))); 310 currElement = ELEM_HYPHEN; 311 } 312 token.setLength(0); 313 } 314 315 public void endElement(String uri, String local, String raw) { 316 317 if (token.length() > 0) { 318 String word = token.toString(); 319 switch (currElement) { 320 case ELEM_CLASSES: 321 consumer.addClass(word); 322 break; 323 case ELEM_EXCEPTIONS: 324 exception.add(word); 325 exception = normalizeException(exception); 326 consumer.addException(getExceptionWord(exception), 327 (ArrayList )exception.clone()); 328 break; 329 case ELEM_PATTERNS: 330 consumer.addPattern(getPattern(word), 331 getInterletterValues(word)); 332 break; 333 case ELEM_HYPHEN: 334 break; 336 } 337 if (currElement != ELEM_HYPHEN) 338 token.setLength(0); 339 } 340 if (currElement == ELEM_HYPHEN) 341 currElement = ELEM_EXCEPTIONS; 342 else 343 currElement = 0; 344 345 } 346 347 350 public void characters(char ch[], int start, int length) { 351 StringBuffer chars = new StringBuffer (length); 352 chars.append(ch, start, length); 353 String word = readToken(chars); 354 while (word != null) { 355 switch (currElement) { 357 case ELEM_CLASSES: 358 consumer.addClass(word); 359 break; 360 case ELEM_EXCEPTIONS: 361 exception.add(word); 362 exception = normalizeException(exception); 363 consumer.addException(getExceptionWord(exception), 364 (ArrayList )exception.clone()); 365 exception.clear(); 366 break; 367 case ELEM_PATTERNS: 368 consumer.addPattern(getPattern(word), 369 getInterletterValues(word)); 370 break; 371 } 372 word = readToken(chars); 373 } 374 375 } 376 377 381 384 public void warning(SAXParseException ex) { 385 errMsg = "[Warning] " + getLocationString(ex) + ": " 386 + ex.getMessage(); 387 } 388 389 392 public void error(SAXParseException ex) { 393 errMsg = "[Error] " + getLocationString(ex) + ": " + ex.getMessage(); 394 } 395 396 399 public void fatalError(SAXParseException ex) throws SAXException { 400 errMsg = "[Fatal Error] " + getLocationString(ex) + ": " 401 + ex.getMessage(); 402 throw ex; 403 } 404 405 408 private String getLocationString(SAXParseException ex) { 409 StringBuffer str = new StringBuffer (); 410 411 String systemId = ex.getSystemId(); 412 if (systemId != null) { 413 int index = systemId.lastIndexOf('/'); 414 if (index != -1) 415 systemId = systemId.substring(index + 1); 416 str.append(systemId); 417 } 418 str.append(':'); 419 str.append(ex.getLineNumber()); 420 str.append(':'); 421 str.append(ex.getColumnNumber()); 422 423 return str.toString(); 424 425 } 427 428 public void addClass(String c) { 430 System.out.println("class: " + c); 431 } 432 433 public void addException(String w, ArrayList e) { 434 System.out.println("exception: " + w + " : " + e.toString()); 435 } 436 437 public void addPattern(String p, String v) { 438 System.out.println("pattern: " + p + " : " + v); 439 } 440 441 public static void main(String [] args) throws Exception { 442 if (args.length > 0) { 443 PatternParser pp = new PatternParser(); 444 pp.setConsumer(pp); 445 pp.parse(args[0]); 446 } 447 } 448 449 } 450 | Popular Tags |