package org.jbehave.eclipse.editor.story.scanner; import java.util.List; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; import org.jbehave.eclipse.JBehaveProject; import org.jbehave.eclipse.editor.step.LocalizedStepSupport; import org.jbehave.eclipse.editor.story.StoryDocumentUtils; import org.jbehave.eclipse.editor.story.StoryPartition; import org.jbehave.eclipse.parser.StoryElement; import org.jbehave.eclipse.parser.StoryVisitor; import org.jbehave.eclipse.util.New; public class StoryPartitionScanner implements org.eclipse.jface.text.rules.IPartitionTokenScanner { private final LocalizedStepSupport localizedStepSupport; // private IDocument document; // private int cursor; private Partition currentPartition; private List<Partition> partitions; public StoryPartitionScanner(JBehaveProject jbehaveProject) { this.localizedStepSupport = jbehaveProject.getLocalizedStepSupport(); } public void setRange(IDocument document, int offset, int length) { setPartialRange(document, offset, length, null, -1); } public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { this.document = document; initializePartitions(); } public int getTokenLength() { return currentPartition.length; } public int getTokenOffset() { return currentPartition.offset; } public IToken nextToken() { if(cursor<partitions.size()) { currentPartition = partitions.get(cursor++); return new Token(currentPartition.keyword.name()); } return Token.EOF; } private void initializePartitions() { partitions = New.arrayList(); cursor = 0; StoryVisitor visitor = new StoryVisitor() { @Override public void visit(StoryElement part) { push(part); } }; new StoryDocumentUtils(localizedStepSupport).traverseStory(document, visitor); } private void push(StoryElement part) { StoryPartition partition = StoryPartition.partitionOf(part.getPreferredKeyword()); Partition p = new Partition( partition, part.getOffset(), part.getLength()); if(partitions.isEmpty()) { partitions.add(p); return; } // pick last, merge it or add it to the list Partition last = partitions.get(partitions.size()-1); if(!last.merge(p)) partitions.add(p); } private class Partition { private StoryPartition keyword; private int offset; private int length; public Partition(StoryPartition keyword, int offset, int length) { this.keyword = keyword; this.offset = offset; this.length = length; } public boolean merge(Partition p) { if(keyword==p.keyword) { this.length += p.length; return true; } return false; } @Override public String toString() { return "P["+keyword+", offset: " + offset + ", length: " + length + "]"; } } }