1 21 package au.id.jericho.lib.html; 22 23 import java.util.*; 24 25 94 public abstract class TagType { 95 private final String description; 96 private final String startDelimiter; 97 private final char[] startDelimiterCharArray; 98 private final String closingDelimiter; 99 private final boolean isServerTag; 100 private final String namePrefix; 101 final String startDelimiterPrefix; 102 103 TagType(final String description, final String startDelimiter, final String closingDelimiter, final boolean isServerTag, final String startDelimiterPrefix) { 104 this.description=description; 106 this.startDelimiter=startDelimiter; 107 startDelimiterCharArray=startDelimiter.toCharArray(); 108 this.closingDelimiter=closingDelimiter; 109 this.isServerTag=isServerTag; 110 this.namePrefix=startDelimiter.substring(startDelimiterPrefix.length()); 111 this.startDelimiterPrefix=startDelimiterPrefix; 112 } 113 114 122 public final void register() { 123 TagTypeRegister.add(this); 124 } 125 126 132 public final void deregister() { 133 TagTypeRegister.remove(this); 134 } 135 136 141 public static final List getRegisteredTagTypes() { 142 return TagTypeRegister.getList(); 143 } 144 145 151 public final String getDescription() { 152 return description; 153 } 154 155 203 public final String getStartDelimiter() { 204 return startDelimiter; 205 } 206 207 256 public final String getClosingDelimiter() { 257 return closingDelimiter; 258 } 259 260 311 public final boolean isServerTag() { 312 return isServerTag; 313 } 314 315 364 protected final String getNamePrefix() { 365 return namePrefix; 366 } 367 368 403 protected boolean isValidPosition(final Source source, final int pos) { 404 if (isServerTag()) return true; 405 if (source.endOfLastTagIgnoringEnclosedMarkup!=-1) { 406 return pos>=source.endOfLastTagIgnoringEnclosedMarkup; 409 } 410 final TagType[] tagTypesIgnoringEnclosedMarkup=getTagTypesIgnoringEnclosedMarkup(); 412 for (int i=0; i<tagTypesIgnoringEnclosedMarkup.length; i++) 413 if (tagTypesIgnoringEnclosedMarkup[i].tagEncloses(source,pos)) return false; 414 return true; 415 } 416 417 460 public static final TagType[] getTagTypesIgnoringEnclosedMarkup() { 461 return TagTypesIgnoringEnclosedMarkup.array; 462 } 463 464 472 public static final void setTagTypesIgnoringEnclosedMarkup(TagType[] tagTypes) { 473 if (tagTypes==null) throw new IllegalArgumentException (); 474 TagTypesIgnoringEnclosedMarkup.array=tagTypes; 475 } 476 477 501 protected abstract Tag constructTagAt(Source source, int pos); 502 503 516 protected final boolean tagEncloses(final Source source, final int pos) { 517 if (pos==0) return false; 518 final Tag enclosingTag=source.findEnclosingTag(pos-1,this); return enclosingTag!=null && pos!=enclosingTag.getEnd(); } 521 522 526 public String toString() { 527 return getDescription(); 528 } 529 530 static final Tag getTagAt(final Source source, final int pos, final boolean assumeNoNestedTags) { 531 final TagTypeRegister.ProspectiveTagTypeIterator prospectiveTagTypeIterator=new TagTypeRegister.ProspectiveTagTypeIterator(source,pos); 532 while (prospectiveTagTypeIterator.hasNext()) { 534 final TagType tagType=prospectiveTagTypeIterator.getNextTagType(); 535 if (assumeNoNestedTags || tagType.isValidPosition(source,pos)) { 536 try { 537 final Tag tag=tagType.constructTagAt(source,pos); 538 if (tag!=null) return tag; 539 } catch (IndexOutOfBoundsException ex) { 540 if (source.isLoggingEnabled()) source.log(source.getRowColumnVector(pos).appendTo(new StringBuffer (200).append("Tag at ")).append(" not recognised as type '").append(tagType.getDescription()).append("' because it has no end delimiter").toString()); 541 } 542 } 543 } 544 return null; 545 } 546 547 final String getNamePrefixForTagConstant() { 548 return getNamePrefix(); 550 } 551 552 final char[] getStartDelimiterCharArray() { 553 return startDelimiterCharArray; 554 } 555 556 private static final class TagTypesIgnoringEnclosedMarkup { 557 public static TagType[] array=new TagType[] { 560 StartTagType.COMMENT, 561 StartTagType.CDATA_SECTION 562 }; 563 } 564 } 565 | Popular Tags |