Author: vrubezhny
Date: 2007-07-13 14:17:19 -0400 (Fri, 13 Jul 2007)
New Revision: 2437
Modified:
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELCompletionEngine.java
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalComputer.java
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalProcessor.java
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamExpressionResolver.java
Log:
http://jira.jboss.org/jira/browse/EXIN-330
comments are added
Modified:
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELCompletionEngine.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELCompletionEngine.java 2007-07-13
17:59:36 UTC (rev 2436)
+++
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELCompletionEngine.java 2007-07-13
18:17:19 UTC (rev 2437)
@@ -33,8 +33,16 @@
import org.jboss.tools.seam.core.ScopeType;
import org.jboss.tools.seam.ui.SeamGuiPlugin;
+/**
+ * Utility class used to find Seam Project content assist proposals
+ *
+ * @author Jeremy
+ */
public final class SeamELCompletionEngine {
+ /**
+ * Constructs SeamELCompletionEngine object
+ */
public SeamELCompletionEngine() {
}
@@ -206,6 +214,13 @@
return sb.toString();
}
+ /*
+ * Compares to tokenized expressions.
+ *
+ * @param first
+ * @param second
+ * @return boolean true if two expressions are equal
+ */
private boolean areEqualExpressions(List<ELToken>first, List<ELToken>second)
{
if (first == null || second == null)
return (first == second);
@@ -220,6 +235,12 @@
return true;
}
+ /* Returns scope for the resource
+ *
+ * @param project
+ * @param resource
+ * @return
+ */
private ScopeType getScope(ISeamProject project, IResource resource) {
if (project == null || resource == null)
return null;
@@ -233,8 +254,17 @@
}
return null;
}
-
- List<ISeamContextVariable> resolveVariables(ISeamProject project, ScopeType scope,
List<ELToken>part, List<ELToken> tokens) {
+
+ /*
+ * Tries to resolve variables by part of expression
+ *
+ * @param project
+ * @param scope
+ * @param part
+ * @param tokens
+ * @return
+ */
+ private List<ISeamContextVariable> resolveVariables(ISeamProject project,
ScopeType scope, List<ELToken>part, List<ELToken> tokens) {
List<ISeamContextVariable>resolvedVars = new
ArrayList<ISeamContextVariable>();
String varName = computeVariableName(part);
if (varName != null) {
@@ -258,6 +288,13 @@
return new ArrayList<ISeamContextVariable>();
}
+ /*
+ * Creates and returns list of possible variable name combinations from expression
starting from the longest name
+ *
+ *
+ * @param prefix
+ * @return
+ */
private List<List<ELToken>>
getPossibleVarsFromPrefix(List<ELToken>prefix) {
ArrayList<List<ELToken>> result = new
ArrayList<List<ELToken>>();
for (int i = 0; prefix != null && i < prefix.size(); i++) {
@@ -274,7 +311,7 @@
}
/**
- * Removes duplicates
+ * Removes duplicates of completion strings
*
* @param suggestions a list of suggestions ({@link String}).
* @return a list of unique completion suggestions.
@@ -297,6 +334,12 @@
return unique;
}
+ /**
+ * EL string parser.
+ * Creates list of tokens for the name, method and separator parts
+ *
+ * @author Jeremy
+ */
public static class SeamELTokenizer {
static final int STATE_INITIAL = 0;
static final int STATE_VAR = 1;
@@ -306,7 +349,13 @@
IDocument fDocument;
List<ELToken> fTokens;
int index;
-
+
+ /**
+ * Constructs SeamELTokenizer object
+ *
+ * @param document
+ * @param offset
+ */
public SeamELTokenizer(IDocument document, int offset) {
fDocument = document;
index = (fDocument == null || fDocument.getLength() < offset? -1 : offset);
@@ -314,10 +363,18 @@
parseBackward();
}
+ /**
+ * Returns list of tokens for the expression parsed
+ *
+ * @return
+ */
public List<ELToken> getTokens() {
return fTokens;
}
+ /*
+ * Performs backward parsing of document text for expression
+ */
private void parseBackward() {
ELToken token;
fState = STATE_INITIAL;
@@ -334,7 +391,13 @@
int fState;
int fEndOfToken;
- ELToken getNextToken() {
+
+ /*
+ * Calculates and returns next token for expression
+ *
+ * @return
+ */
+ private ELToken getNextToken() {
switch (fState) {
case STATE_INITIAL: // Just started
{
@@ -400,6 +463,10 @@
return ELToken.EOF;
}
+ /* Reads and returns the method token from the expression
+ *
+ * @return
+ */
ELToken readMethodToken() {
fState = STATE_METHOD;
int endOfToken = index;
@@ -417,7 +484,14 @@
return (endOfToken - index > 0 ? new ELToken(index, endOfToken - index,
getCharSequence(index, endOfToken - index), ELToken.EL_METHOD_TOKEN) : ELToken.EOF);
}
-
+
+ /*
+ * Returns the CharSequence object
+ *
+ * @param start
+ * @param length
+ * @return
+ */
private CharSequence getCharSequence(int start, int length) {
String text = "";
try {
@@ -428,6 +502,10 @@
return text.subSequence(0, text.length());
}
+
+ /*
+ * Skips the space characters in the document
+ */
boolean skipSpaceChars() {
int ch;
while ((ch = readCharBackward()) != -1) {
@@ -439,6 +517,11 @@
return true;
}
+ /*
+ * Skips the method name characters in the document
+ *
+ * @return boolean true if at least 1 character had been read
+ */
boolean skipMethodName() {
int endOfToken = index;
int ch;
@@ -451,6 +534,11 @@
return false;
}
+ /*
+ * Skips the method parameters characters in the document
+ *
+ * @return boolean true if complete parameters set had been read
+ */
boolean skipMethodParameters() {
int ch = readCharBackward();
if (ch != ')')
@@ -477,6 +565,10 @@
return true;
}
+ /*
+ * Skips the quoted characters
+ *
+ */
void skipQuotedChars(char pair) {
int ch = readCharBackward();
@@ -498,7 +590,11 @@
ch = readCharBackward();
}
}
-
+
+ /* Reads and returns the separator token from the expression
+ *
+ * @return
+ */
ELToken readSeparatorToken() {
fState = STATE_SEPARATOR;
int ch = readCharBackward();
@@ -507,6 +603,10 @@
ELToken.EOF);
}
+ /* Reads and returns the variable token from the expression
+ *
+ * @return
+ */
ELToken readVarToken() {
fState = STATE_VAR;
int endOfToken = index;
@@ -521,6 +621,10 @@
return (endOfToken - index > 0 ? new ELToken(index, endOfToken - index,
getCharSequence(index, endOfToken - index), ELToken.EL_NAME_TOKEN) : ELToken.EOF);
}
+ /* Reads the next character in the document
+ *
+ * @return
+ */
int readCharBackward() {
if (--index < 0 ||
fDocument == null ||
@@ -534,12 +638,23 @@
}
}
+ /*
+ * returns the character to the document
+ */
void releaseChar() {
if (index < fDocument.getLength())
index++;
}
}
+ /**
+ * Calculates the EX expression operand string
+ *
+ * @param viewer
+ * @param offset
+ * @return
+ * @throws BadLocationException
+ */
public static String getPrefix(ITextViewer viewer, int offset) throws
BadLocationException {
IDocument doc= viewer.getDocument();
if (doc == null || offset > doc.getLength())
@@ -553,9 +668,13 @@
return doc.get(tokens.get(0).start, offset - tokens.get(0).start);
}
+}
-
-}
+/**
+ * Token for the EX expression
+ *
+ * @author Jeremy
+ */
class ELToken implements IToken {
static final ELToken EOF = new ELToken(-1, -1, null, -1);
static final int EL_NAME_TOKEN = 1;
@@ -567,6 +686,14 @@
CharSequence chars;
int type;
+ /**
+ * Constructs the ELToken object
+ *
+ * @param start
+ * @param length
+ * @param chars
+ * @param type
+ */
public ELToken(int start, int length, CharSequence chars, int type) {
this.start = start;
this.length = length;
@@ -574,34 +701,58 @@
this.type = type;
}
+ /**
+ * Returns string representation for the token
+ */
public String toString() {
return "ELToken(" + start + ", " + length + ", " + type +
") [" + (chars == null ? "<Empty>" : chars.toString()) +
"]";
}
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#getData()
+ */
public Object getData() {
return (chars == null ? null : chars.subSequence(start, start+length).toString());
}
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isEOF()
+ */
public boolean isEOF() {
return (start == -1 && length == -1 && chars == null);
}
-
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isOther()
+ */
public boolean isOther() {
return false;
}
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isUndefined()
+ */
public boolean isUndefined() {
return false;
}
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isWhitespace()
+ */
public boolean isWhitespace() {
return false;
}
+ /*
+ * Returns the token type
+ */
public int getType(){
return type;
}
+ /*
+ * Returns the token text
+ */
public String getText() {
return chars.toString();
}
Modified:
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalComputer.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalComputer.java 2007-07-13
17:59:36 UTC (rev 2436)
+++
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalComputer.java 2007-07-13
18:17:19 UTC (rev 2437)
@@ -20,7 +20,11 @@
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
-
+/**
+ * Custom Java Completion Proposal computer
+ *
+ * @author Jeremy
+ */
public class SeamELProposalComputer implements IJavaCompletionProposalComputer {
/** The wrapped processor. */
private final SeamELProposalProcessor fProcessor= new SeamELProposalProcessor();
Modified:
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalProcessor.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalProcessor.java 2007-07-13
17:59:36 UTC (rev 2436)
+++
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamELProposalProcessor.java 2007-07-13
18:17:19 UTC (rev 2437)
@@ -45,7 +45,14 @@
import org.jboss.tools.common.text.ext.IEditorWrapper;
import org.jboss.tools.seam.core.ISeamProject;
import org.jboss.tools.seam.core.SeamCorePlugin;
+import org.jboss.tools.seam.ui.SeamGuiPlugin;
+/**
+ * Content assist proposal processor.
+ * Computes Seam EL proposals.
+ *
+ * @author Jeremy
+ */
public class SeamELProposalProcessor implements IContentAssistProcessor {
private static final ICompletionProposal[] NO_PROPOSALS= new ICompletionProposal[0];
@@ -63,62 +70,103 @@
fOffset= offset;
}
+ /*
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(IDocument)
+ */
public void apply(IDocument document) {
apply(null, '\0', 0, fOffset);
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(IDocument)
+ */
public Point getSelection(IDocument document) {
return new Point(fOffset + fString.length(), 0);
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+ */
public String getAdditionalProposalInfo() {
return null;
}
+ /*
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+ */
public String getDisplayString() {
return fPrefix + fString;
}
+ /*
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+ */
public Image getImage() {
return
SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_ATTRIBUTE);
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+ */
public IContextInformation getContextInformation() {
return null;
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension#apply(IDocument, char,
int)
+ */
public void apply(IDocument document, char trigger, int offset) {
try {
String replacement= fString.substring(offset - fOffset);
document.replace(offset, 0, replacement);
} catch (BadLocationException x) {
- // TODO Auto-generated catch block
- x.printStackTrace();
+ SeamGuiPlugin.getPluginLog().logError(x);
}
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension#isValidFor(IDocument,
int)
+ */
public boolean isValidFor(IDocument document, int offset) {
return validate(document, offset, null);
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
+ */
public char[] getTriggerCharacters() {
return null;
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
+ */
public int getContextInformationPosition() {
return 0;
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(ITextViewer,
char, int, int)
+ */
public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
apply(viewer.getDocument(), trigger, offset);
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(ITextViewer,
boolean)
+ */
public void selected(ITextViewer viewer, boolean smartToggle) {
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(ITextViewer)
+ */
public void unselected(ITextViewer viewer) {
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(IDocument
document, int offset, DocumentEvent event)
+ */
public boolean validate(IDocument document, int offset, DocumentEvent event) {
try {
int prefixStart= fOffset - fPrefix.length();
@@ -128,20 +176,32 @@
}
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getInformationControlCreator()
+ */
public IInformationControlCreator getInformationControlCreator() {
return null;
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionText(IDocument,
int)
+ */
public CharSequence getPrefixCompletionText(IDocument document, int completionOffset)
{
return fPrefix + fString;
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionStart(IDocument,
int)
+ */
public int getPrefixCompletionStart(IDocument document, int completionOffset) {
return fOffset - fPrefix.length();
}
+ /*
+ * @see
org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable()
+ */
public boolean isAutoInsertable() {
- return true;
+ return false;
}
}
@@ -195,6 +255,13 @@
}
}
+ /* Creates Proposal object
+ *
+ * @param string
+ * @param prefix
+ * @param offset
+ * @return
+ */
private ICompletionProposal createProposal(String string, String prefix, int offset) {
return new Proposal(string, prefix, offset);
}
@@ -252,6 +319,10 @@
return null; // no custom error message
}
+ /*
+ * Returns active text editor
+ * @return
+ */
private ITextEditor getActiveEditor() {
IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null) {
@@ -270,6 +341,14 @@
return null;
}
+
+ /*
+ * Checks if the EL start starting characters are present
+ * @param viewer
+ * @param offset
+ * @return
+ * @throws BadLocationException
+ */
private boolean checkStartPositionInEL(ITextViewer viewer, int offset) throws
BadLocationException {
IDocument doc= viewer.getDocument();
if (doc == null || offset > doc.getLength())
Modified:
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamExpressionResolver.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamExpressionResolver.java 2007-07-13
17:59:36 UTC (rev 2436)
+++
trunk/seam/plugins/org.jboss.tools.seam.ui/src/org/jboss/tools/seam/ui/text/java/SeamExpressionResolver.java 2007-07-13
18:17:19 UTC (rev 2437)
@@ -34,14 +34,35 @@
import org.jboss.tools.seam.core.ISeamXmlFactory;
import org.jboss.tools.seam.core.ScopeType;
+/**
+ * Utility class used to resolve Seam project variables and to get the methods/properties
and their presentation strings from type
+ *
+ * @author Jeremy
+ */
public class SeamExpressionResolver {
+ /**
+ * Returns Seam project variables which names start from specified value
+ *
+ * @param project
+ * @param scope
+ * @param name
+ * @return
+ */
public static List<ISeamContextVariable> resolveVariables(ISeamProject project,
ScopeType scope, String name) {
if (project == null || name == null) return null;
return (scope == null ? internalResolveVariables(project, name) :
internalResolveVariablesByScope(project, scope, name));
}
+ /**
+ * Returns Seam project variables which names start from specified value
+ * No scope used
+ *
+ * @param project
+ * @param name
+ * @return
+ */
private static List<ISeamContextVariable> internalResolveVariables(ISeamProject
project, String name) {
List<ISeamContextVariable> resolvedVariables = new
ArrayList<ISeamContextVariable>();
Set<ISeamContextVariable> variables = project.getVariables();
@@ -53,6 +74,15 @@
return resolvedVariables;
}
+ /**
+ * Returns Seam project variables which names start from specified value
+ * Search is performed using scope
+ *
+ * @param project
+ * @param scope
+ * @param name
+ * @return
+ */
private static List<ISeamContextVariable>
internalResolveVariablesByScope(ISeamProject project, ScopeType scope, String name) {
List<ISeamContextVariable> resolvedVariables = new
ArrayList<ISeamContextVariable>();
Set<ISeamContextVariable> variables = project.getVariablesByScope(scope);
@@ -63,7 +93,13 @@
}
return resolvedVariables;
}
-
+
+ /**
+ * Returns the IMember for the variable specified
+ *
+ * @param variable
+ * @return
+ */
public static IMember getMemberByVariable(ISeamContextVariable variable) {
IMember member = null;
if (variable instanceof ISeamComponent) {
@@ -101,6 +137,12 @@
return member;
}
+ /**
+ * Returns the methods for the type specified
+ *
+ * @param type
+ * @return
+ */
public static Set<IMember> getMethods(IType type) {
Set<IMember> methods = new HashSet<IMember>();
if (type != null) {
@@ -120,6 +162,12 @@
return methods;
}
+ /**
+ * Returns the method presentation strings for the type specified
+ *
+ * @param type
+ * @return
+ */
public static Set<String> getMethodPresentations(IType type) {
Set<String> methods = new HashSet<String>();
if (type != null) {
@@ -151,6 +199,12 @@
return methods;
}
+ /**
+ * Returns the properties for the type specified
+ *
+ * @param type
+ * @return
+ */
public static Set<IMember> getProperties(IType type) {
Set<IMember> properties = new HashSet<IMember>();
if (type != null) {
@@ -180,6 +234,13 @@
}
return properties;
}
+
+ /**
+ * Returns the property presentation strings for the type specified
+ *
+ * @param type
+ * @return
+ */
public static Set<String> getPropertyPresentations(IType type) {
Set<String> properties = new
TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
if (type != null) {
@@ -214,5 +275,4 @@
}
return properties;
}
-
}