package com.liferay.ide.velocity.vaulttec.ui.editor.text; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import com.liferay.ide.velocity.ui.editor.xml.VelocityAutoIndentStrategy; /** * Guesses the start/end and the type of Velocity content (directive or * identifier) from a given offset. */ public class VelocityTextGuesser { public static final int TYPE_END = 6; public static final int TYPE_APOSTROPHE = 5; public static final int TYPE_INVALID = 0; public static final int TYPE_DIRECTIVE = 1; public static final int TAG_DIRECTIVE = 3; public static final int TAG_CLOSE = 4; public static final int TYPE_VARIABLE = 2; public static final int TYPE_MEMBER_QUALIFIER = 7; private int fType; private String fText; private int fLine; private int tagoffset = -1; private String fVariable; /** * Create an invalid text guesser. */ public VelocityTextGuesser() { fType = TYPE_INVALID; fText = ""; fVariable = ""; fLine = -1; } public VelocityTextGuesser(IDocument aDocument, int anOffset, boolean aGuessEnd) { String f = ""; try { // Guess start position int start = anOffset; while ((start >= 1) && isWordPart(aDocument.getChar(start - 1))) { start--; } // Guess end position int end = anOffset; if (aGuessEnd) { int len = aDocument.getLength() - 1; while ((end < len) && isWordPart(aDocument.getChar(end))) { end++; } } fText = aDocument.get(start, (end - start)); fLine = aDocument.getLineOfOffset(start) + 1; // Now guess fType of completion if (start >= 1) { // Directive or shorthand reference char c1 = aDocument.getChar(start - 1); char c0 = 0; try { c0 = aDocument.getChar(start - 2); } catch (Exception e) { // TODO: handle exception } try { f = VelocityAutoIndentStrategy.getVeloIdentifier(aDocument, start - 1, start + 4); } catch (Exception e) { // TODO: handle exception } if (f.equals("#end")) { fType = TYPE_END; tagoffset = start - 1; } else if (c1 == '#' || c1 == '@') { fType = TYPE_DIRECTIVE; } else if (c1 == '\"') { fType = TYPE_APOSTROPHE; } else if (c1 == '$') { fType = TYPE_VARIABLE; } else if (c1 == '.') { fType = TYPE_MEMBER_QUALIFIER; // try to find the variable name: int scan = end = start - 1; int line = aDocument.getLineOfOffset(scan); while ((scan >= 1) && (aDocument.getChar(scan - 1) != '$')) { scan--; } // if we moved to a different line, it cannot be a variable: if (aDocument.getLineOfOffset(scan) == line) { fVariable = aDocument.get(scan, (end - scan)); } else { fVariable = ""; } } else if (c1 == '<') { fType = TAG_DIRECTIVE; } else if ((c1 == '/') && (c0 == '<')) { fType = TAG_CLOSE; } else { if (start >= 2) { // Formal or quiet reference char c2 = aDocument.getChar(start - 2); if ((c2 == '$') && ((c1 == '{') || (c1 == '!'))) { fType = TYPE_VARIABLE; } else { if (start >= 3) { // Formal quiet reference char c3 = aDocument.getChar(start - 3); if (((c3 == '$') && (c2 == '!')) || (c1 == '{')) { fType = TYPE_VARIABLE; } } } // if(fType ==0) // fType = TAG_DIRECTIVE; } } } } catch (BadLocationException e) { fType = TYPE_INVALID; fText = ""; fLine = -1; } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getTagOffset() { return tagoffset; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getType() { return fType; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String getText() { return fText; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getLine() { return fLine; } /** * @return The variable, if the current position relates to a member qualifier (the dot). */ public String getVariable() { return fVariable; } /** * Determines if the specified character may be part of a Velocity * identifier as other than the first character. A character may be part of * a Velocity identifier if and only if it is one of the following: * <ul> * <li>a letter (a..z, A..Z) * <li>a digit (0..9) * <li>a hyphen ("-") * <li>a connecting punctuation character ("_") * </ul> * * @param aChar * the character to be tested. * @return true if the character may be part of a Velocity identifier; false * otherwise. * @see java.lang.Character#isLetterOrDigit(char) */ private static final boolean isWordPart(char aChar) { return Character.isLetterOrDigit(aChar) || (aChar == '-') || (aChar == '_') || (aChar == ':'); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String toString() { return "type=" + fType + ", text=" + fText + ", line=" + fLine; } }