blob: 16b84c52e0fa55f27f88f592c1ce81578e908049 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 ILOG and others.
* 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:
* Joel Cheuoua - Initial API and implementation
*******************************************************************************/
package org.eclipse.jet.internal.editor.contentassist;
import java.util.*;
import org.eclipse.jet.internal.editor.JETDocumentReader;
import org.eclipse.jet.internal.editor.JETTextEditor;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
public abstract class AbstractXMLTagsBasedAssistProcessor extends AbstractJETAssistProcessor {
private TreeSet keywordSet;
private TreeSet innerKeywordSet;
private TreeMap innerMap;
public AbstractXMLTagsBasedAssistProcessor(JETTextEditor editor) {
super(editor);
keywordSet = new TreeSet();
innerKeywordSet = new TreeSet();
innerMap = new TreeMap();
String tagAttrs[][] = getTagAttributes();
for (int i = 0; i < tagAttrs.length; i++)
keywordSet.add(tagAttrs[i][0]);
for (int i = 0; i < tagAttrs.length; i++) {
TreeSet innerSet = new TreeSet();
for (int j = 1; j < tagAttrs[i].length; j++) {
innerSet.add(tagAttrs[i][j]);
innerKeywordSet.add(tagAttrs[i][j]);
}
innerMap.put(tagAttrs[i][0], innerSet);
}
}
public abstract String[] getRootTags();
public abstract String[][] getTagAttributes();
public String[] getAllKeywords() {
return (String[]) keywordSet.toArray(new String[keywordSet.size()]);
}
public String[] getAllInnerKeywords() {
return (String[]) innerKeywordSet.toArray(new String[innerKeywordSet.size()]);
}
public String[] getInnerKeywordsFor(String key) {
TreeSet set = (TreeSet) (TreeSet) innerMap.get(key);
if (set == null && key.length() == 0)
return getRootTags();
else if (set != null)
return (String[]) set.toArray(new String[set.size()]);
return new String[0];
}
private boolean prefixMatches(String prefix, String word) {
prefix = prefix.toLowerCase();
return word.startsWith(prefix);
}
public String[] getAllWordsWithPrefix(String prefix) {
String all[] = getAllKeywords();
return getMatched(prefix, all);
}
private String[] getMatched(String prefix, String all[]) {
ArrayList matched = new ArrayList(10);
for (int i = 0; i < all.length; i++)
if (prefixMatches(prefix, all[i]))
matched.add(all[i]);
return (String[]) matched.toArray(new String[matched.size()]);
}
public String[] getTagsWithPrefix(String prefix) {
return getMatched(prefix, getRootTags());
}
public String[] getNonTagsKeywordsWithPrefix(String key, String prefix) {
return getMatched(prefix, getInnerKeywordsFor(key));
}
protected String[] getAllWords(char c, JETDocumentReader reader) {
ArrayList all = new ArrayList(20);
char currChar = c;
currChar = trimBlanksBackward(reader, currChar);
for (boolean done = false; !done;) {
Stack stack = new Stack();
for (; currChar != '\uFFFF' && !Character.isWhitespace(currChar); currChar = reader.readBackward())
stack.push(new Character(currChar));
String s;
for (s = new String(); !stack.empty(); s = (new StringBuilder(String.valueOf(s))).append(
((Character) stack.pop()).toString()).toString())
;
int jspPt = s.indexOf("<%@");
if (jspPt >= 0) {
s = s.substring(jspPt + 3);
done = true;
}
all.add(s);
currChar = trimBlanksBackward(reader, currChar);
if (currChar == '\uFFFF' || currChar == '@')
done = true;
}
return (String[]) all.toArray(new String[all.size()]);
}
private char trimBlanksBackward(JETDocumentReader reader, char currChar) {
for (; currChar != '\uFFFF' && Character.isWhitespace(currChar); currChar = reader.readBackward())
;
return currChar;
}
protected abstract char getRootTagPrevChar();
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
org.eclipse.jface.text.IDocument doc = viewer.getDocument();
JETDocumentReader reader = new JETDocumentReader(doc, offset);
char c = reader.readBackward();
ICompletionProposal result[] = (ICompletionProposal[]) null;
String allWords[] = getAllWords(c, reader);
if (Character.isSpaceChar(c)) {
String nonTagWords[] = getInnerKeywordsFor(allWords[allWords.length - 1]);
result = new ICompletionProposal[nonTagWords.length];
for (int i = 0; i < nonTagWords.length; i++)
result[i] = new CompletionProposal(nonTagWords[i], offset, 0, nonTagWords[i].length());
} else if (c == getRootTagPrevChar()) {
String words[] = getRootTags();
result = new ICompletionProposal[words.length];
for (int i = 0; i < words.length; i++)
result[i] = new CompletionProposal(words[i].substring(allWords[0].length()), offset, 0, words[i].length()
- allWords[0].length(), null, words[i], null, null);
} else if (Character.isLetter(c)) {
String words[];
if (allWords.length > 1)
words = getNonTagsKeywordsWithPrefix(allWords[allWords.length - 1], allWords[0]);
else
words = getTagsWithPrefix(allWords[0]);
result = new ICompletionProposal[words.length];
for (int i = 0; i < words.length; i++)
result[i] = new CompletionProposal(words[i].substring(allWords[0].length()), offset, 0, words[i].length()
- allWords[0].length(), null, words[i], null, null);
}
return result;
}
}