/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.helpers;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.text.rules.Token;
import de.innovationgate.eclipse.editors.Plugin;
import de.innovationgate.eclipse.editors.tml.TokenBean;
public abstract class WrappedRuleBasedPartionScanner extends RuleBasedPartitionScanner {
private TokenBean _currentToken;
private Iterator<TokenBean> _tokensiter;
private IToken _defaultReturnToken;
protected IDocument _document;
private int _offset;
private String _contentType;
private int _length;
private int _partitionOffset;
private boolean _partialScanning;
@Override
public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
_document = document;
_offset = offset;
_length = length;
_contentType = contentType;
_partitionOffset = partitionOffset;
_partialScanning = true;
_tokensiter = computeTokens().iterator();
}
@Override
public int getTokenLength() {
if (_currentToken != null) {
return _currentToken.getLength();
} else {
return 0;
}
}
@Override
public int getTokenOffset() {
if (_currentToken != null) {
return _currentToken.getOffset();
} else {
return 0;
}
}
@Override
public IToken nextToken() {
if (_tokensiter.hasNext()) {
_currentToken = _tokensiter.next();
if (Plugin.getDefault().isDebugging()) {
System.out.println(_currentToken);
}
return _currentToken.getToken();
} else {
_currentToken = null;
return Token.EOF;
}
}
@Override
public void setRange(IDocument document, int offset, int length) {
_document = document;
_offset = offset;
_length = length;
_partialScanning = false;
_tokensiter = computeTokens().iterator();
}
public List<TokenBean> computeTokens() {
return computeTokens(false);
}
public List<TokenBean> computeTokens(boolean filterEOF) {
// init rule scanner
if (_partialScanning) {
getRuleScanner().setPartialRange(_document, _offset, _length, _contentType, _partitionOffset);
} else {
getRuleScanner().setRange(_document, _offset, _length);
}
List<TokenBean> tokens = new ArrayList<TokenBean>();
IToken tmptoken;
do {
tmptoken = getRuleScanner().nextToken();
if (filterEOF && tmptoken.equals(Token.EOF)) {
continue;
} else {
TokenBean bean = new TokenBean();
bean.setToken(tmptoken, getRuleScanner().getTokenLength(), getRuleScanner().getTokenOffset());
tokens.add(bean);
}
} while (!tmptoken.equals(Token.EOF));
List<IToken> typelist = new ArrayList<IToken>();
typelist.add(new Token(null));
if (_defaultReturnToken != null) {
typelist.add(_defaultReturnToken);
}
return sumUnknownInTokenList(tokens, typelist);
}
/**
* should return the rule scanner to wrap, each call has to return the same instance
* @return
*/
public abstract RuleBasedPartitionScanner getRuleScanner();
@Override
public void setDefaultReturnToken(IToken defaultReturnToken) {
super.setDefaultReturnToken(defaultReturnToken);
getRuleScanner().setDefaultReturnToken(defaultReturnToken);
_defaultReturnToken = defaultReturnToken;
}
protected void printTokenList(List<TokenBean> tokens) {
int zeahl = 0;
TokenBean tmpbean = new TokenBean();
Iterator<TokenBean> inter = tokens.iterator();
while (inter.hasNext()) {
zeahl++;
tmpbean = inter.next();
if (Plugin.getDefault().isDebugging()) {
System.out.println(zeahl + tmpbean.toString());
}
}
}
protected boolean equals(IToken token1, IToken token2) {
Object data1 = token1.getData();
Object data2 = token2.getData();
if(data1==null && data2 == null)
return true;
else {
if(data1!=null){
return data1.equals(data2);
}else{
return data2.equals(data1);
}
}
}
protected List<TokenBean> sumUnknownInTokenList(List<TokenBean> listtosum,List<IToken> types) {
List<TokenBean> newlist= new ArrayList<TokenBean>();
for(int i=0;i<listtosum.size();i++){
TokenBean current = listtosum.get(i);
if(isTokenInList(current.getToken(), types)){
int sumTokenLenght=0;
int j=i;
TokenBean next = null;
if (i < listtosum.size()-1) {
next = listtosum.get(i+1);
}
while(next != null && equals(current.getToken(), next.getToken())){
sumTokenLenght+=current.getLength();
j++;
current = listtosum.get(j);
if (j < listtosum.size() - 1) {
next = listtosum.get(j+1);
} else {
next = null;
}
}
TokenBean tokenAtSummingStart = listtosum.get(i);
TokenBean newTokenBean = new TokenBean();
newTokenBean.setToken(tokenAtSummingStart.getToken(), sumTokenLenght+current.getLength(), tokenAtSummingStart.getOffset());
newlist.add(newTokenBean);
i=j;
}
else{
newlist.add(current);
}
}
return newlist;
}
private boolean isTokenInList(IToken token, List<IToken> types){
Iterator<IToken> inter = types.iterator();
IToken currentToken;
while (inter.hasNext()) {
currentToken = inter.next();
if (equals(currentToken, token)) {
return true;
}
}
return false;
}
/*
public List<TokenBean>getTokensFromOffset(int offset, boolean includeEOF) {
Iterator<TokenBean> tokens = computeTokens().iterator();
List<TokenBean> filteredTokens = new ArrayList<TokenBean>();
while (tokens.hasNext()) {
TokenBean token = tokens.next();
if (!includeEOF && token.getToken().isEOF()) {
continue;
}
if (offset != 0 && offset - token.getOffset() < token.getLength()) {
// given offset is included in this token
// adapt token offset && length for include
int length = token.getLength() - (offset - token.getOffset());
if (length < 0) {
length = 0;
}
//token.setLength(length);
//token.setOffset(offset);
filteredTokens.add(token);
} else if (token.getOffset() >= offset) {
// token at offset or behind - just add
filteredTokens.add(token);
}
}
return filteredTokens;
}*/
}