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

rentBlock.getParent();
    if (currentBlock == null) {
      throw new IllegalStateException();
    }
  }
  
  public void endDocument()
  {
    if (currentBlock != outerBlock) {
      throw new IllegalStateException();
    }
    Locator locator = getLocator();
    outerBlock.setLength((locator == null ? 0 : locator.getDocumentOffset()) + offset);
    
    partitions = new ArrayList();
    for (Segment<?> child : outerBlock.getChildren().asList()) {
      createRegions(null, child);
    }
  }
  
  public FastMarkupPartitioner.MarkupPartition createRegions(FastMarkupPartitioner.MarkupPartition parent, Segment<?> segment)
  {
    if (segment.getLength() == 0) {
      return parent;
    }
    if ((segment instanceof Block))
    {
      Block block = (Block)segment;
      if (!filtered(block))
      {
        FastMarkupPartitioner.MarkupPartition partition = new FastMarkupPartitioner.MarkupPartition(block, segment.getOffset(), segment.getLength(), null);
        int parentLength;
        if (parent == null)
        {
          partitions.add(partition);
        }
        else
        {
          int parentIndex = partitions.indexOf(parent);
          if (FastMarkupPartitioner.MarkupPartition.access$1(partition) == FastMarkupPartitioner.MarkupPartition.access$1(parent))
          {
            if (FastMarkupPartitioner.MarkupPartition.access$2(partition) == FastMarkupPartitioner.MarkupPartition.access$2(parent))
            {
              partitions.remove(parentIndex);
              partitions.add(parentIndex, partition);
            }
            else
            {
              FastMarkupPartitioner.MarkupPartition.access$3(parent, FastMarkupPartitioner.MarkupPartition.access$1(partition) + FastMarkupPartitioner.MarkupPartition.access$2(partition)); FastMarkupPartitioner.MarkupPartition 
                tmp147_146 = parent;FastMarkupPartitioner.MarkupPartition.access$4(tmp147_146, FastMarkupPartitioner.MarkupPartition.access$2(tmp147_146) - FastMarkupPartitioner.MarkupPartition.access$2(partition));
              partitions.add(parentIndex, partition);
            }
          }
          else if (FastMarkupPartitioner.MarkupPartition.access$2(partition) + FastMarkupPartitioner.MarkupPartition.access$1(partition) == FastMarkupPartitioner.MarkupPartition.access$2(parent) + FastMarkupPartitioner.MarkupPartition.access$1(parent))
          {
            FastMarkupPartitioner.MarkupPartition.access$4(parent, FastMarkupPartitioner.MarkupPartition.access$1(partition) - FastMarkupPartitioner.MarkupPartition.access$1(parent));
            partitions.add(parentIndex + 1, partition);
          }
          else
          {
            parentLength = FastMarkupPartitioner.MarkupPartition.access$2(parent);
            FastMarkupPartitioner.MarkupPartition.access$4(parent, FastMarkupPartitioner.MarkupPartition.access$1(partition) - FastMarkupPartitioner.MarkupPartition.access$1(parent));
            int splitOffset = FastMarkupPartitioner.MarkupPartition.access$1(partition) + FastMarkupPartitioner.MarkupPartition.access$2(partition);
            FastMarkupPartitioner.MarkupPartition trailer = new FastMarkupPartitioner.MarkupPartition(FastMarkupPartitioner.MarkupPartition.access$5(parent), splitOffset, FastMarkupPartitioner.MarkupPartition.access$1(parent) + 
              parentLength - splitOffset, null);
            partitions.add(parentIndex + 1, partition);
            partitions.add(parentIndex + 2, trailer);
            parent = trailer;
          }
        }
        if (!block.getChildren().isEmpty()) {
          for (Segment<?> child : block.getChildren().asList()) {
            partition = createRegions(partition, child);
          }
        }
      }
    }
    return parent;
  }
  
  private boolean filtered(Block block)
  {
    if (block.getType() == null) {
      return false;
    }
    switch (block.getType())
    {
    case PREFORMATTED: 
    case TABLE: 
    case TABLE_CELL_HEADER: 
    case TABLE_CELL_NORMAL: 
    case TIP: 
    case WARNING: 
      return true;
    case BULLETED_LIST: 
      if ((block.getParent() != null) && (block.getParent().getType() == DocumentBuilder.BlockType.QUOTE)) {
        return true;
      }
      break;
    case PANEL: 
    case PARAGRAPH: 
    case TABLE_ROW: 
      return (block.getParent() != null) && (filtered(block.getParent()));
    }
    return false;
  }
  
  public void endHeading()
  {
    currentBlock = currentBlock.getParent();
    if (currentBlock == null) {
      throw new IllegalStateException();
    }
  }
  
  public void endSpan()
  {
    if (currentSpan == null) {
      throw new IllegalStateException();
    }
    if ((currentSpan.getParent() instanceof Span)) {
      currentSpan = ((Span)currentSpan.getParent());
    } else {
      currentSpan = null;
    }
  }
  
  public void entityReference(String entity) {}
  
  public void image(Attributes attributes, String url) {}
  
  public void imageLink(Attributes linkAttributes, Attributes attributes, String href, String imageUrl) {}
  
  public void lineBreak() {}
  
  public void link(Attributes attributes, String hrefOrHashName, String text) {}
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.ui.editor.syntax.FastMarkupPartitioner.PartitionBuilder
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.ui.editor.syntax;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.mylyn.internal.wikitext.core.util.css.CssParser;
import org.eclipse.mylyn.internal.wikitext.core.util.css.CssRule;
import org.eclipse.mylyn.internal.wikitext.ui.WikiTextUiPlugin;
import org.eclipse.mylyn.internal.wikitext.ui.editor.preferences.Preferences;
import org.eclipse.mylyn.internal.wikitext.ui.viewer.CssStyleManager;
import org.eclipse.mylyn.internal.wikitext.ui.viewer.FontState;
import org.eclipse.mylyn.wikitext.core.parser.Attributes;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Font;

public class MarkupTokenScanner
  implements ITokenScanner
{
  private Token currentToken = null;
  private Iterator<Token> tokenIt = null;
  private CssStyleManager styleManager;
  private FontState defaultState;
  private Preferences preferences;
  private final CssParser cssParser = new CssParser();
  
  public MarkupTokenScanner(Font defaultFont, Font defaultMonospaceFont)
  {
    initialize(defaultFont, defaultMonospaceFont);
    reloadPreferences();
  }
  
  public void resetFonts(Font defaultFont, Font defaultMonospaceFont)
  {
    if (defaultFont == null) {
      throw new IllegalArgumentException();
    }
    initialize(defaultFont, defaultMonospaceFont);
  }
  
  private void initialize(Font defaultFont, Font defaultMonospaceFont)
  {
    styleManager = new CssStyleManager(defaultFont, defaultMonospaceFont);
    defaultState = styleManager.createDefaultFontState();
  }
  
  public void reloadPreferences()
  {
    preferences = WikiTextUiPlugin.getDefault().getPreferences();
  }
  
  public int getTokenLength()
  {
    return currentToken == null ? -1 : currentToken.getLength();
  }
  
  public int getTokenOffset()
  {
    return currentToken == null ? -1 : currentToken.getOffset();
  }
  
  public IToken nextToken()
  {
    if ((tokenIt != null) && (tokenIt.hasNext()))
    {
      currentToken = ((Token)tokenIt.next());
    }
    else
    {
      currentToken = null;
      tokenIt = null;
      return Token.EOF;
    }
    return currentToken;
  }
  
  public void setRange(IDocument document, int offset, int length)
  {
    IDocumentPartitioner partitioner = document.getDocumentPartitioner();
    List<Token> tokens = null;
    if ((partitioner instanceof FastMarkupPartitioner))
    {
      FastMarkupPartitioner fastMarkupPartitioner = (FastMarkupPartitioner)partitioner;
      ITypedRegion[] partitioning = partitioner.computePartitioning(offset, length);
      if (partitioning != null)
      {
        tokens = new ArrayList();
        
        ITypedRegion[] partitions = ((FastMarkupPartitioner)partitioner).getScanner().computePartitions(
          document, offset, length);
        int lastEnd = offset;
        
        StyleRange styleRange = styleManager.createStyleRange(defaultState, 0, 1);
        TextAttribute textAttribute = createTextAttribute(styleRange);
        Token defaultToken = new Token(defaultState, textAttribute, offset, length);
        if (partitions != null)
        {
          ITypedRegion[] arrayOfITypedRegion1;
          TextAttribute localTextAttribute1 = (arrayOfITypedRegion1 = partitions).length;
          for (textAttribute = 0; textAttribute < localTextAttribute1; textAttribute++)
          {
            ITypedRegion region = arrayOfITypedRegion1[textAttribute];
            if (region.getOffset() >= offset + length) {
              break;
            }
            if (region.getOffset() + region.getLength() >= offset) {
              if ((region instanceof FastMarkupPartitioner.MarkupPartition))
              {
                FastMarkupPartitioner.MarkupPartition partition = (FastMarkupPartitioner.MarkupPartition)region;
                if (lastEnd < partition.getOffset())
                {
                  Token blockBridgeToken = new Token(fontState, defaultToken.getData(), 
                    lastEnd, partition.getOffset() - lastEnd);
                  addToken(tokens, blockBridgeToken);
                }
                Token blockToken = createToken(partition);
                if (blockToken == null) {
                  blockToken = defaultToken;
                }
                if (!partition.getBlock().isSpansComputed()) {
                  fastMarkupPartitioner.reparse(document, partition.getBlock());
                }
                List<Span> spans = partition.getSpans();
                if (spans != null) {
                  for (Span span : spans) {
                    if (span.getOffset() >= lastEnd)
                    {
                      Token spanToken = createToken(blockToken.getFontState(), span);
                      if (spanToken != null)
                      {
                        int blockTokenStartOffset = lastEnd < offset ? offset : lastEnd;
                        if (blockTokenStartOffset < spanToken.getOffset())
                        {
                          int blockTokenLength = spanToken.getOffset() - blockTokenStartOffset;
                          Token blockBridgeToken = new Token(fontState, 
                            blockToken.getData(), blockTokenStartOffset, blockTokenLength);
                          addToken(tokens, blockBridgeToken);
                        }
                        Token[] spanTokens = null;
                        if (!span.getChildren().isEmpty()) {
                          spanTokens = splitSpan(spanToken, span, defaultToken);
                        }
                        if (spanTokens != null)
                        {
                          Token[] arrayOfToken1;
                          int j = (arrayOfToken1 = spanTokens).length;
                          for (int i = 0; i < j; i++)
                          {
                            Token spanSplitToken = arrayOfToken1[i];
                            addToken(tokens, spanSplitToken);
                          }
                        }
                        else
                        {
                          addToken(tokens, spanToken);
                        }
                        lastEnd = offset + length;
                        if (lastEnd > partition.getOffset() + partition.getLength()) {
                          throw new IllegalStateException();
                        }
                      }
                    }
                  }
                }
                int partitionEnd = partition.getOffset() + partition.getLength();
                if (lastEnd < partitionEnd)
                {
                  int realLastEnd = Math.max(lastEnd, partition.getOffset());
                  int diff = partitionEnd - realLastEnd;
                  if (diff > 0)
                  {
                    int blockTokenStartOffset = realLastEnd;
                    int blockTokenLength = diff;
                    Token blockBridgeToken = new Token(fontState, 
                      blockToken.getData(), blockTokenStartOffset, blockTokenLength);
                    addToken(tokens, blockBridgeToken);
                    lastEnd = blockTokenStartOffset + blockTokenLength;
                    if (lastEnd > partition.getOffset() + partition.getLength()) {
                      throw new IllegalStateException();
                    }
                  }
                }
              }
            }
          }
        }
        if (lastEnd < offset + length) {
          addToken(tokens, new Token(fontState, defaultToken.getData(), lastEnd, length - (
            lastEnd - offset)));
        }
      }
    }
    currentToken = null;
    if ((tokens == null) || (tokens.isEmpty()))
    {
      tokenIt = null;
    }
    else
    {
      Iterator<Token> it = tokens.iterator();
      while (it.hasNext())
      {
        Token next = (Token)it.next();
        if (next.getOffset() < offset) {
          it.remove();
        } else if (next.getOffset() + next.getLength() > offset + length) {
          it.remove();
        }
      }
      tokenIt = tokens.iterator();
    }
  }
  
  protected TextAttribute createTextAttribute(StyleRange styleRange)
  {
    int fontStyle = fontStyle;
    if (strikeout) {
      fontStyle |= 0x20000000;
    }
    if (underline) {
      fontStyle |= 0x40000000;
    }
    return new TextAttribute(foreground, background, fontStyle, font);
  }
  
  private Token[] splitSpan(Token spanToken, Span span, Token defaultToken)
  {
    List<Token> tokens = new ArrayList(span.getChildren().size() + 1);
    int previousEnd = offset;
    for (Span child : span.getChildren().asList())
    {
      if (child.getOffset() > previousEnd) {
        tokens.add(new Token(fontState, spanToken.getData(), previousEnd, child.getOffset() - 
          previousEnd));
      }
      Token childToken = createToken(fontState, child);
      TextAttribute textAttribute;
      if (childToken == null)
      {
        StyleRange styleRange = styleManager.createStyleRange(fontState, 0, 1);
        textAttribute = createTextAttribute(styleRange);
        childToken = new Token(fontState, textAttribute, child.getOffset(), child.getLength());
      }
      if (child.getChildren().isEmpty())
      {
        tokens.add(childToken);
      }
      else
      {
        Token[] arrayOfToken;
        TextAttribute localTextAttribute1 = (arrayOfToken = splitSpan(childToken, child, defaultToken)).length;
        for (textAttribute = 0; textAttribute < localTextAttribute1; textAttribute++)
        {
          Token t = arrayOfToken[textAttribute];
          tokens.add(t);
        }
      }
      previousEnd = child.getEndOffset();
    }
    if (previousEnd < span.getEndOffset()) {
      tokens.add(new Token(fontState, spanToken.getData(), previousEnd, span.getEndOffset() - 
        previousEnd));
    }
    return (Token[])tokens.toArray(new Token[tokens.size()]);
  }
  
  private void addToken(List<Token> tokens, Token newToken)
  {
    checkAddToken(tokens, newToken);
    tokens.add(newToken);
  }
  
  private void checkAddToken(List<Token> tokens, Token newToken)
  {
    if (newToken.getLength() <= 0) {
      throw new IllegalStateException(NLS.bind(Messages.MarkupTokenScanner_badTokenLength, 
        new Object[] { Integer.valueOf(newToken.getLength()) }));
    }
    if (newToken.getOffset() < 0) {
      throw new IllegalStateException(NLS.bind(Messages.MarkupTokenScanner_badTokenOffset, 
        new Object[] { Integer.valueOf(newToken.getOffset()) }));
    }
    if (!tokens.isEmpty())
    {
      Token previous = (Token)tokens.get(tokens.size() - 1);
      if (previous.getOffset() >= newToken.getOffset()) {
        throw new IllegalStateException(Messages.MarkupTokenScanner_2);
      }
      if (previous.getOffset() + previous.getLength() > newToken.getOffset()) {
        throw new IllegalStateException(Messages.MarkupTokenScanner_3);
      }
    }
  }
  
  private Token createToken(FontState parentState, Span span)
  {
    if (span.getLength() == 0) {
      return null;
    }
    String cssStyles = null;
    String key = null;
    switch (span.getType())
    {
    case DELETED: 
      key = "**bold**";
      break;
    case EMPHASIS: 
      key = "??citation??";
      break;
    case SPAN: 
      key = "@code@";
      break;
    case INSERTED: 
      key = "-deleted text-";
      break;
    case BOLD: 
      key = "_emphasis_";
      break;
    case ITALIC: 
      key = "+inserted text+";
      break;
    case CODE: 
      key = "__italic__";
      break;
    case STRONG: 
      key = "monospace";
      break;
    case SUPERSCRIPT: 
      key = "quote";
      break;
    case QUOTE: 
      key = "%span%";
      break;
    case CITATION: 
      key = "*strong*";
      break;
    case MONOSPACE: 
      key = "~subscript~";
      break;
    case LINK: 
      key = "^superscript^";
      break;
    case SUBSCRIPT: 
      key = "underlined";
    }
    cssStyles = (String)preferences.getCssByPhraseModifierType().get(key);
    if ((cssStyles == null) && (span.getAttributes().getCssStyle() == null) && (span.getChildren().isEmpty())) {
      return null;
    }
    FontState fontState = new FontState(parentState);
    if (cssStyles != null) {
      processCssStyles(fontState, parentState, cssStyles);
    }
    if (span.getAttributes().getCssStyle() != null) {
      processCssStyles(fontState, parentState, span.getAttributes().getCssStyle());
    }
    StyleRange styleRange = styleManager.createStyleRange(fontState, 0, 1);
    
    TextAttribute textAttribute = createTextAttribute(styleRange);
    return new Token(fontState, textAttribute, span.getOffset(), span.getLength());
  }
  
  private Token createToken(FastMarkupPartitioner.MarkupPartition partition)
  {
    if (partition.getLength() == 0) {
      return null;
    }
    FontState fontState = new FontState(defaultState);
    boolean hasStyles = processStyles(partition.getBlock(), partition, fontState);
    if (partition.getBlock().getAttributes().getCssStyle() != null) {
      processCssStyles(fontState, defaultState, partition.getBlock().getAttributes().getCssStyle());
    } else if (!hasStyles) {
      return null;
    }
    StyleRange styleRange = styleManager.createStyleRange(fontState, 0, 1);
    
    TextAttribute textAttribute = createTextAttribute(styleRange);
    return new Token(fontState, textAttribute, partition.getOffset(), partition.getLength());
  }
  
  private boolean processStyles(Block block, FastMarkupPartitioner.MarkupPartition partition, FontState fontState)
  {
    boolean hasStyles = false;
    if (block.getParent() != null) {
      hasStyles = processStyles(block.getParent(), partition, fontState);
    }
    String cssStyles = computeCssStyles(block, partition);
    if (cssStyles != null)
    {
      hasStyles = true;
      processCssStyles(fontState, defaultState, cssStyles);
    }
    return hasStyles;
  }
  
  private String computeCssStyles(Block block, FastMarkupPartitioner.MarkupPartition partition)
  {
    String cssStyles = null;
    if (block.getHeadingLevel() > 0)
    {
      cssStyles = (String)preferences.getCssByBlockModifierType().get(
        Preferences.HEADING_PREFERENCES[block.getHeadingLevel()]);
    }
    else if (block.getType() != null)
    {
      String key = null;
      switch (block.getType())
      {
      case NOTE: 
        key = "bc.";
        break;
      case LIST_ITEM: 
        key = "bq.";
        break;
      case NUMERIC_LIST: 
        key = "pre.";
      }
      cssStyles = (String)preferences.getCssByBlockModifierType().get(key);
    }
    return cssStyles;
  }
  
  private void processCssStyles(FontState fontState, FontState parentState, String cssStyles)
  {
    Iterator<CssRule> ruleIterator = cssParser.createRuleIterator(cssStyles);
    while (ruleIterator.hasNext()) {
      styleManager.processCssStyles(fontState, parentState, (CssRule)ruleIterator.next());
    }
  }
  
  public static class Token
    extends Token
  {
    private final int offset;
    private final int length;
    private final FontState fontState;
    
    public Token(FontState fontState, TextAttribute attribute, int offset, int length)
    {
      super();
      this.fontState = fontState;
      if (offset < 0) {
        throw new IllegalArgumentException();
      }
      if (length < 0) {
        throw new IllegalArgumentException();
      }
      this.offset = offset;
      this.length = length;
    }
    
    public int getOffset()
    {
      return offset;
    }
    
    public int getLength()
    {
      return length;
    }
    
    public FontState getFontState()
    {
      return fontState;
    }
    
    public TextAttribute getData()
    {
      return (TextAttribute)super.getData();
    }
    
    public String toString()
    {
      return "Token [offset=" + offset + ", length=" + length + "]";
    }
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.ui.editor.syntax.MarkupTokenScanner
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.ui.editor.syntax;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.mylyn.wikitext.core.parser.Attributes;
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.Locator;
import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
import org.eclipse.osgi.util.NLS;

public class FastMarkupPartitioner
  extends FastPartitioner
{
  public static final String CONTENT_TYPE_MARKUP = "__markup_block";
  public static final String[] ALL_CONTENT_TYPES = { "__markup_block" };
  static boolean debug = Boolean.getBoolean(FastMarkupPartitioner.class.getName() + ".debug");
  private MarkupLanguage markupLanguage;
  
  public FastMarkupPartitioner()
  {
    super(new PartitionTokenScanner(), ALL_CONTENT_TYPES);
  }
  
  public MarkupLanguage getMarkupLanguage()
  {
    return markupLanguage;
  }
  
  public void setMarkupLanguage(MarkupLanguage markupLanguage)
  {
    this.markupLanguage = markupLanguage;
    getScanner().setMarkupLanguage(markupLanguage);
    resetPartitions();
  }
  
  PartitionTokenScanner getScanner()
  {
    return (PartitionTokenScanner)fScanner;
  }
  
  public void resetPartitions()
  {
    if (fDocument != null)
    {
      super.flushRewriteSession();
      initialize();
    }
    else
    {
      clearPositionCache();
    }
  }
  
  static class PartitionTokenScanner
    implements IPartitionTokenScanner
  {
    private final Map<Integer, PartitioningResult> cachedPartitioning = new HashMap();
    private MarkupLanguage markupLanguage;
    private int index = -1;
    private PartitioningResult lastComputed;
    
    private static class PartitioningResult
    {
      int offset;
      int length;
      ITypedRegion[] partitions;
      
      public PartitioningResult(int offset, int length, ITypedRegion[] partitions)
      {
        this.offset = offset;
        this.length = length;
        this.partitions = partitions;
      }
      
      public boolean overlapsWith(PartitioningResult other)
      {
        int end = offset + length;
        int thisEnd = offset + length;
        if (end > thisEnd) {
          return offset < thisEnd;
        }
        if (thisEnd > end) {
          return offset < end;
        }
        return true;
      }
    }
    
    public ITypedRegion[] computePartitions(IDocument document, int offset, int length)
    {
      if ((lastComputed != null) && (lastComputed.offset <= offset) && 
        (lastComputed.offset + lastComputed.length >= offset + length)) {
        return lastComputed.partitions;
      }
      PartitioningResult result = (PartitioningResult)cachedPartitioning.get(Integer.valueOf(offset));
      if ((result == null) || (length != length))
      {
        result = computeOlp(document, offset, length, -1);
        updateCache(result, document.getLength());
      }
      return partitions;
    }
    
    public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset)
    {
      lastComputed = computeOlp(document, offset, length, partitionOffset);
      index = -1;
      updateCache(lastComputed, document.getLength());
    }
    
    private void updateCache(PartitioningResult updated, int maxLength)
    {
      Iterator<PartitioningResult> it = cachedPartitioning.values().iterator();
      while (it.hasNext())
      {
        PartitioningResult result = (PartitioningResult)it.next();
        if ((offset >= maxLength) || ((updated != null) && (result.overlapsWith(updated)))) {
          it.remove();
        }
      }
      if (updated != null) {
        cachedPartitioning.put(Integer.valueOf(offset), updated);
      }
    }
    
    private PartitioningResult computeOlp(IDocument document, int offset, int length, int partitionOffset)
    {
      if (markupLanguage == null) {
        return new PartitioningResult(offset, length, null);
      }
      int startOffset = partitionOffset == -1 ? offset : Math.min(offset, partitionOffset);
      int endOffset = offset + length;
      
      MarkupParser markupParser = new MarkupParser(markupLanguage);
      markupLanguage.setBlocksOnly(partitionOffset != -1);
      markupLanguage.setFilterGenerativeContents(true);
      FastMarkupPartitioner.PartitionBuilder partitionBuilder = new FastMarkupPartitioner.PartitionBuilder(startOffset, markupLanguage.isBlocksOnly());
      markupParser.setBuilder(partitionBuilder);
      String markupContent;
      try
      {
        markupContent = document.get(startOffset, endOffset - startOffset);
      }
      catch (BadLocationException localBadLocationException)
      {
        String markupContent;
        markupContent = document.get();
      }
      markupParser.parse(markupContent);
      
      ITypedRegion[] latestPartitions = (ITypedRegion[])partitions.toArray(new ITypedRegion[partitions.size()]);
      List<ITypedRegion> partitioning = new ArrayList(latestPartitions.length);
      
      ITypedRegion previous = null;
      ITypedRegion[] arrayOfITypedRegion1;
      int j = (arrayOfITypedRegion1 = latestPartitions).length;
      for (int i = 0; i < j; i++)
      {
        ITypedRegion region = arrayOfITypedRegion1[i];
        if (region.getLength() != 0)
        {
          if ((previous != null) && (region.getOffset() < previous.getOffset() + previous.getLength()))
          {
            String message = NLS.bind(Messages.FastMarkupPartitioner_0, new Object[] { region, previous, 
              markupLanguage.getName() });
            if (FastMarkupPartitioner.debug)
            {
              String markupSavePath = FastMarkupPartitioner.saveToTempFile(markupLanguage, markupContent);
              message = NLS.bind(Messages.FastMarkupPartitioner_1, new Object[] { message, markupSavePath });
            }
            throw new IllegalStateException(message);
          }
          previous = region;
          if ((region.getOffset() >= startOffset) && (region.getOffset() < endOffset)) {
            partitioning.add(region);
          } else {
            if (region.getOffset() >= offset + length) {
              break;
            }
          }
        }
      }
      return new PartitioningResult(offset, length, (ITypedRegion[])partitioning.toArray(new ITypedRegion[partitioning.size()]));
    }
    
    public void setMarkupLanguage(MarkupLanguage markupLanguage)
    {
      this.markupLanguage = markupLanguage;
    }
    
    public int getTokenLength()
    {
      return lastComputed.partitions[index].getLength();
    }
    
    public int getTokenOffset()
    {
      return lastComputed.partitions[index].getOffset();
    }
    
    public IToken nextToken()
    {
      if ((lastComputed == null) || (lastComputed.partitions == null) || (++index >= lastComputed.partitions.length)) {
        return Token.EOF;
      }
      return new Token(lastComputed.partitions[index].getType());
    }
    
    public void setRange(IDocument document, int offset, int length)
    {
      setPartialRange(document, offset, length, null, -1);
    }
  }
  
  public static class MarkupPartition
    implements ITypedRegion
  {
    private final Block block;
    private int offset;
    private int length;
    private List<Span> spans;
    
    private MarkupPartition(Block block, int offset, int length)
    {
      this.block = block;
      this.offset = offset;
      this.length = length;
    }
    
    public int getOffset()
    {
      return offset;
    }
    
    public int getLength()
    {
      return length;
    }
    
    public String getType()
    {
      return "__markup_block";
    }
    
    public Block getBlock()
    {
      return block;
    }
    
    public List<Span> getSpans()
    {
      if (this.spans == null)
      {
        List<Span> spans = new ArrayList();
        getSpans(block, spans);
        this.spans = spans;
      }
      return this.spans;
    }
    
    private void getSpans(Block block, List<Span> spans)
    {
      for (Segment<?> s : block.getChildren().asList()) {
        if ((s.getOffset() >= offset) && (s.getOffset() < offset + length)) {
          if ((s instanceof Span)) {
            spans.add((Span)s);
          } else {
            getSpans((Block)s, spans);
          }
        }
      }
    }
    
    public String toString()
    {
      return String.format("MarkupPartition(type=%s,offset=%s,length=%s,end=%s)", new Object[] { block.getType(), Integer.valueOf(offset), 
        Integer.valueOf(length), Integer.valueOf(offset + length) });
    }
  }
  
  private static class PartitionBuilder
    extends DocumentBuilder
  {
    private final Block outerBlock = new Block(null, 0, 1073741823);
    private Block currentBlock = outerBlock;
    private Span currentSpan = null;
    private final int offset;
    private List<FastMarkupPartitioner.MarkupPartition> partitions;
    private final boolean blocksOnly;
    
    public PartitionBuilder(int offset, boolean blocksOnly)
    {
      this.offset = offset;
      this.blocksOnly = blocksOnly;
    }
    
    public void acronym(String text, String definition) {}
    
    public void beginBlock(DocumentBuilder.BlockType type, Attributes attributes)
    {
      int newBlockOffset = getLocator().getDocumentOffset() + offset;
      Block newBlock = new Block(type, attributes, newBlockOffset, currentBlock.getLength() - (
        newBlockOffset - currentBlock.getOffset()));
      newBlock.setSpansComputed(!blocksOnly);
      currentBlock.add(newBlock);
      currentBlock = newBlock;
    }
    
    public void beginDocument() {}
    
    public void beginHeading(int level, Attributes attributes)
    {
      int newBlockOffset = getLocator().getDocumentOffset() + offset;
      Block newBlock = new Block(level, attributes, newBlockOffset, currentBlock.getLength() - (
        newBlockOffset - currentBlock.getOffset()));
      newBlock.setSpansComputed(!blocksOnly);
      currentBlock.add(newBlock);
      currentBlock = newBlock;
    }
    
    public void beginSpan(DocumentBuilder.SpanType type, Attributes attributes)
    {
      Span span = new Span(type, attributes, getLocator().getDocumentOffset() + offset, 
        getLocator().getLineSegmentEndOffset() - getLocator().getLineCharacterOffset());
      if (currentSpan != null)
      {
        currentSpan.add(span);
        currentSpan = span;
      }
      else
      {
        currentSpan = span;
        currentBlock.add(span);
      }
    }
    
    public void characters(String text) {}
    
    public void charactersUnescaped(String literal) {}
    
    public void endBlock()
    {
      currentBlock = currentBlock.getParent();
      if (currentBlock == null) {
        throw new IllegalStateException();
      }
    }
    
    public void endDocument()
    {
      if (currentBlock != outerBlock) {
        throw new IllegalStateException();
      }
      Locator locator = getLocator();
      outerBlock.setLength((locator == null ? 0 : locator.getDocumentOffset()) + offset);
      
      partitions = new ArrayList();
      for (Segment<?> child : outerBlock.getChildren().asList()) {
        createRegions(null, child);
      }
    }
    
    public FastMarkupPartitioner.MarkupPartition createRegions(FastMarkupPartitioner.MarkupPartition parent, Segment<?> segment)
    {
      if (segment.getLength() == 0) {
        return parent;
      }
      if ((segment instanceof Block))
      {
        Block block = (Block)segment;
        if (!filtered(block))
        {
          FastMarkupPartitioner.MarkupPartition partition = new FastMarkupPartitioner.MarkupPartition(block, segment.getOffset(), segment.getLength(), null);
          int parentLength;
          if (parent == null)
          {
            partitions.add(partition);
          }
          else
          {
            int parentIndex = partitions.indexOf(parent);
            if (offset == offset)
            {
              if (length == length)
              {
                partitions.remove(parentIndex);
                partitions.add(parentIndex, partition);
              }
              else
              {
                offset += length;
                length -= length;
                partitions.add(parentIndex, partition);
              }
            }
            else if (length + offset == length + offset)
            {
              length = (offset - offset);
              partitions.add(parentIndex + 1, partition);
            }
            else
            {
              parentLength = length;
              length = (offset - offset);
              int splitOffset = offset + length;
              FastMarkupPartitioner.MarkupPartition trailer = new FastMarkupPartitioner.MarkupPartition(block, splitOffset, offset + 
                parentLength - splitOffset, null);
              partitions.add(parentIndex + 1, partition);
              partitions.add(parentIndex + 2, trailer);
              parent = trailer;
            }
          }
          if (!block.getChildren().isEmpty()) {
            for (Segment<?> child : block.getChildren().asList()) {
              partition = createRegions(partition, child);
            }
          }
        }
      }
      return parent;
    }
    
    private boolean filtered(Block block)
    {
      if (block.getType() == null) {
        return false;
      }
      switch (block.getType())
      {
      case PREFORMATTED: 
      case TABLE: 
      case TABLE_CELL_HEADER: 
      case TABLE_CELL_NORMAL: 
      case TIP: 
      case WARNING: 
        return true;
      case BULLETED_LIST: 
        if ((block.getParent() != null) && (block.getParent().getType() == DocumentBuilder.BlockType.QUOTE)) {
          return true;
        }
        break;
      case PANEL: 
      case PARAGRAPH: 
      case TABLE_ROW: 
        return (block.getParent() != null) && (filtered(block.getParent()));
      }
      return false;
    }
    
    public void endHeading()
    {
      currentBlock = currentBlock.getParent();
      if (currentBlock == null) {
        throw new IllegalStateException();
      }
    }
    
    public void endSpan()
    {
      if (currentSpan == null) {
        throw new IllegalStateException();
      }
      if ((currentSpan.getParent() instanceof Span)) {
        currentSpan = ((Span)currentSpan.getParent());
      } else {
        currentSpan = null;
      }
    }
    
    public void entityReference(String entity) {}
    
    public void image(Attributes attributes, String url) {}
    
    public void imageLink(Attributes linkAttributes, Attributes attributes, String href, String imageUrl) {}
    
    public void lineBreak() {}
    
    public void link(Attributes attributes, String hrefOrHashName, String text) {}
  }
  
  public void reparse(IDocument document, Block block)
  {
    MarkupParser markupParser = new MarkupParser(markupLanguage);
    markupLanguage.setBlocksOnly(false);
    markupLanguage.setFilterGenerativeContents(true);
    PartitionBuilder partitionBuilder = new PartitionBuilder(block.getOffset(), false);
    markupParser.setBuilder(partitionBuilder);
    try
    {
      markupParser.parse(document.get(block.getOffset(), block.getLength()));
      for (Segment<?> s : outerBlock.getChildren().asList()) {
        if ((s.getOffset() == block.getOffset()) && 
          ((s instanceof Block)))
        {
          block.replaceChildren(s);
          block.setSpansComputed(true);
          break;
        }
      }
    }
    catch (BadLocationException e)
    {
      throw new IllegalStateException(e);
    }
  }
  
  /* Error */
  private static String saveToTempFile(MarkupLanguage markupLanguage, String markupContent)
  {
    // Byte code:
    //   0: aconst_null
    //   1: astore_2
    //   2: ldc 6
    //   4: new 107	java/lang/StringBuilder
    //   7: dup
    //   8: ldc 2
    //   10: invokespecial 219	java/lang/StringBuilder:<init>	(Ljava/lang/String;)V
    //   13: aload_0
    //   14: invokevirtual 244	org/eclipse/mylyn/wikitext/core/parser/markup/MarkupLanguage:getName	()Ljava/lang/String;
    //   17: invokevirtual 215	java/lang/String:toLowerCase	()Ljava/lang/String;
    //   20: ldc 4
    //   22: ldc 1
    //   24: invokevirtual 217	java/lang/String:replaceAll	(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //   27: invokevirtual 220	java/lang/StringBuilder:append	(Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   30: invokevirtual 218	java/lang/StringBuilder:toString	()Ljava/lang/String;
    //   33: invokestatic 208	java/io/File:createTempFile	(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;
    //   36: astore_3
    //   37: new 100	java/io/FileWriter
    //   40: dup
    //   41: aload_3
    //   42: invokespecial 209	java/io/FileWriter:<init>	(Ljava/io/File;)V
    //   45: astore 4
    //   47: aload 4
    //   49: aload_1
    //   50: invokevirtual 211	java/io/Writer:write	(Ljava/lang/String;)V
    //   53: goto +13 -> 66
    //   56: astore 5
    //   58: aload 4
    //   60: invokevirtual 210	java/io/Writer:close	()V
    //   63: aload 5
    //   65: athrow
    //   66: aload 4
    //   68: invokevirtual 210	java/io/Writer:close	()V
    //   71: aload_3
    //   72: invokevirtual 207	java/io/File:getAbsolutePath	()Ljava/lang/String;
    //   75: astore_2
    //   76: goto +4 -> 80
    //   79: pop
    //   80: aload_2
    //   81: areturn
    // Line number table:
    //   Java source line #528	-> byte code offset #0
    //   Java source line #530	-> byte code offset #2
    //   Java source line #531	-> byte code offset #13
    //   Java source line #530	-> byte code offset #33
  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

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