org.eclipse.mylyn.wikitext.core_1.6.1.v20120425-0100

 DITA topic mapping for " + type);
      writer.writeStartElement("ph");
    }
    applyAttributes(attributes);
  }
  
  public void endSpan()
  {
    writer.writeEndElement();
  }
  
  public void charactersUnescaped(String literal)
  {
    ensureOpenTopic();
    
    writer.writeLiteral(literal);
  }
  
  private void ensureOpenTopic()
  {
    if (topicInfos.isEmpty())
    {
      beginHeading(1, new Attributes());
      endHeading();
    }
  }
  
  private void closeTopics(int toLevel)
  {
    if (toLevel < 0) {
      toLevel = 0;
    }
    TopicInfo topicInfo;
    int x;
    for (; (!topicInfos.isEmpty()) && (topicInfos.peek()).headingLevel > toLevel); x < openElements)
    {
      topicInfo = (TopicInfo)topicInfos.pop();
      x = 0; continue;
      writer.writeEndElement();x++;
    }
    if (!topicInfos.isEmpty())
    {
      TopicInfo topicInfo = (TopicInfo)topicInfos.peek();
      while (openElements > 1)
      {
        openElements -= 1;
        writer.writeEndElement();
      }
    }
  }
  
  public void endDocument()
  {
    closeTopics(0);
    if (rootTitle != null) {
      writer.writeEndElement();
    }
    writer.writeEndDocument();
  }
  
  public void endHeading()
  {
    writer.writeEndElement();
    writer.writeStartElement("body");
  }
  
  public void image(Attributes attributes, String url)
  {
    ensureOpenTopic();
    
    boolean emitAsFigure = attributes.getTitle() != null;
    if (emitAsFigure)
    {
      writer.writeStartElement("fig");
      writer.writeStartElement("title");
      writer.writeCharacters(attributes.getTitle());
      writer.writeEndElement();
    }
    writer.writeEmptyElement("image");
    writer.writeAttribute("href", url);
    applyImageAttributes(attributes);
    if (emitAsFigure) {
      writer.writeEndElement();
    }
  }
  
  public void imageLink(Attributes linkAttributes, Attributes imageAttributes, String href, String imageUrl)
  {
    ensureOpenTopic();
    writer.writeStartElement("xref");
    writer.writeAttribute("href", computeDitaXref(href));
    writer.writeAttribute("format", "html");
    image(imageAttributes, imageUrl);
    writer.writeEndElement();
  }
  
  private void applyImageAttributes(Attributes imageAttributes)
  {
    applyAttributes(imageAttributes);
    if ((imageAttributes instanceof ImageAttributes))
    {
      ImageAttributes attributes = (ImageAttributes)imageAttributes;
      if (attributes.getAlt() != null) {
        writer.writeAttribute("alt", attributes.getAlt());
      }
      if (attributes.getHeight() > 0) {
        writer.writeAttribute("height", Integer.toString(attributes.getHeight()));
      }
      if (attributes.getWidth() > 0) {
        writer.writeAttribute("width", Integer.toString(attributes.getWidth()));
      }
      if (attributes.getAlign() != null)
      {
        switch (attributes.getAlign())
        {
        case Absbottom: 
          writer.writeAttribute("align", "center");
          break;
        case Absmiddle: 
          writer.writeAttribute("align", "right");
          break;
        case Top: 
          writer.writeAttribute("align", "center");
        }
        writer.writeAttribute("placement", "break");
      }
    }
  }
  
  public void lineBreak() {}
  
  public void link(Attributes attributes, String hrefOrHashName, String text)
  {
    ensureOpenTopic();
    writer.writeStartElement("xref");
    writer.writeAttribute("href", computeDitaXref(hrefOrHashName));
    if (text != null) {
      characters(text);
    }
    writer.writeEndElement();
  }
  
  public void characters(String text)
  {
    ensureOpenTopic();
    super.characters(text);
  }
  
  public void entityReference(String entity)
  {
    ensureOpenTopic();
    if (entity.startsWith("#"))
    {
      String numeric = entity.substring(1);
      int base = 10;
      if (numeric.startsWith("x"))
      {
        numeric = entity.substring(1);
        base = 16;
      }
      int unicodeValue = Integer.parseInt(numeric, base);
      if (entityReferenceToUnicode.contains(Integer.valueOf(unicodeValue)))
      {
        writer.writeCharacters((char)unicodeValue);
        return;
      }
    }
    writer.writeEntityRef(entity);
  }
  
  public OutlineItem getOutline()
  {
    return outline;
  }
  
  public void setOutline(OutlineItem outline)
  {
    this.outline = outline;
  }
  
  public String getFilename()
  {
    return filename;
  }
  
  public void setFilename(String filename)
  {
    this.filename = filename;
  }
  
  private String computeDitaXref(String href)
  {
    if ((href.startsWith("#")) && (topicBreakLevel < Integer.MAX_VALUE) && 
      (outline != null))
    {
      OutlineItem item = outline.findItemById(href.substring(1));
      if (item != null)
      {
        OutlineItem topicItem = computeTopicFileItem(item);
        String targetFilename = computeTargetFilename(topicItem);
        String ref;
        String ref;
        if (targetFilename.equals(filename)) {
          ref = href;
        } else {
          ref = targetFilename + href;
        }
        return ref;
      }
    }
    return href;
  }
  
  public static String computeName(String headingId, String topicFilenameSuffix)
  {
    String name = headingId == null ? "__topic" : headingId.replaceAll("[^a-zA-Z0-9_.-]", "-");
    name = name + topicFilenameSuffix;
    return name;
  }
  
  private String computeTargetFilename(OutlineItem item)
  {
    String filenameSuffix = filename.substring(filename.lastIndexOf('.'));
    return computeName(item.getLevel() == topicBreakLevel ? item.getId() : null, filenameSuffix);
  }
  
  private OutlineItem computeTopicFileItem(OutlineItem item)
  {
    while ((item.getLevel() > topicBreakLevel) && (item.getParent() != null) && 
      (item.getParent().getLevel() > topicBreakLevel - 1)) {
      item = item.getParent();
    }
    return item;
  }
  
  public int getTopicBreakLevel()
  {
    return topicBreakLevel;
  }
  
  public void setTopicBreakLevel(int topicBreakLevel)
  {
    this.topicBreakLevel = topicBreakLevel;
  }
  
  public void setRootTopicTitle(String rootTitle)
  {
    this.rootTitle = rootTitle;
  }
  
  public String getRootTopicTitle()
  {
    return rootTitle;
  }
  
  private static class TopicInfo
  {
    int headingLevel;
    int openElements;
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.core.parser.builder.DitaTopicDocumentBuilder
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.core.parser.builder;

import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.SpanType;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

class AbstractSaxHtmlParser$DocumentBuilderAdapter
  implements ContentHandler
{
  private final Stack<ElementHandler> handlers = new Stack();
  private AbstractSaxHtmlParser.ElementState elementState;
  private final DocumentBuilder builder;
  private boolean processingContent;
  private final StringBuilder elementText = new StringBuilder();
  
  public AbstractSaxHtmlParser$DocumentBuilderAdapter(AbstractSaxHtmlParser paramAbstractSaxHtmlParser, DocumentBuilder builder)
  {
    this.builder = builder;
  }
  
  public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts)
    throws SAXException
  {
    if (processingContent) {
      emitText(elementState, false);
    }
    String lowerCaseName = localName.toLowerCase();
    elementState = new AbstractSaxHtmlParser.ElementState(elementState, lowerCaseName, null);
    if ((!processingContent) && 
      (lowerCaseName.equals("body"))) {
      processingContent = true;
    }
    if (elementState.parent != null) {
      elementState.parent.childCount += 1;
    }
    ElementHandler handler = computeElementHandler(lowerCaseName);
    handlers.push(handler);
    handler.start(atts);
  }
  
  public void endElement(String uri, String localName, String qName)
    throws SAXException
  {
    emitText(elementState, true);
    
    String lowerCaseName = localName.toLowerCase();
    elementState = elementState.parent;
    if ((processingContent) && 
      (lowerCaseName.equals("body"))) {
      processingContent = false;
    }
    if (!processingContent) {
      return;
    }
    ElementHandler handler = (ElementHandler)handlers.pop();
    handler.end();
  }
  
  private void emitText(AbstractSaxHtmlParser.ElementState elementState, boolean elementClosing)
  {
    String text = elementText.toString();
    if (!preserveWhitespace) {
      if (elementClosing)
      {
        if (childCount == 0)
        {
          if (blockElement) {
            text = text.trim();
          }
        }
        else if (blockElement) {
          text = AbstractSaxHtmlParser.access$5(text);
        }
      }
      else
      {
        String originalText = text;
        if ((blockElement) && (childCount == 0))
        {
          text = AbstractSaxHtmlParser.access$6(text);
          if ((text.length() == 0) && (originalText.length() > 0)) {
            text = originalText.substring(0, 1);
          }
        }
      }
    }
    elementText.delete(0, elementText.length());
    if (text.length() > 0) {
      ((ElementHandler)handlers.peek()).characters(text);
    }
  }
  
  public void characters(char[] ch, int start, int length)
    throws SAXException
  {
    if (processingContent)
    {
      if (((elementState.noWhitespaceTextContainer) && ((elementState.lastChild == null) || (elementState.lastChild.blockElement))) || 
        ((elementState.blockElement) && (!elementState.preserveWhitespace) && 
        (elementState.textChildCount == 0) && (elementState.childCount == 0)) || (
        (elementState.lastChild != null) && (elementState.lastChild.collapsesAdjacentWhitespace)))
      {
        int skip = 0;
        while ((skip < length) && (Character.isWhitespace(ch[(start + skip)]))) {
          skip++;
        }
        start += skip;
        length -= skip;
      }
      elementState.lastChild = null;
      if (length != 0)
      {
        elementState.textChildCount += 1;
        append(elementState, ch, start, length);
      }
    }
  }
  
  private void append(AbstractSaxHtmlParser.ElementState elementState, char[] ch, int start, int length)
  {
    if (!preserveWhitespace)
    {
      int previousWhitespaceIndex = Integer.MIN_VALUE;
      for (int x = 0; x < length; x++)
      {
        int index = start + x;
        char c = ch[index];
        if (Character.isWhitespace(c))
        {
          if (previousWhitespaceIndex == index - 1)
          {
            previousWhitespaceIndex = index;
          }
          else
          {
            previousWhitespaceIndex = index;
            elementText.append(c == '\t' ? c : ' ');
          }
        }
        else {
          elementText.append(c);
        }
      }
    }
    else
    {
      elementText.append(ch, start, length);
    }
  }
  
  public void setDocumentLocator(Locator locator) {}
  
  public void startDocument()
    throws SAXException
  {
    builder.beginDocument();
  }
  
  public void endDocument()
    throws SAXException
  {
    builder.endDocument();
  }
  
  public void startPrefixMapping(String prefix, String uri)
    throws SAXException
  {}
  
  public void endPrefixMapping(String prefix)
    throws SAXException
  {}
  
  public void ignorableWhitespace(char[] ch, int start, int length)
    throws SAXException
  {
    if ((processingContent) && (elementState.preserveWhitespace)) {
      characters(ch, start, length);
    }
  }
  
  public void processingInstruction(String target, String data)
    throws SAXException
  {}
  
  public void skippedEntity(String name)
    throws SAXException
  {}
  
  private abstract class ElementHandler
  {
    private ElementHandler() {}
    
    abstract void start(org.xml.sax.Attributes paramAttributes);
    
    abstract void end();
    
    void characters(String s)
    {
      builder.characters(s);
    }
  }
  
  private class BlockElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private final DocumentBuilder.BlockType blockType;
    
    private BlockElementHandler(DocumentBuilder.BlockType blockType)
    {
      super(null);
      this.blockType = blockType;
    }
    
    public void start(org.xml.sax.Attributes atts)
    {
      builder.beginBlock(blockType, AbstractSaxHtmlParser.access$2(this$0, atts));
    }
    
    public void end()
    {
      builder.endBlock();
    }
    
    public void characters(String s)
    {
      builder.characters(s);
    }
  }
  
  private class SpanElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private final DocumentBuilder.SpanType spanType;
    private boolean noop;
    
    private SpanElementHandler(DocumentBuilder.SpanType spanType)
    {
      super(null);
      this.spanType = spanType;
    }
    
    public void start(org.xml.sax.Attributes atts)
    {
      org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = AbstractSaxHtmlParser.access$3(this$0, spanType, atts);
      if ((spanType == DocumentBuilder.SpanType.SPAN) && (attributes.getCssClass() == null) && (attributes.getCssStyle() == null) && 
        (attributes.getId() == null)) {
        noop = true;
      } else {
        builder.beginSpan(spanType, attributes);
      }
    }
    
    public void end()
    {
      if (!noop) {
        builder.endSpan();
      }
    }
  }
  
  private class ContentElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private ContentElementHandler()
    {
      super(null);
    }
    
    public void start(org.xml.sax.Attributes atts) {}
    
    public void end() {}
  }
  
  private class HeadingElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    int level;
    
    private HeadingElementHandler(int level)
    {
      super(null);
      this.level = level;
    }
    
    void start(org.xml.sax.Attributes atts)
    {
      builder.beginHeading(level, AbstractSaxHtmlParser.access$2(this$0, atts));
    }
    
    void end()
    {
      builder.endHeading();
    }
  }
  
  private class ImageElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private ImageElementHandler()
    {
      super(null);
    }
    
    public void start(org.xml.sax.Attributes atts)
    {
      org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = AbstractSaxHtmlParser.access$3(this$0, DocumentBuilder.SpanType.SPAN, atts);
      builder.image(attributes, AbstractSaxHtmlParser.access$4(this$0, "src", atts));
    }
    
    public void end() {}
  }
  
  private class PreformattedBlockElementHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private org.xml.sax.Attributes atts;
    
    private PreformattedBlockElementHandler()
    {
      super(null);
    }
    
    void start(org.xml.sax.Attributes atts)
    {
      this.atts = new AttributesImpl(atts);
    }
    
    void end()
    {
      if (atts == null) {
        builder.endBlock();
      }
    }
    
    void characters(String s)
    {
      if (atts != null)
      {
        builder.beginBlock(DocumentBuilder.BlockType.PREFORMATTED, AbstractSaxHtmlParser.access$2(this$0, atts));
        atts = null;
      }
      super.characters(s);
    }
  }
  
  private class LineBreakHandler
    extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
  {
    private LineBreakHandler()
    {
      super(null);
    }
    
    public void start(org.xml.sax.Attributes atts) {}
    
    public void end()
    {
      builder.lineBreak();
    }
  }
  
  private ElementHandler computeElementHandler(String elementName)
  {
    DocumentBuilder.BlockType blockType = (DocumentBuilder.BlockType)AbstractSaxHtmlParser.access$7().get(elementName);
    if (blockType == null)
    {
      DocumentBuilder.SpanType spanType = (DocumentBuilder.SpanType)AbstractSaxHtmlParser.access$8().get(elementName);
      if (spanType != null) {
        return new SpanElementHandler(spanType, null);
      }
      if (elementName.equals("img")) {
        return new ImageElementHandler(null);
      }
      if (elementName.equals("br")) {
        return new LineBreakHandler(null);
      }
      Matcher headingMatcher = AbstractSaxHtmlParser.access$9().matcher(elementName);
      if (headingMatcher.matches()) {
        return new HeadingElementHandler(Integer.parseInt(headingMatcher.group(1)), null);
      }
      return new ContentElementHandler(null);
    }
    if ((blockType == DocumentBuilder.BlockType.CODE) && (!handlers.isEmpty()))
    {
      ElementHandler outerHandler = (ElementHandler)handlers.peek();
      if (!(outerHandler instanceof PreformattedBlockElementHandler)) {
        return new SpanElementHandler(DocumentBuilder.SpanType.CODE, null);
      }
    }
    if (blockType == DocumentBuilder.BlockType.PREFORMATTED) {
      return new PreformattedBlockElementHandler(null);
    }
    return new BlockElementHandler(blockType, null);
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.core.parser.builder.AbstractSaxHtmlParser.DocumentBuilderAdapter
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.core.parser.builder;

import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder;
import org.xml.sax.Attributes;

class AbstractSaxHtmlParser$DocumentBuilderAdapter$LineBreakHandler
  extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
{
  private AbstractSaxHtmlParser$DocumentBuilderAdapter$LineBreakHandler(AbstractSaxHtmlParser.DocumentBuilderAdapter paramDocumentBuilderAdapter)
  {
    super(paramDocumentBuilderAdapter, null);
  }
  
  public void start(Attributes atts) {}
  
  public void end()
  {
    AbstractSaxHtmlParser.DocumentBuilderAdapter.access$0(this$1).lineBreak();
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.core.parser.builder.AbstractSaxHtmlParser.DocumentBuilderAdapter.LineBreakHandler
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.core.parser.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem;
import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem.Visitor;

public class SplitOutlineItem
  extends OutlineItem
{
  private String splitTarget;
  private Map<String, SplitOutlineItem> outlineItemById;
  private List<SplitOutlineItem> pages;
  
  public SplitOutlineItem(OutlineItem parent, int level, String id, int offset, int length, String label)
  {
    super(parent, level, id, offset, length, label);
  }
  
  public void setSplitTarget(String splitTarget)
  {
    this.splitTarget = splitTarget;
  }
  
  public String getSplitTarget()
  {
    if ((splitTarget == null) && (getParent() != null)) {
      return getParent().getSplitTarget();
    }
    return splitTarget;
  }
  
  public List<SplitOutlineItem> getPageOrder()
  {
    if (getParent() != null) {
      return getParent().getPageOrder();
    }
    if (pages == null)
    {
      final Set<String> pageTargets = new HashSet();
      pages = new ArrayList();
      accept(new OutlineItem.Visitor()
      {
        public boolean visit(OutlineItem item)
        {
          SplitOutlineItem split = (SplitOutlineItem)item;
          if (pageTargets.add(split.getSplitTarget())) {
            pages.add(split);
          }
          return true;
        }
      });
    }
    return pages;
  }
  
  public SplitOutlineItem getParent()
  {
    return (SplitOutlineItem)super.getParent();
  }
  
  public SplitOutlineItem getOutlineItemById(String id)
  {
    if (getParent() != null) {
      return getParent().getOutlineItemById(id);
    }
    if (outlineItemById == null)
    {
      final Map<String, SplitOutlineItem> splitTargetById = new HashMap();
      accept(new OutlineItem.Visitor()
      {
        public boolean visit(OutlineItem item)
        {
          if (item.getId() != null)
          {
            if (splitTargetById.containsKey(item.getId())) {
              throw new IllegalStateException(String.format("Duplicate id '%s'", new Object[] { item.getId() }));
            }
            splitTargetById.put(item.getId(), (SplitOutlineItem)item);
          }
          return true;
        }
      });
      outlineItemById = splitTargetById;
    }
    return (SplitOutlineItem)outlineItemById.get(id);
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.core.parser.builder.SplitOutlineItem
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.core.parser.builder;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.SpanType;
import org.eclipse.mylyn.wikitext.core.parser.LinkAttributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

public abstract class AbstractSaxHtmlParser
{
  private static final Pattern HEADING_PATTERN = Pattern.compile("h([1-6])");
  private static Set<String> blockElements = new HashSet();
  private static Set<String> whitespaceCollapsingElements = new HashSet();
  private static final Map<String, DocumentBuilder.SpanType> elementNameToSpanType;
  private static final Map<String, DocumentBuilder.BlockType> elementNameToBlockType;
  
  static
  {
    blockElements.add("div");
    blockElements.add("dl");
    blockElements.add("form");
    blockElements.add("h1");
    blockElements.add("h2");
    blockElements.add("h3");
    blockElements.add("h4");
    blockElements.add("h5");
    blockElements.add("h6");
    blockElements.add("ol");
    blockElements.add("p");
    blockElements.add("pre");
    blockElements.add("table");
    blockElements.add("textarea");
    blockElements.add("td");
    blockElements.add("tr");
    blockElements.add("ul");
    blockElements.add("tbody");
    blockElements.add("thead");
    blockElements.add("tfoot");
    blockElements.add("li");
    blockElements.add("dd");
    blockElements.add("dt");
    
    whitespaceCollapsingElements.add("br");
    whitespaceCollapsingElements.add("hr");
    
    elementNameToSpanType = new HashMap();
    
    elementNameToSpanType.put("a", DocumentBuilder.SpanType.LINK);
    elementNameToSpanType.put("b", DocumentBuilder.SpanType.BOLD);
    elementNameToSpanType.put("cite", DocumentBuilder.SpanType.CITATION);
    elementNameToSpanType.put("i", DocumentBuilder.SpanType.ITALIC);
    elementNameToSpanType.put("em", DocumentBuilder.SpanType.EMPHASIS);
    elementNameToSpanType.put("strong", DocumentBuilder.SpanType.STRONG);
    elementNameToSpanType.put("del", DocumentBuilder.SpanType.DELETED);
    elementNameToSpanType.put("ins", DocumentBuilder.SpanType.INSERTED);
    elementNameToSpanType.put("q", DocumentBuilder.SpanType.QUOTE);
    elementNameToSpanType.put("u", DocumentBuilder.SpanType.UNDERLINED);
    elementNameToSpanType.put("sup", DocumentBuilder.SpanType.SUPERSCRIPT);
    elementNameToSpanType.put("sub", DocumentBuilder.SpanType.SUBSCRIPT);
    elementNameToSpanType.put("span", DocumentBuilder.SpanType.SPAN);
    elementNameToSpanType.put("font", DocumentBuilder.SpanType.SPAN);
    elementNameToSpanType.put("code", DocumentBuilder.SpanType.CODE);
    elementNameToSpanType.put("tt", DocumentBuilder.SpanType.MONOSPACE);
    
    elementNameToBlockType = new HashMap();
    
    elementNameToBlockType.put("ul", DocumentBuilder.BlockType.BULLETED_LIST);
    elementNameToBlockType.put("code", DocumentBuilder.BlockType.CODE);
    elementNameToBlockType.put("div", DocumentBuilder.BlockType.DIV);
    elementNameToBlockType.put("footnote", DocumentBuilder.BlockType.FOOTNOTE);
    elementNameToBlockType.put("li", DocumentBuilder.BlockType.LIST_ITEM);
    elementNameToBlockType.put("ol", DocumentBuilder.BlockType.NUMERIC_LIST);
    elementNameToBlockType.put("dl", DocumentBuilder.BlockType.DEFINITION_LIST);
    elementNameToBlockType.put("dt", DocumentBuilder.BlockType.DEFINITION_TERM);
    elementNameToBlockType.put("dd", DocumentBuilder.BlockType.DEFINITION_ITEM);
    elementNameToBlockType.put("p", DocumentBuilder.BlockType.PARAGRAPH);
    elementNameToBlockType.put("pre", DocumentBuilder.BlockType.PREFORMATTED);
    elementNameToBlockType.put("blockquote", DocumentBuilder.BlockType.QUOTE);
    elementNameToBlockType.put("table", DocumentBuilder.BlockType.TABLE);
    elementNameToBlockType.put("th", DocumentBuilder.BlockType.TABLE_CELL_HEADER);
    elementNameToBlockType.put("td", DocumentBuilder.BlockType.TABLE_CELL_NORMAL);
    elementNameToBlockType.put("tr", DocumentBuilder.BlockType.TABLE_ROW);
  }
  
  private static final class ElementState
  {
    final String elementName;
    final ElementState parent;
    final boolean preserveWhitespace;
    final boolean blockElement;
    final boolean noWhitespaceTextContainer;
    final boolean collapsesAdjacentWhitespace;
    
    private ElementState(ElementState parent, String elementName)
    {
      this.parent = parent;
      this.elementName = elementName;
      blockElement = AbstractSaxHtmlParser.blockElements.contains(elementName);
      collapsesAdjacentWhitespace = AbstractSaxHtmlParser.whitespaceCollapsingElements.contains(elementName);
      noWhitespaceTextContainer = "body".equals(elementName);
      preserveWhitespace = (((parent != null) && (preserveWhitespace)) || ("pre".equals(elementName)));
      if (parent != null) {
        lastChild = this;
      }
    }
    
    int childCount = 0;
    int textChildCount = 0;
    ElementState lastChild;
  }
  
  private class DocumentBuilderAdapter
    implements ContentHandler
  {
    private final Stack<ElementHandler> handlers = new Stack();
    private AbstractSaxHtmlParser.ElementState elementState;
    private final DocumentBuilder builder;
    private boolean processingContent;
    private final StringBuilder elementText = new StringBuilder();
    
    public DocumentBuilderAdapter(DocumentBuilder builder)
    {
      this.builder = builder;
    }
    
    public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts)
      throws SAXException
    {
      if (processingContent) {
        emitText(elementState, false);
      }
      String lowerCaseName = localName.toLowerCase();
      elementState = new AbstractSaxHtmlParser.ElementState(elementState, lowerCaseName, null);
      if ((!processingContent) && 
        (lowerCaseName.equals("body"))) {
        processingContent = true;
      }
      if (elementState.parent != null) {
        elementState.parent.childCount += 1;
      }
      ElementHandler handler = computeElementHandler(lowerCaseName);
      handlers.push(handler);
      handler.start(atts);
    }
    
    public void endElement(String uri, String localName, String qName)
      throws SAXException
    {
      emitText(elementState, true);
      
      String lowerCaseName = localName.toLowerCase();
      elementState = elementState.parent;
      if ((processingContent) && 
        (lowerCaseName.equals("body"))) {
        processingContent = false;
      }
      if (!processingContent) {
        return;
      }
      ElementHandler handler = (ElementHandler)handlers.pop();
      handler.end();
    }
    
    private void emitText(AbstractSaxHtmlParser.ElementState elementState, boolean elementClosing)
    {
      String text = elementText.toString();
      if (!preserveWhitespace) {
        if (elementClosing)
        {
          if (childCount == 0)
          {
            if (blockElement) {
              text = text.trim();
            }
          }
          else if (blockElement) {
            text = AbstractSaxHtmlParser.trimRight(text);
          }
        }
        else
        {
          String originalText = text;
          if ((blockElement) && (childCount == 0))
          {
            text = AbstractSaxHtmlParser.trimLeft(text);
            if ((text.length() == 0) && (originalText.length() > 0)) {
              text = originalText.substring(0, 1);
            }
          }
        }
      }
      elementText.delete(0, elementText.length());
      if (text.length() > 0) {
        ((ElementHandler)handlers.peek()).characters(text);
      }
    }
    
    public void characters(char[] ch, int start, int length)
      throws SAXException
    {
      if (processingContent)
      {
        if (((elementState.noWhitespaceTextContainer) && ((elementState.lastChild == null) || (elementState.lastChild.blockElement))) || 
          ((elementState.blockElement) && (!elementState.preserveWhitespace) && 
          (elementState.textChildCount == 0) && (elementState.childCount == 0)) || (
          (elementState.lastChild != null) && (elementState.lastChild.collapsesAdjacentWhitespace)))
        {
          int skip = 0;
          while ((skip < length) && (Character.isWhitespace(ch[(start + skip)]))) {
            skip++;
          }
          start += skip;
          length -= skip;
        }
        elementState.lastChild = null;
        if (length != 0)
        {
          elementState.textChildCount += 1;
          append(elementState, ch, start, length);
        }
      }
    }
    
    private void append(AbstractSaxHtmlParser.ElementState elementState, char[] ch, int start, int length)
    {
      if (!preserveWhitespace)
      {
        int previousWhitespaceIndex = Integer.MIN_VALUE;
        for (int x = 0; x < length; x++)
        {
          int index = start + x;
          char c = ch[index];
          if (Character.isWhitespace(c))
          {
            if (previousWhitespaceIndex == index - 1)
            {
              previousWhitespaceIndex = index;
            }
            else
            {
              previousWhitespaceIndex = index;
              elementText.append(c == '\t' ? c : ' ');
            }
          }
          else {
            elementText.append(c);
          }
        }
      }
      else
      {
        elementText.append(ch, start, length);
      }
    }
    
    public void setDocumentLocator(Locator locator) {}
    
    public void startDocument()
      throws SAXException
    {
      builder.beginDocument();
    }
    
    public void endDocument()
      throws SAXException
    {
      builder.endDocument();
    }
    
    public void startPrefixMapping(String prefix, String uri)
      throws SAXException
    {}
    
    public void endPrefixMapping(String prefix)
      throws SAXException
    {}
    
    public void ignorableWhitespace(char[] ch, int start, int length)
      throws SAXException
    {
      if ((processingContent) && (elementState.preserveWhitespace)) {
        characters(ch, start, length);
      }
    }
    
    public void processingInstruction(String target, String data)
      throws SAXException
    {}
    
    public void skippedEntity(String name)
      throws SAXException
    {}
    
    private abstract class ElementHandler
    {
      private ElementHandler() {}
      
      abstract void start(org.xml.sax.Attributes paramAttributes);
      
      abstract void end();
      
      void characters(String s)
      {
        builder.characters(s);
      }
    }
    
    private class BlockElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private final DocumentBuilder.BlockType blockType;
      
      private BlockElementHandler(DocumentBuilder.BlockType blockType)
      {
        super(null);
        this.blockType = blockType;
      }
      
      public void start(org.xml.sax.Attributes atts)
      {
        builder.beginBlock(blockType, AbstractSaxHtmlParser.this.computeAttributes(atts));
      }
      
      public void end()
      {
        builder.endBlock();
      }
      
      public void characters(String s)
      {
        builder.characters(s);
      }
    }
    
    private class SpanElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private final DocumentBuilder.SpanType spanType;
      private boolean noop;
      
      private SpanElementHandler(DocumentBuilder.SpanType spanType)
      {
        super(null);
        this.spanType = spanType;
      }
      
      public void start(org.xml.sax.Attributes atts)
      {
        org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = AbstractSaxHtmlParser.this.computeAttributes(spanType, atts);
        if ((spanType == DocumentBuilder.SpanType.SPAN) && (attributes.getCssClass() == null) && (attributes.getCssStyle() == null) && 
          (attributes.getId() == null)) {
          noop = true;
        } else {
          builder.beginSpan(spanType, attributes);
        }
      }
      
      public void end()
      {
        if (!noop) {
          builder.endSpan();
        }
      }
    }
    
    private class ContentElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private ContentElementHandler()
      {
        super(null);
      }
      
      public void start(org.xml.sax.Attributes atts) {}
      
      public void end() {}
    }
    
    private class HeadingElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      int level;
      
      private HeadingElementHandler(int level)
      {
        super(null);
        this.level = level;
      }
      
      void start(org.xml.sax.Attributes atts)
      {
        builder.beginHeading(level, AbstractSaxHtmlParser.this.computeAttributes(atts));
      }
      
      void end()
      {
        builder.endHeading();
      }
    }
    
    private class ImageElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private ImageElementHandler()
      {
        super(null);
      }
      
      public void start(org.xml.sax.Attributes atts)
      {
        org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = AbstractSaxHtmlParser.this.computeAttributes(DocumentBuilder.SpanType.SPAN, atts);
        builder.image(attributes, AbstractSaxHtmlParser.this.getValue("src", atts));
      }
      
      public void end() {}
    }
    
    private class PreformattedBlockElementHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private org.xml.sax.Attributes atts;
      
      private PreformattedBlockElementHandler()
      {
        super(null);
      }
      
      void start(org.xml.sax.Attributes atts)
      {
        this.atts = new AttributesImpl(atts);
      }
      
      void end()
      {
        if (atts == null) {
          builder.endBlock();
        }
      }
      
      void characters(String s)
      {
        if (atts != null)
        {
          builder.beginBlock(DocumentBuilder.BlockType.PREFORMATTED, AbstractSaxHtmlParser.this.computeAttributes(atts));
          atts = null;
        }
        super.characters(s);
      }
    }
    
    private class LineBreakHandler
      extends AbstractSaxHtmlParser.DocumentBuilderAdapter.ElementHandler
    {
      private LineBreakHandler()
      {
        super(null);
      }
      
      public void start(org.xml.sax.Attributes atts) {}
      
      public void end()
      {
        builder.lineBreak();
      }
    }
    
    private ElementHandler computeElementHandler(String elementName)
    {
      DocumentBuilder.BlockType blockType = (DocumentBuilder.BlockType)AbstractSaxHtmlParser.elementNameToBlockType.get(elementName);
      if (blockType == null)
      {
        DocumentBuilder.SpanType spanType = (DocumentBuilder.SpanType)AbstractSaxHtmlParser.elementNameToSpanType.get(elementName);
        if (spanType != null) {
          return new SpanElementHandler(spanType, null);
        }
        if (elementName.equals("img")) {
          return new ImageElementHandler(null);
        }
        if (elementName.equals("br")) {
          return new LineBreakHandler(null);
        }
        Matcher headingMatcher = AbstractSaxHtmlParser.HEADING_PATTERN.matcher(elementName);
        if (headingMatcher.matches()) {
          return new HeadingElementHandler(Integer.parseInt(headingMatcher.group(1)), null);
        }
        return new ContentElementHandler(null);
      }
      if ((blockType == DocumentBuilder.BlockType.CODE) && (!handlers.isEmpty()))
      {
        ElementHandler outerHandler = (ElementHandler)handlers.peek();
        if (!(outerHandler instanceof PreformattedBlockElementHandler)) {
          return new SpanElementHandler(DocumentBuilder.SpanType.CODE, null);
        }
      }
      if (blockType == DocumentBuilder.BlockType.PREFORMATTED) {
        return new PreformattedBlockElementHandler(null);
      }
      return new BlockElementHandler(blockType, null);
    }
  }
  
  private org.eclipse.mylyn.wikitext.core.parser.Attributes computeAttributes(DocumentBuilder.SpanType spanType, org.xml.sax.Attributes atts)
  {
    org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = spanType == DocumentBuilder.SpanType.LINK ? 
      new LinkAttributes() : 
      new org.eclipse.mylyn.wikitext.core.parser.Attributes();
    populateCommonAttributes(attributes, atts);
    if (spanType == DocumentBuilder.SpanType.LINK)
    {
      String href = getValue("href", atts);
      if (href != null) {
        ((LinkAttributes)attributes).setHref(href);
      }
    }
    return attributes;
  }
  
  private String getValue(String name, org.xml.sax.Attributes atts)
  {
    for (int x = 0; x < atts.getLength(); x++)
    {
      String localName = atts.getLocalName(x);
      if (localName.equals(name)) {
        return atts.getValue(x);
      }
    }
    return null;
  }
  
  private org.eclipse.mylyn.wikitext.core.parser.Attributes computeAttributes(org.xml.sax.Attributes atts)
  {
    org.eclipse.mylyn.wikitext.core.parser.Attributes attributes = new org.eclipse.mylyn.wikitext.core.parser.Attributes();
    populateCommonAttributes(attributes, atts);
    return attributes;
  }
  
  private void populateCommonAttributes(org.eclipse.mylyn.wikitext.core.parser.Attributes attributes, org.xml.sax.Attributes atts)
  {
    for (int x = 0; x < atts.getLength(); x++)
    {
      String localName = atts.getLocalName(x);
      if ((localName.equals("id")) || (localName.equals("name"))) {
        attributes.setId(atts.getValue(x));
      } else if (localName.equals("style")) {
        attributes.setCssStyle(atts.getValue(x));
      } else if (localName.equals("class")) {
        attributes.setCssClass(atts.getValue(x));
      } else if (localName.equals("title")) {
        attributes.setTitle(atts.getValue(x));
      } else if (localName.equals("color")) {
        attributes.appendCssStyle("color: " + atts.getValue(x) + ";");
      }
    }
  }
  
  private static String trimRight(String text)
  {
    int len = text.length();
    while ((len > 0) && (text.charAt(len - 1) <= ' ')) {
      len--;
    }
    return len < text.length() ? text.substring(0, len) : text;
  }
  
  private static String trimLeft(String text)
  {
    int len = text.length();
    int st = 0;
  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd