1 69 package org.eclipse.emf.codegen.jet; 70 71 72 import java.io.CharArrayWriter ; 73 import java.io.IOException ; 74 import java.util.ArrayList ; 75 import java.util.Collection ; 76 import java.util.Iterator ; 77 import java.util.List ; 78 import java.util.Map ; 79 80 import org.eclipse.emf.codegen.CodeGenPlugin; 81 82 83 96 public class JETParser 97 { 98 public interface Action 99 { 100 void execute() throws JETException; 101 } 102 103 public static class DelegatingListener implements JETParseEventListener 104 { 105 protected JETParseEventListener delegate; 106 protected JETParser.Action action; 107 108 public DelegatingListener(JETParseEventListener delegate, JETParser.Action action) 109 { 110 this.delegate = delegate; 111 this.action = action; 112 } 113 114 public void doAction() throws JETException 115 { 116 action.execute(); 117 } 118 119 public void beginPageProcessing() throws JETException 120 { 121 delegate.beginPageProcessing(); 122 } 123 124 public void endPageProcessing() throws JETException 125 { 126 delegate.endPageProcessing(); 127 } 128 129 public void handleDirective(String directive, JETMark start, JETMark stop, Map attrs) 130 throws JETException 131 { 132 doAction(); 133 delegate.handleDirective(directive, start, stop, attrs); 134 } 135 136 public void handleScriptlet(JETMark start, JETMark stop, Map attrs) throws JETException 137 { 138 doAction(); 139 delegate.handleScriptlet(start, stop, attrs); 140 } 141 142 public void handleExpression(JETMark start, JETMark stop, Map attrs) throws JETException 143 { 144 doAction(); 145 delegate.handleExpression(start, stop, attrs); 146 } 147 148 public void handleCharData(char[] chars) throws JETException 149 { 150 delegate.handleCharData(chars); 151 } 152 } 153 154 157 protected JETReader reader; 158 159 162 protected JETParseEventListener listener; 163 164 167 protected CharArrayWriter writer; 168 169 protected List coreElements = new ArrayList (); 170 171 protected String openDirective = "<%@"; 172 protected String closeDirective = "%>"; 173 174 protected String openScriptlet = "<%"; 175 protected String closeScriptlet = "%>"; 176 177 protected String openExpr = "<%="; 178 protected String closeExpr = "%>"; 179 180 protected String quotedStartTag = "<\\%"; 181 protected String quotedEndTag = "%\\>"; 182 protected String startTag = "<%"; 183 protected String endTag = "%>"; 184 185 public JETParser(JETReader reader, final JETParseEventListener parseEventListener, JETCoreElement[] coreElements) 186 { 187 this.reader = reader; 188 this.listener = 189 new DelegatingListener 190 (parseEventListener, 191 new Action() 192 { 193 public void execute() throws JETException 194 { 195 JETParser.this.flushCharData(); 196 } 197 }); 198 199 this.writer = new CharArrayWriter (); 200 201 for (int i = 0; i < coreElements.length; i++) 202 { 203 this.coreElements.add(coreElements[i]); 204 } 205 } 206 207 public JETReader getReader() 208 { 209 return reader; 210 } 211 212 public void setStartTag(String tag) 213 { 214 openScriptlet = tag; 215 openExpr = tag + "="; 216 openDirective = tag + "@"; 217 quotedStartTag = tag.charAt(0) + "\\" + tag.charAt(1); 218 startTag = tag; 219 reader.setStartTag(tag); 220 } 221 222 public void setEndTag(String tag) 223 { 224 closeScriptlet = tag; 225 closeExpr = tag; 226 closeDirective = tag; 227 quotedEndTag = tag.charAt(0) + "\\" + tag.charAt(1); 228 endTag = tag; 229 reader.setEndTag(tag); 230 } 231 232 public String getOpenScriptlet() 233 { 234 return openScriptlet; 235 } 236 237 public String getCloseScriptlet() 238 { 239 return closeScriptlet; 240 } 241 242 public String getOpenExpr() 243 { 244 return openExpr; 245 } 246 247 public String getCloseExpr() 248 { 249 return closeExpr; 250 } 251 252 public String getOpenDirective() 253 { 254 return openDirective; 255 } 256 257 public String getCloseDirective() 258 { 259 return closeDirective; 260 } 261 262 public String getQuotedStartTag() 263 { 264 return quotedStartTag; 265 } 266 267 public String getQuotedEndTag() 268 { 269 return quotedEndTag; 270 } 271 272 public String getStartTag() 273 { 274 return startTag; 275 } 276 277 public String getEndTag() 278 { 279 return endTag; 280 } 281 282 public static class Scriptlet implements JETCoreElement 283 { 284 public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException 285 { 286 String close, open, end_open = null; 287 Map attrs = null; 288 289 if (reader.matches(parser.getOpenScriptlet())) 290 { 291 open = parser.getOpenScriptlet(); 292 close = parser.getCloseScriptlet(); 293 } 294 else 295 { 296 return false; 297 } 298 299 reader.advance(open.length()); 300 301 if (end_open != null) 302 { 303 attrs = reader.parseTagAttributes(); 304 305 reader.skipSpaces(); 306 if (!reader.matches(end_open)) 307 { 308 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object [] { open, reader.mark().toString() })); 309 } 310 reader.advance(end_open.length()); 311 reader.skipSpaces(); 312 } 313 314 JETMark start = reader.mark(); 315 JETMark stop = reader.skipUntil(close); 316 if (stop == null) 317 { 318 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object [] { open, reader.mark().toString() })); 319 } 320 listener.handleScriptlet(start, stop, attrs); 321 return true; 322 } 323 } 324 325 public static class Expression implements JETCoreElement 326 { 327 public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException 328 { 329 String close, open; 330 Map attrs = null; 331 332 if (reader.matches(parser.getOpenExpr())) 333 { 334 open = parser.getOpenExpr(); 335 close = parser.getCloseExpr(); 336 } 337 else 338 { 339 return false; 340 } 341 342 reader.advance(open.length()); 343 344 JETMark start = reader.mark(); 345 JETMark stop = reader.skipUntil(close); 346 if (stop == null) 347 { 348 throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object [] { open, reader.mark().toString() })); 349 } 350 listener.handleExpression(start, stop, attrs); 351 return true; 352 } 353 } 354 355 359 public static class QuoteEscape implements JETCoreElement 360 { 361 364 protected static final String APOS = "'"; 365 protected static final String QUOTE = ""e;"; 366 367 public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException 368 { 369 try 370 { 371 if (reader.matches(parser.getQuotedEndTag())) 372 { 373 reader.advance(parser.getQuotedEndTag().length()); 374 parser.writer.write(parser.getEndTag()); 375 parser.flushCharData(); 376 return true; 377 } 378 else if (reader.matches(APOS)) 379 { 380 reader.advance(APOS.length()); 381 parser.writer.write("\'"); 382 parser.flushCharData(); 383 return true; 384 } 385 else if (reader.matches(QUOTE)) 386 { 387 reader.advance(QUOTE.length()); 388 parser.writer.write("\""); 389 parser.flushCharData(); 390 return true; 391 } 392 } 393 catch (IOException exception) 394 { 395 throw new JETException(exception); 396 } 397 return false; 398 } 399 } 400 401 public static class Directive implements JETCoreElement 402 { 403 protected Collection directives = new ArrayList (); 404 405 public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException 406 { 407 if (reader.matches(parser.getOpenDirective())) 408 { 409 JETMark start = reader.mark(); 410 reader.advance(parser.getOpenDirective().length()); 411 reader.skipSpaces(); 412 413 String match = null; 416 417 for (Iterator i = directives.iterator(); i.hasNext(); ) 418 { 419 String directive = (String )i.next(); 420 if (reader.matches(directive)) 421 { 422 match = directive; 423 break; 424 } 425 } 426 427 if (match == null) 428 { 429 throw 430 new JETException 431 (CodeGenPlugin.getPlugin().getString 432 ("jet.error.bad.directive", 433 new Object [] { start.format("jet.mark.file.line.column") })); 434 } 437 438 reader.advance(match.length()); 439 440 Map attrs = reader.parseTagAttributes(); 443 444 reader.skipSpaces(); 446 if (!reader.matches(parser.getCloseDirective())) 447 { 448 throw 449 new JETException 450 (CodeGenPlugin.getPlugin().getString 451 ("jet.error.unterminated", new Object [] { parser.getOpenDirective(), reader.mark().toString() })); 452 } 453 else 454 { 455 reader.advance(parser.getCloseDirective().length()); 456 } 457 458 JETMark stop = reader.mark(); 459 listener.handleDirective(match, start, stop, attrs); 460 return true; 461 } 462 else 463 { 464 return false; 465 } 466 } 467 468 public Collection getDirectives() 469 { 470 return directives; 471 } 472 } 473 474 protected void flushCharData() throws JETException 475 { 476 char[] array = writer.toCharArray(); 477 if (array.length != 0) { 479 listener.handleCharData(writer.toCharArray()); 480 } 481 writer = new CharArrayWriter (); 482 } 483 484 public void parse() throws JETException 485 { 486 parse(null); 487 } 488 489 public void parse(String until) throws JETException 490 { 491 parse(until, null); 492 } 493 494 public void parse(String until, Class [] accept) throws JETException 495 { 496 while (reader.hasMoreInput()) 497 { 498 if (until != null && reader.matches(until)) 499 { 500 return; 501 } 502 503 Iterator e = coreElements.iterator(); 504 505 if (accept != null) 506 { 507 List v = new ArrayList (); 508 while (e.hasNext()) 509 { 510 JETCoreElement c = (JETCoreElement) e.next(); 511 for(int i = 0; i < accept.length; i++) 512 { 513 if (c.getClass().equals(accept[i])) 514 { 515 v.add(c); 516 } 517 } 518 } 519 e = v.iterator(); 520 } 521 522 boolean accepted = false; 523 while (e.hasNext()) 524 { 525 JETCoreElement c = (JETCoreElement) e.next(); 526 reader.mark(); 527 if (c.accept(listener, reader, this)) 528 { 529 accepted = true; 530 break; 531 } 532 } 533 if (!accepted) 534 { 535 String s = reader.nextContent(); 536 writer.write(s, 0, s.length()); 537 } 538 } 539 flushCharData(); 540 } 541 } 542 | Popular Tags |