1 17 package org.eclipse.emf.codegen.jet; 18 19 20 import java.io.CharArrayWriter ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.InputStreamReader ; 24 import java.io.UnsupportedEncodingException ; 25 import java.util.ArrayList ; 26 import java.util.HashMap ; 27 import java.util.List ; 28 29 import org.eclipse.emf.codegen.CodeGenPlugin; 30 31 32 37 public class JETReader 38 { 39 protected char startTagInitialChar = '<'; 40 protected char endTagInitialChar = '%'; 41 protected char endTagFinalChar = '>'; 42 protected JETMark current = null; 43 protected String master = null; 44 protected List sourceFiles = new ArrayList (); 45 protected List baseURIs = new ArrayList (); 46 protected int size = 0; 47 protected boolean trimExtraNewLine = true; 48 49 public JETReader(String baseURI, String locationURI, InputStream inputStream, String encoding) throws JETException 50 { 51 stackStream(baseURI, locationURI, inputStream, encoding); 52 } 53 54 public JETReader(String locationURI, InputStream inputStream, String encoding) throws JETException 55 { 56 this(null, locationURI, inputStream, encoding); 57 } 58 59 public String getFile(int fileid) 60 { 61 return (String ) sourceFiles.get(fileid); 62 } 63 64 public String getBaseURI(int fileid) 65 { 66 return (String ) baseURIs.get(fileid); 67 } 68 69 public void stackStream(String locationURI, InputStream iStream, String encoding) throws JETException 70 { 71 stackStream(null, locationURI, iStream, encoding); 72 } 73 74 79 public void stackStream(String baseURI, String locationURI, InputStream iStream, String encoding) throws JETException 80 { 81 InputStreamReader reader = null; 82 try 83 { 84 if (encoding == null) 87 { 88 encoding = "UTF8"; 89 } 90 91 int fileid = registerSourceFile(locationURI); 94 registerBaseURI(baseURI); 95 reader = new InputStreamReader (iStream, encoding); 96 CharArrayWriter writer = new CharArrayWriter (); 97 char buf[] = new char[1024]; 98 for (int i = 0; (i = reader.read(buf)) != -1; ) 99 { 100 if (buf[0] == '\uFEFF') 104 { 105 writer.write(buf, 1, i - 1); 106 } 107 else 108 { 109 writer.write(buf, 0, i); 110 } 111 } 112 writer.close(); 113 if (current == null) 114 { 115 current = new JETMark(this, writer.toCharArray(), fileid, locationURI, encoding); 116 } 117 else 118 { 119 current.pushStream(writer.toCharArray(), fileid, locationURI, encoding); 120 } 121 } 122 catch (UnsupportedEncodingException exception) 123 { 124 throw new JETException(exception); 125 } 126 catch (IOException exception) 127 { 128 throw new JETException(exception); 129 } 130 finally 131 { 132 if (reader != null) 133 { 134 try 135 { 136 reader.close(); 137 } 138 catch (Exception exception) 139 { 140 throw new JETException(exception); 141 } 142 } 143 } 144 } 145 146 public boolean popFile() 147 { 148 if (current == null) 151 { 152 return false; 153 } 154 155 size--; 158 159 return current.popStream(); 160 } 161 162 168 protected int registerSourceFile(String file) 169 { 170 sourceFiles.add(file); 171 ++this.size; 172 return sourceFiles.size() - 1; 173 } 174 175 181 protected void registerBaseURI(String baseURI) 182 { 183 baseURIs.add(baseURI); 184 } 185 186 193 public boolean hasMoreInput() 194 { 195 if (current.cursor < current.stream.length) 196 { 197 return true; 198 } 199 200 boolean nl = hasTrailingNewLine(); 201 while (popFile()) 202 { 203 if (current.cursor < current.stream.length) 204 { 205 if (trimExtraNewLine && nl) 206 { 207 skipNewLine(); 208 } 209 return true; 210 } 211 } 212 return false; 213 } 214 215 218 protected boolean hasTrailingNewLine() 219 { 220 char[] stream = current.stream; 221 222 for (int i = stream.length - 1; i >= 0; i--) 223 { 224 if (stream[i] == '\n' || stream[i] == '\r') 225 { 226 return true; 227 } 228 else if (stream[i] != ' ') 229 { 230 return false; 231 } 232 } 233 return false; 234 } 235 236 239 protected void skipNewLine() 240 { 241 char[] stream = current.stream; 242 int c = current.cursor; 243 244 if (stream.length > c + 1 && (stream[c] == '\n' && stream[c + 1] == '\r' || stream[c] == '\r' && stream[c + 1] == '\n')) 245 { 246 current.cursor += 2; 247 current.line++; 248 current.col = stream[0] == '\n' ? 1 : 0; 249 } 250 else if (stream.length > c && (stream[c] == '\n' || stream[c] == '\r')) 251 { 252 current.cursor++; 253 current.line++; 254 current.col = 0; 255 } 256 } 257 258 public int nextChar() 259 { 260 if (!hasMoreInput()) 261 { 262 return -1; 263 } 264 265 int ch = current.stream[current.cursor]; 266 267 ++current.cursor; 268 269 if (ch == '\n') 270 { 271 ++current.line; 272 current.col = 0; 273 } 274 else 275 { 276 ++current.col; 277 } 278 return ch; 279 } 280 281 285 public String nextContent() 286 { 287 int cur_cursor = current.cursor; 288 int len = current.stream.length; 289 if (cur_cursor == len) return ""; 290 char ch; 291 292 while (++current.cursor < len && (ch = current.stream[current.cursor]) != startTagInitialChar) 294 { 295 if (ch == '\n') 296 { 297 ++current.line; 298 current.col = 0; 299 } 300 else 301 { 302 ++current.col; 303 } 304 } 305 306 return new String (current.stream, cur_cursor, current.cursor-cur_cursor); 307 } 308 309 public char[] getChars(JETMark start, JETMark stop) 310 { 311 JETMark oldstart = mark(); 312 reset(start); 313 CharArrayWriter writer = new CharArrayWriter (); 314 while (!stop.equals(mark())) 315 { 316 writer.write(nextChar()); 317 } 318 writer.close(); 319 reset(oldstart); 320 return writer.toCharArray(); 321 } 322 323 public int peekChar() 324 { 325 return current.stream[current.cursor]; 326 } 327 328 public JETMark mark() 329 { 330 return new JETMark(current); 331 } 332 333 public void reset(JETMark mark) 334 { 335 current = new JETMark(mark); 336 } 337 338 public boolean matchesIgnoreCase(String string) 339 { 340 JETMark mark = mark(); 341 int ch = 0; 342 int i = 0; 343 do 344 { 345 ch = nextChar(); 346 if (Character.toLowerCase((char) ch) != string.charAt(i++)) 347 { 348 reset(mark); 349 return false; 350 } 351 } while (i < string.length()); 352 reset(mark); 353 return true; 354 } 355 356 public boolean matches(String string) 357 { 358 JETMark mark = mark(); 359 int ch = 0; 360 int i = 0; 361 do 362 { 363 ch = nextChar(); 364 if (((char) ch) != string.charAt(i++)) 365 { 366 reset(mark); 367 return false; 368 } 369 } while (i < string.length()); 370 reset(mark); 371 return true; 372 } 373 374 public void advance(int n) 375 { 376 while (--n >= 0) 377 nextChar(); 378 } 379 380 public int skipSpaces() 381 { 382 int i = 0; 383 while (isSpace()) 384 { 385 ++i; 386 nextChar(); 387 } 388 return i; 389 } 390 391 398 public JETMark skipUntil(String limit) 399 { 400 JETMark ret = null; 401 int limlen = limit.length(); 402 int ch; 403 404 skip: 405 for (ret = mark(), ch = nextChar(); ch != -1; ret = mark(), ch = nextChar()) 406 { 407 if (ch == limit.charAt(0)) 408 { 409 for (int i = 1; i < limlen; i++) 410 { 411 if (Character.toLowerCase((char) nextChar()) != limit.charAt(i)) 412 { 413 continue skip; 414 } 415 } 416 return ret; 417 } 418 } 419 return null; 420 } 421 422 protected boolean isSpace() 423 { 424 return peekChar() <= ' '; 425 } 426 427 433 public String parseToken(boolean quoted) throws JETException 434 { 435 StringBuffer stringBuffer = new StringBuffer (); 436 skipSpaces(); 437 stringBuffer.setLength(0); 438 439 int ch = peekChar(); 440 441 if (quoted) 442 { 443 if (ch == '"' || ch == '\'') 444 { 445 char endQuote = ch == '"' ? '"' : '\''; 446 447 ch = nextChar(); 450 for (ch = nextChar(); ch != -1 && ch != endQuote; ch = nextChar()) 451 { 452 if (ch == '\\') 453 { 454 ch = nextChar(); 455 } 456 stringBuffer.append((char) ch); 457 } 458 459 if (ch == -1) 462 { 463 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.quotes.unterminated", new Object [] { mark().toString()})); 464 } 465 } 466 else 467 { 468 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.attr.quoted", new Object [] { mark().toString() })); 469 } 470 } 471 else 472 { 473 if (!isDelimiter()) 474 { 475 do 477 { 478 ch = nextChar(); 479 if (ch == '\\') 481 { 482 if (peekChar() == '"' || peekChar() == '\'' || peekChar() == endTagFinalChar || peekChar() == endTagInitialChar) 483 { 484 ch = nextChar(); 485 } 486 } 487 stringBuffer.append((char) ch); 488 } 489 while (!isDelimiter()); 490 } 491 } 492 return stringBuffer.toString(); 493 } 494 495 507 protected void parseAttributeValue(HashMap into) throws JETException 508 { 509 skipSpaces(); 512 String name = parseToken(false); 513 514 skipSpaces(); 517 if (peekChar() != '=') 518 { 519 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.attr.novalue", new Object [] { name, mark().toString() })); 520 } 521 nextChar(); 522 523 skipSpaces(); 526 String value = parseToken(true); 527 skipSpaces(); 528 529 into.put(name, value); 532 } 533 534 547 public HashMap parseTagAttributesBean() throws JETException 548 { 549 HashMap values = new HashMap (11); 550 while (true) 551 { 552 skipSpaces(); 553 int ch = peekChar(); 554 if (ch == endTagFinalChar) 555 { 556 return values; 559 } 560 else if (ch == '/') 561 { 562 JETMark mark = mark(); 563 nextChar(); 564 565 try 568 { 569 if (nextChar() == endTagFinalChar) 570 { 571 return values; 572 } 573 } 574 finally 575 { 576 reset(mark); 577 } 578 } 579 if (ch == -1) 580 { 581 break; 582 } 583 584 parseAttributeValue(values); 587 } 588 589 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.tag.attr.unterminated", new Object [] { mark().toString() })); 592 } 593 594 607 public HashMap parseTagAttributes() 608 throws JETException 609 { 610 HashMap values = new HashMap (11); 611 while (true) 612 { 613 skipSpaces(); 614 int ch = peekChar(); 615 if (ch == endTagFinalChar) 616 { 617 return values; 618 } 619 620 if (ch == '-') 621 { 622 JETMark mark = mark(); 623 nextChar(); 624 try 626 { 627 if (nextChar() == '-' && nextChar() == endTagFinalChar) 628 { 629 return values; 630 } 631 } 632 finally 633 { 634 reset(mark); 635 } 636 } 637 else if (ch == endTagInitialChar) 638 { 639 JETMark mark = mark(); 640 nextChar(); 641 try 643 { 644 if (nextChar() == endTagFinalChar) 645 { 646 return values; 647 } 648 } 649 finally 650 { 651 reset(mark); 652 } 653 } 654 else if (ch == '/') 655 { 656 JETMark mark = mark(); 657 nextChar(); 658 try 660 { 661 if (nextChar() == endTagFinalChar) 662 { 663 return values; 664 } 665 } 666 finally 667 { 668 reset(mark); 669 } 670 } 671 if (ch == -1) 672 { 673 break; 674 } 675 parseAttributeValue(values); 677 } 678 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.tag.attr.unterminated", new Object [] { mark().toString() })); 680 } 681 682 688 protected boolean isDelimiter() 689 { 690 if (! isSpace()) 691 { 692 int ch = peekChar(); 693 694 if (ch == '=' || ch == endTagFinalChar || ch == '"' || ch == '\'' || ch == '/') 697 { 698 return true; 699 } 700 701 if (ch == '-') 704 { 705 JETMark mark = mark(); 706 if (((ch = nextChar()) == endTagFinalChar) || ((ch == '-') && (nextChar() == endTagFinalChar))) 707 { 708 reset(mark); 709 return true; 710 } 711 else 712 { 713 reset(mark); 714 return false; 715 } 716 } 717 return false; 718 } 719 else 720 { 721 return true; 722 } 723 } 724 725 public void setStartTag(String startTag) 726 { 727 startTagInitialChar = startTag.charAt(0); 728 } 729 730 public void setEndTag(String endTag) 731 { 732 endTagFinalChar = endTag.charAt(endTag.length() - 1); 733 endTagInitialChar = endTag.charAt(0); 734 } 735 } 736 | Popular Tags |