[jboss-svn-commits] JBL Code SVN: r14041 - labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sat Aug 4 22:32:30 EDT 2007
Author: pombredanne
Date: 2007-08-04 22:32:30 -0400 (Sat, 04 Aug 2007)
New Revision: 14041
Added:
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/ReflectionUtils.java
Removed:
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/MvelCompletionRequestor.java
Modified:
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionContext.java
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionUtil.java
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/DefaultCompletionProcessor.java
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProcessor.java
labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProposal.java
Log:
Beefed up mvel COMPLETION TO WRK CORRECTLY (MINUS SOME ISSUES RELATED TO COMPLETION PROPOSAL ORDEING)-
Modified: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionContext.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionContext.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionContext.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -46,22 +46,28 @@
static final Pattern ENDS_WITH_SPACES = Pattern.compile( ".*\\s+",
Pattern.DOTALL );
- static final Pattern MVEL_DIALECT = Pattern.compile( ".*dialect\\s+\"mvel\".*",
+ static final Pattern MVEL_DIALECT_PATTERN = Pattern.compile( ".*dialect\\s+\"mvel\".*",
Pattern.DOTALL );
+ static final Pattern JAVA_DIALECT_PATTERN = Pattern.compile( ".*dialect\\s+\"java\".*",
+ Pattern.DOTALL );
+
+ static final String MVEL_DIALECT = "mvel";
+ static final String JAVA_DIALECT = "java";
+
private String backText;
private DrlParser parser;
private RuleDescr rule;
private PackageDescr packageDescr;
- private boolean javaDialect = true;
- private Class getMvelReturnedType;
+ private String dialect;
+ private Class mvelReturnedType;
- public CompletionContext(String ruleText) {
- this.backText = ruleText;
+ public CompletionContext(String backText) {
+ this.backText = backText;
this.parser = new DrlParser();
try {
- packageDescr = parser.parse( ruleText );
+ packageDescr = parser.parse( backText );
List rules = packageDescr.getRules();
if ( rules != null && rules.size() == 1 ) {
this.rule = (RuleDescr) rules.get( 0 );
@@ -71,13 +77,24 @@
// do nothing
}
- determineDialect( ruleText );
+ //FIXME: the whole story of dialect determination for completion needs beefing up
+ determineDialect( backText );
}
+
public boolean isJavaDialect() {
- return javaDialect;
+ return JAVA_DIALECT.equalsIgnoreCase(dialect);
}
+ public boolean isMvelDialect() {
+ return MVEL_DIALECT.equalsIgnoreCase(dialect);
+ }
+
+ public boolean isDefaultDialect() {
+ return !isJavaDialect() && !isMvelDialect();
+ }
+
+
public PackageDescr getPackageDescr() {
return packageDescr;
}
@@ -85,13 +102,16 @@
//note: this is a crude but reasonably fast way to determine the dialect,
//especially when parsing imcomplete rules
private void determineDialect(String backText) {
- //which dialect are we using for this rule?
- //we test only for mvel for now: java is the default dialect
- if ( MVEL_DIALECT.matcher( backText ).matches() ) {
- javaDialect = false;
- } else {
- javaDialect = true;
+ dialect = null;
+ boolean mvel = MVEL_DIALECT_PATTERN.matcher( backText ).matches();
+ boolean java = JAVA_DIALECT_PATTERN.matcher( backText ).matches();
+ //which dialect may be defined for this rule?
+ if ( mvel ) {
+ dialect = MVEL_DIALECT;
}
+ if (java) {
+ dialect = JAVA_DIALECT;
+ }
}
public Location getLocation() {
@@ -194,11 +214,11 @@
return location;
}
- public Class getGetMvelReturnedType() {
- return getMvelReturnedType;
+ public Class getMvelReturnedType() {
+ return mvelReturnedType;
}
- public void setGetMvelReturnedType(Class getMvelReturnedType) {
- this.getMvelReturnedType = getMvelReturnedType;
+ public void setMvelReturnedType(Class getMvelReturnedType) {
+ this.mvelReturnedType = getMvelReturnedType;
}
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionUtil.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionUtil.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/CompletionUtil.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -1,191 +1,261 @@
package org.drools.eclipse.editors.completion;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.regex.Pattern;
import org.eclipse.jdt.core.Signature;
public class CompletionUtil {
- protected static final Pattern INCOMPLETED_MVEL_EXPRESSION = Pattern
- .compile("[\\.\\(\\{\\[]\\Z", Pattern.DOTALL);
+ protected static final Pattern INCOMPLETED_MVEL_EXPRESSION = Pattern.compile( "[\\.\\(\\{\\[]\\Z",
+ Pattern.DOTALL );
- protected static final Pattern COMPLETED_MVEL_EXPRESSION = Pattern.compile(
- "]\\)\\}\\]\\Z", Pattern.DOTALL);
+ protected static final Pattern COMPLETED_MVEL_EXPRESSION = Pattern.compile( "]\\)\\}\\]\\Z",
+ Pattern.DOTALL );
- private CompletionUtil() {
- }
+ private CompletionUtil() {
+ }
- /**
- * Looks behind, gets stuff after the white space. Basically ripping out the
- * last word.
- */
- public static String stripLastWord(String prefix) {
- if ("".equals(prefix)) {
- return prefix;
- }
- if (prefix.charAt(prefix.length() - 1) == ' ') {
- return "";
- } else {
- char[] c = prefix.toCharArray();
- int start = 0;
- for (int i = c.length - 1; i >= 0; i--) {
- if (Character.isWhitespace(c[i]) || c[i] == '(' || c[i] == ':'
- || c[i] == ';' || c[i] == '=' || c[i] == '<'
- || c[i] == '>' || c[i] == '.' || c[i] == '{'
- || c[i] == '}') {
- start = i + 1;
- break;
- }
- }
- prefix = prefix.substring(start, prefix.length());
- return prefix;
- }
- }
+ /**
+ * Looks behind, gets stuff after the white space. Basically ripping out the
+ * last word.
+ */
+ public static String stripLastWord(String prefix) {
+ if ( "".equals( prefix ) ) {
+ return prefix;
+ }
+ if ( prefix.charAt( prefix.length() - 1 ) == ' ' ) {
+ return "";
+ } else {
+ char[] c = prefix.toCharArray();
+ int start = 0;
+ for ( int i = c.length - 1; i >= 0; i-- ) {
+ if ( Character.isWhitespace( c[i] ) || c[i] == '(' || c[i] == ':' || c[i] == ';' || c[i] == '=' || c[i] == '<' || c[i] == '>' || c[i] == '.' || c[i] == '{' || c[i] == '}' ) {
+ start = i + 1;
+ break;
+ }
+ }
+ prefix = prefix.substring( start,
+ prefix.length() );
+ return prefix;
+ }
+ }
- public static String stripWhiteSpace(String prefix) {
- if ("".equals(prefix)) {
- return prefix;
- }
- if (prefix.charAt(prefix.length() - 1) == ' ') {
- return "";
- } else {
- char[] c = prefix.toCharArray();
- int start = 0;
- for (int i = c.length - 1; i >= 0; i--) {
- if (Character.isWhitespace(c[i])) {
- start = i + 1;
- break;
- }
- }
- prefix = prefix.substring(start, prefix.length());
- return prefix;
- }
- }
+ public static String stripWhiteSpace(String prefix) {
+ if ( "".equals( prefix ) ) {
+ return prefix;
+ }
+ if ( prefix.charAt( prefix.length() - 1 ) == ' ' ) {
+ return "";
+ } else {
+ char[] c = prefix.toCharArray();
+ int start = 0;
+ for ( int i = c.length - 1; i >= 0; i-- ) {
+ if ( Character.isWhitespace( c[i] ) ) {
+ start = i + 1;
+ break;
+ }
+ }
+ prefix = prefix.substring( start,
+ prefix.length() );
+ return prefix;
+ }
+ }
- /**
- *
- * @param backText
- * @return a substring of the back text, that should be compilable without
- * syntax errors by the mvel compiler TODO: add tests and more use
- * cases
- */
- public static String getCompilableText(String backText) {
- if (backText.trim().endsWith(";")) {
- // RHS expression should compile if it ends with ;. but to hget the last object, we do no want it
- return backText.substring(0, backText.length() - 1);
- }
- else if (backText.endsWith(".")) {
- // RHS expression should compile if it ends with ;
- return backText.substring(0, backText.length() - 1) ;
- } else if (CompletionUtil.COMPLETED_MVEL_EXPRESSION.matcher(backText)
- .matches()) {
- // RHS expression should compile if closed. just need to close the
- // statement
- return backText + ";";
- } else if (INCOMPLETED_MVEL_EXPRESSION.matcher(backText).matches()) {
- // remove the last char and close the statement
- return backText.substring(0, backText.length() - 1) ;
- } else {
- return backText;
- }
- }
+ /**
+ * Attempt to enhance a consequence backtext such that it should compile in MVEL
+ * @param backText
+ * @return a substring of the back text, that should be compilable without
+ * syntax errors by the mvel compiler TODO: add tests and more use
+ * cases
+ */
+ public static String getCompilableText(String backText) {
+ if ( backText.trim().endsWith( ";" ) ) {
+ // RHS expression should compile if it ends with ;. but to hget the last object, we do no want it
+ return backText.substring( 0,
+ backText.length() - 1 );
+ } else if ( backText.endsWith( "." ) ) {
+ // RHS expression should compile if it ends with ;
+ return backText.substring( 0,
+ backText.length() - 1 );
+ } else if ( CompletionUtil.COMPLETED_MVEL_EXPRESSION.matcher( backText ).matches() ) {
+ // RHS expression should compile if closed. just need to close the
+ // statement
+ return backText + ";";
+ } else if ( INCOMPLETED_MVEL_EXPRESSION.matcher( backText ).matches() ) {
+ // remove the last char and close the statement
+ return backText.substring( 0,
+ backText.length() - 1 );
+ } else {
+ return backText;
+ }
+ }
- /*
- * propertyname extraction and bean convention methods names checks
- */
+ /*
+ * propertyname extraction and bean convention methods names checks
+ */
- public static boolean isGetter(String methodName, int argCount,
- String returnedType) {
- return isAccessor(methodName, argCount, 0, "get", returnedType,
- Signature.SIG_VOID, false);
- }
+ public static boolean isGetter(String methodName,
+ int argCount,
+ String returnedType) {
+ return isAccessor( methodName,
+ argCount,
+ 0,
+ "get",
+ returnedType,
+ Signature.SIG_VOID,
+ false );
+ }
- public static boolean isSetter(String methodName, int argCount,
- String returnedType) {
- return isAccessor(methodName, argCount, 1, "set", returnedType,
- Signature.SIG_VOID, true);
- }
+ public static boolean isSetter(String methodName,
+ int argCount,
+ String returnedType) {
+ return isAccessor( methodName,
+ argCount,
+ 1,
+ "set",
+ returnedType,
+ Signature.SIG_VOID,
+ true );
+ }
- public static boolean isIsGetter(String methodName, int argCount,
- String returnedType) {
- return isAccessor(methodName, argCount, 0, "is", returnedType,
- Signature.SIG_BOOLEAN, true);
- }
+ public static boolean isIsGetter(String methodName,
+ int argCount,
+ String returnedType) {
+ return isAccessor( methodName,
+ argCount,
+ 0,
+ "is",
+ returnedType,
+ Signature.SIG_BOOLEAN,
+ true );
+ }
- public static String getPropertyName(String methodName, int parameterCount,
- String returnType) {
- if (methodName == null) {
- return null;
- }
- String simpleName = methodName.replaceAll("\\(\\)", "");
- int prefixLength = 0;
- if (isIsGetter(simpleName, parameterCount, returnType)) {
+ /**
+ * Given a data depicting a method (name, # or params/args, returned type key), tries to return a bean property name derived from that method.
+ * If a bean property name is not found, the initial method name is returned
+ * @param methodName
+ * @param parameterCount
+ * @param returnType
+ * @return a bean property name
+ */
+ public static String getPropertyName(String methodName,
+ int parameterCount,
+ String returnType) {
+ if ( methodName == null ) {
+ return null;
+ }
+ String simpleName = methodName.replaceAll( "\\(\\)",
+ "" );
+ int prefixLength = 0;
+ if ( isIsGetter( simpleName,
+ parameterCount,
+ returnType ) ) {
- prefixLength = 2;
+ prefixLength = 2;
- } else if (isGetter(simpleName, parameterCount, returnType) //
- || isSetter(methodName, parameterCount, returnType)) {
+ } else if ( isGetter( simpleName,
+ parameterCount,
+ returnType ) //
+ || isSetter( simpleName,
+ parameterCount,
+ returnType ) ) {
- prefixLength = 3;
- } else {
- return methodName;
- }
+ prefixLength = 3;
+ } else {
+ return methodName;
+ }
- char firstChar = Character.toLowerCase(simpleName.charAt(prefixLength));
- String propertyName = firstChar
- + simpleName.substring(prefixLength + 1);
- return propertyName;
- }
+ char firstChar = Character.toLowerCase( simpleName.charAt( prefixLength ) );
+ String propertyName = firstChar + simpleName.substring( prefixLength + 1 );
+ return propertyName;
+ }
- public static String getPropertyName(String methodName, char[] signature) {
- if (signature == null || methodName == null) {
- return methodName;
- }
+ public static String getPropertyName(String methodName,
+ char[] signature) {
+ if ( signature == null || methodName == null ) {
+ return methodName;
+ }
- int parameterCount = Signature.getParameterCount(signature);
- String returnType = new String(Signature.getReturnType(signature));
+ int parameterCount = Signature.getParameterCount( signature );
+ String returnType = new String( Signature.getReturnType( signature ) );
- return getPropertyName(methodName, parameterCount, returnType);
- }
+ return getPropertyName( methodName,
+ parameterCount,
+ returnType );
+ }
- private static boolean isAccessor(String methodName,
- int actualParameterCount, int requiredParameterCount,
- String prefix, String returnType, String requiredReturnType,
- boolean includeType) {
+ /**
+ * Determine if the given method is a bean accessor (ie getter/setter)
+ * @param methodName
+ * @param actualParameterCount
+ * @param requiredParameterCount
+ * @param prefix
+ * @param returnType
+ * @param requiredReturnType
+ * @param includeType
+ * @return true if the method is a bean accessor, false otherwise
+ */private static boolean isAccessor(String methodName,
+ int actualParameterCount,
+ int requiredParameterCount,
+ String prefix,
+ String returnType,
+ String requiredReturnType,
+ boolean includeType) {
- if (methodName.length() < prefix.length() + 1) {
- return false;
- }
+ //must be longer than the accessor prefix
+ if ( methodName.length() < prefix.length() + 1 ) {
+ return false;
+ }
- if (!methodName.startsWith(prefix)) {
- return false;
- }
+ //start with get, set or is
+ if ( !methodName.startsWith( prefix ) ) {
+ return false;
+ }
- if (actualParameterCount != requiredParameterCount) {
- return false;
- }
+ if ( actualParameterCount != requiredParameterCount ) {
+ return false;
+ }
- if (includeType) {
- if (!requiredReturnType.equals(returnType)) {
- return false;
- }
- } else {
- if (requiredReturnType.equals(returnType)) {
- return false;
- }
- }
- return true;
- }
+ //if we check for the returned type, verify that the returned type is of the cirrect type signature
+ if ( includeType ) {
+ if ( !requiredReturnType.equals( returnType ) ) {
+ return false;
+ }
+ } else {
+ if ( requiredReturnType.equals( returnType ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
- public static boolean isStartOfNewStatement(String text, String prefix) {
- String javaTextWithoutPrefix = text.substring(0, text.length()
- - prefix.length());
+ public static boolean isStartOfNewStatement(String text,
+ String prefix) {
+ String javaTextWithoutPrefix = text.substring( 0, text.length() - prefix.length() );
- if ("".equals(javaTextWithoutPrefix.trim())
- || DefaultCompletionProcessor.START_OF_NEW_JAVA_STATEMENT
- .matcher(javaTextWithoutPrefix).matches()) {
- return true;
- }
- return false;
- }
+ if ( "".equals( javaTextWithoutPrefix.trim() ) || DefaultCompletionProcessor.START_OF_NEW_JAVA_STATEMENT.matcher( javaTextWithoutPrefix ).matches() ) {
+ return true;
+ }
+ return false;
+ }
+
+
+ public static String getLastLine(String text) {
+ final BufferedReader reader = new BufferedReader( new StringReader( text ) );
+ String line = null;
+ String lastLine = null;
+ try {
+ while ( (line = reader.readLine()) != null ) {
+ if ( line.trim().length()>0 ) {
+ lastLine = line;
+ }
+ }
+ } catch ( final IOException e ) {
+ // should never happen, it's just reading over a string.
+ }
+ return lastLine;
+ }
}
Modified: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/DefaultCompletionProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/DefaultCompletionProcessor.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/DefaultCompletionProcessor.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -21,12 +21,17 @@
import org.drools.util.StringUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.eval.IEvaluationContext;
import org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal;
import org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal;
+import org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jface.text.IDocument;
@@ -122,37 +127,50 @@
return result;
}
+ /*
+ * create and returns a java project based on the current editor input or returns null
+ */
+ private IJavaProject getCurrentJavaProject() {
+ IEditorInput input = getEditor().getEditorInput();
+ if (!(input instanceof IFileEditorInput)) {
+ return null;
+ }
+ IProject project = ((IFileEditorInput) input).getFile().getProject();
+ IJavaProject javaProject = JavaCore.create(project);
+ return javaProject;
+ }
+
private List getAllClassProposals(final String classNameStart, final int documentOffset, final String prefix) {
final List list = new ArrayList();
- IEditorInput input = getEditor().getEditorInput();
- if (input instanceof IFileEditorInput) {
- IProject project = ((IFileEditorInput) input).getFile().getProject();
- IJavaProject javaProject = JavaCore.create(project);
+ IJavaProject javaProject = getCurrentJavaProject();
+ if (javaProject ==null) {
+ return list;
+ }
- CompletionRequestor requestor = new CompletionRequestor() {
- public void accept(org.eclipse.jdt.core.CompletionProposal proposal) {
- String className = new String(proposal.getCompletion());
- if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.PACKAGE_REF) {
- RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), classNameStart.length(), className, className + ".");
- prop.setImage(DroolsPluginImages.getImage(DroolsPluginImages.PACKAGE));
- list.add(prop);
- } else if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.TYPE_REF) {
- RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), classNameStart.length() - proposal.getReplaceStart(), className, className + ";");
- prop.setImage(DroolsPluginImages.getImage(DroolsPluginImages.CLASS));
- list.add(prop);
- }
- // ignore all other proposals
+ CompletionRequestor requestor = new CompletionRequestor() {
+ public void accept(org.eclipse.jdt.core.CompletionProposal proposal) {
+ String className = new String(proposal.getCompletion());
+ if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.PACKAGE_REF) {
+ RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), classNameStart.length(), className, className + ".");
+ prop.setImage(DroolsPluginImages.getImage(DroolsPluginImages.PACKAGE));
+ list.add(prop);
+ } else if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.TYPE_REF) {
+ RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), classNameStart.length() - proposal.getReplaceStart(), className, className + ";");
+ prop.setImage(DroolsPluginImages.getImage(DroolsPluginImages.CLASS));
+ list.add(prop);
}
- };
+ // ignore all other proposals
+ }
+ };
- try {
- javaProject.newEvaluationContext().codeComplete( classNameStart,
- classNameStart.length(),
- requestor );
- } catch ( Throwable t ) {
- DroolsEclipsePlugin.log( t );
- }
+ try {
+ javaProject.newEvaluationContext().codeComplete( classNameStart,
+ classNameStart.length(),
+ requestor );
+ } catch ( Throwable t ) {
+ DroolsEclipsePlugin.log( t );
}
+
return list;
}
@@ -182,58 +200,90 @@
}
/**
- * @return a list of "MVELified" RuleCompletionProposal. Thta list contains only unqiue proposal based on
+ * @return a list of "MVELified" RuleCompletionProposal. That list contains only unique proposal based on
* the overrriden equals in {@link RuleCompletionProposal} to avoid the situation when several
* accessors can exist for one property. for that case we want to keep only one proposal.
*/
- protected Collection getJavaMvelCompletionProposals(final String javaText,
- final String prefix, final int documentOffset, Map params) {
+ protected Collection getJavaMvelCompletionProposals(final int documentOffset, final String javaText, final String prefix, Map params) {
+ final List list = new ArrayList();
+ requestJavaCompletionProposals(javaText, prefix, documentOffset, params, list);
+
+ Collection mvelList = mvelifyProposals(list);
+ return mvelList;
+ }
+
+
+ /*
+ * Filters accessor method proposals to replace them with their mvel expression equivalent
+ * For instance a completion for getStatus() would be replaced by a completion for status
+ */
+ private static Collection mvelifyProposals(List list) {
final Collection set = new HashSet();
- CompletionRequestor requestor = new MvelCompletionRequestor(prefix,
- documentOffset, javaText, set);
- requestJavaMVELCompletionProposals(javaText, prefix, params, requestor);
+
+ for (Iterator iter = list.iterator(); iter.hasNext();) {
+ Object o = iter.next();
+ if (o instanceof JavaMethodCompletionProposal) {
+ LazyJavaCompletionProposal javaProposal = (LazyJavaCompletionProposal) o;
+ //TODO: FIXME: this is very fragile ass it uses reflection to access the private completion field.
+ //Yet this is needed to do mvel filtering based on the method signtures, IF we use the richer JDT completion
+ Object field = ReflectionUtils.getField(o, "fProposal");
+ if (field != null && field instanceof CompletionProposal) {
+ CompletionProposal proposal = (CompletionProposal) field;
+
+ String completion = new String(proposal.getCompletion());
+
+ // get the eventual property name for that method name and signature
+ String propertyOrMethodName = CompletionUtil.getPropertyName(
+ completion, proposal.getSignature());
+ //if we got a proeprty name that differs from the orginal method name
+ //, this is a a bean accessor
+ boolean isAccessor = !completion.equals(propertyOrMethodName);
+
+ // is the completion for a bean accessor? and do we have already some relevant completion?
+ if (isAccessor && doesNotContainFieldCompletion(propertyOrMethodName, list)) {
+ //TODO: craft a better JDTish display name
+ RuleCompletionProposal prop = new RuleCompletionProposal(
+ javaProposal.getReplacementOffset(),
+ javaProposal.getReplacementLength(),
+ propertyOrMethodName);
+ prop.setImage(DefaultCompletionProcessor.VARIABLE_ICON);
+ set.add(prop);
+
+ } else {
+ set.add(o);
+ }
+ }
+
+ } else {
+ //add other proposals as is
+ set.add(o);
+ }
+ }
return set;
}
- protected void requestJavaMVELCompletionProposals(final String javaText,
- final String prefix, Map params, CompletionRequestor requestor) {
-
- // TODO different methods for MVEL and Java code completion
- // now reusing Java completion proposals
- // can this be used by MVEL as well?
- IEditorInput input = getEditor().getEditorInput();
- if (!(input instanceof IFileEditorInput)) {
- return;
+ /*
+ * do we already have a completion for that string that would be either a local variable or a field?
+ */
+ private static boolean doesNotContainFieldCompletion(String completion, List completions) {
+ if (completion == null || completion.length() == 0 || completions == null ){
+ return false;
}
- IProject project = ((IFileEditorInput) input).getFile().getProject();
- IJavaProject javaProject = JavaCore.create(project);
-
- try {
- IEvaluationContext evalContext = javaProject.newEvaluationContext();
- List imports = getImports();
- if (imports != null && imports.size() > 0) {
- evalContext.setImports((String[]) imports
- .toArray(new String[imports.size()]));
+ for (Iterator iter = completions.iterator(); iter.hasNext();) {
+ Object o = iter.next();
+ if (o instanceof AbstractJavaCompletionProposal) {
+ AbstractJavaCompletionProposal prop = (AbstractJavaCompletionProposal) o;
+ String content = prop.getReplacementString();
+ if (completion.equals(content)) {
+ IJavaElement javaElement = prop.getJavaElement();
+ if (javaElement instanceof ILocalVariable
+ || javaElement instanceof IField) {
+ return false;
+ }
+ }
}
- StringBuffer javaTextWithParams = new StringBuffer();
- Iterator iterator = params.entrySet().iterator();
- while (iterator.hasNext()) {
- Map.Entry entry = (Map.Entry) iterator.next();
- // this does not seem to work, so adding variables manually
- // evalContext.newVariable((String) entry.getValue(), (String)
- // entry.getKey(), null);
- javaTextWithParams.append(entry.getValue() + " "
- + entry.getKey() + ";\n");
- }
- javaTextWithParams.append("org.drools.spi.KnowledgeHelper drools;");
- javaTextWithParams.append(javaText);
- String text = javaTextWithParams.toString();
- // System.out.println( "" );
- // System.out.println( "MVEL: synthetic Java text:" + text );
- evalContext.codeComplete(text, text.length(), requestor);
- } catch (Throwable t) {
- DroolsEclipsePlugin.log(t);
}
+ return true;
}
protected void requestJavaCompletionProposals(final String javaText,
@@ -248,14 +298,12 @@
if ("".equals(javaTextWithoutPrefix.trim()) || START_OF_NEW_JAVA_STATEMENT.matcher(javaTextWithoutPrefix).matches()) {
filterObjectMethods = true;
}
- IEditorInput input = getEditor().getEditorInput();
- if ( !(input instanceof IFileEditorInput) ) {
- return;
- }
- IProject project = ((IFileEditorInput) input).getFile().getProject();
- IJavaProject javaProject = JavaCore.create( project );
+ IJavaProject javaProject = getCurrentJavaProject();
+ if (javaProject ==null) {
+ return ;
+ }
- CompletionProposalCollector collector = new CompletionProposalCollector(javaProject);
+ CompletionProposalCollector collector = new CompletionProposalCollector(javaProject);
collector.acceptContext(new CompletionContext());
try {
@@ -307,10 +355,10 @@
return Collections.EMPTY_LIST;
}
- protected List getUniqueImports() {
- List list = new ArrayList();
- list.addAll(getImports());
- return list;
+ protected Set getUniqueImports() {
+ HashSet set = new HashSet();
+ set.addAll(getImports());
+ return set;
}
protected List getFunctions() {
@@ -320,6 +368,13 @@
return Collections.EMPTY_LIST;
}
+ protected Map getAttributes() {
+ if ( getEditor() instanceof DRLRuleEditor ) {
+ return ((DRLRuleEditor) getEditor()).getAttributes();
+ }
+ return Collections.EMPTY_MAP;
+ }
+
protected Set getTemplates() {
if ( getEditor() instanceof DRLRuleEditor ) {
return ((DRLRuleEditor) getEditor()).getTemplates();
Deleted: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/MvelCompletionRequestor.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/MvelCompletionRequestor.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/MvelCompletionRequestor.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -1,67 +0,0 @@
-package org.drools.eclipse.editors.completion;
-
-import java.util.Collection;
-
-import org.eclipse.jdt.core.CompletionProposal;
-import org.eclipse.jdt.core.CompletionRequestor;
-
-public class MvelCompletionRequestor extends CompletionRequestor {
- private final String prefix;
- private final String text;
- private final Collection list;
- private final int documentOffset;
-
- public MvelCompletionRequestor(String prefix,
- int documentOffset,
- String text,
- Collection list) {
- this.prefix = prefix;
- this.text = text;
- this.list = list;
- this.documentOffset = documentOffset;
- }
-
- public void accept(CompletionProposal proposal) {
- // TODO set other proposal properties too (display name, icon, ...)
- String completion = new String( proposal.getCompletion() );
- RuleCompletionProposal prop = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), completion );;
-
- switch ( proposal.getKind() ) {
- case CompletionProposal.LOCAL_VARIABLE_REF :
- prop.setImage( DefaultCompletionProcessor.VARIABLE_ICON );
- break;
-
- case CompletionProposal.METHOD_REF :
- // TODO: Object methods are proposed when in the start of a line
-
- //get the eventual property name for that method name and signature
- String propertyOrMethodName = CompletionUtil.getPropertyName( completion,
- proposal.getSignature() );
- //is the completion for a bean accessor?
- boolean isAccessor = completion.equals( propertyOrMethodName );
-
- prop = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), propertyOrMethodName );
- boolean startOfNewStatement = CompletionUtil.isStartOfNewStatement( text,
- prefix );
- if ( startOfNewStatement ) {
- //ignore non accessor methods when starting a new statement
- if ( isAccessor ) {
- prop.setImage( DefaultCompletionProcessor.VARIABLE_ICON );
- }
- } else {
- if ( isAccessor ) {
- prop.setImage( DefaultCompletionProcessor.VARIABLE_ICON );
- } else {
- prop.setImage( DefaultCompletionProcessor.METHOD_ICON );
- }
- }
-
- break;
-
- default :
- }
- list.add( prop );
- }
-}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/ReflectionUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/ReflectionUtils.java (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/ReflectionUtils.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -0,0 +1,35 @@
+package org.drools.eclipse.editors.completion;
+
+import java.lang.reflect.Field;
+
+public class ReflectionUtils {
+
+ private ReflectionUtils() {
+ }
+
+ public static Object getField(Object instance, String name) {
+ Class clazz = instance.getClass();
+
+ do {
+ Field[] fields = clazz.getDeclaredFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field f = fields[i];
+ if (name.equals(f.getName())) {
+ try {
+ f.setAccessible(true);
+ return f.get(instance);
+
+ } catch (SecurityException ex) {
+ return null;
+ } catch (IllegalArgumentException ex) {
+ return null;
+ } catch (IllegalAccessException ex) {
+ return null;
+ }
+ }
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz.getSuperclass() != null);
+ return null;
+ }
+}
Modified: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProcessor.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProcessor.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -39,6 +39,7 @@
import org.mvel.CompiledExpression;
import org.mvel.ExpressionCompiler;
import org.mvel.ParserContext;
+import org.mvel.PropertyVerifier;
/**
* For handling within rules.
@@ -47,682 +48,896 @@
*/
public class RuleCompletionProcessor extends DefaultCompletionProcessor {
- private static final Image DROOLS_ICON = DroolsPluginImages
- .getImage(DroolsPluginImages.DROOLS);
+ private static final String DIALECT = "dialect";
- private static final Image CLASS_ICON = DroolsPluginImages
- .getImage(DroolsPluginImages.CLASS);
+ private static final Image DROOLS_ICON = DroolsPluginImages.getImage( DroolsPluginImages.DROOLS );
- /**
- * A CompletionContext contains the DRL backtext parsing results, to avoid
- * multilpe parser invocations
- */
- private CompletionContext context;
+ private static final Image CLASS_ICON = DroolsPluginImages.getImage( DroolsPluginImages.CLASS );
- public RuleCompletionProcessor(AbstractRuleEditor editor) {
- super(editor);
- }
+ /**
+ * A CompletionContext contains the DRL backtext parsing results, to avoid
+ * multilpe parser invocations
+ */
+ private CompletionContext context;
- protected List getCompletionProposals(ITextViewer viewer, int documentOffset) {
- try {
- final List list = new ArrayList();
- IDocument doc = viewer.getDocument();
+ public RuleCompletionProcessor(AbstractRuleEditor editor) {
+ super( editor );
+ }
- String backText = readBackwards(documentOffset, doc);
- final String prefix = CompletionUtil.stripLastWord(backText);
+ protected List getCompletionProposals(ITextViewer viewer,
+ int documentOffset) {
+ try {
+ final List list = new ArrayList();
+ IDocument doc = viewer.getDocument();
- // if inside the keyword "rule ", no code completion
- if (backText.length() < 5) {
- return list;
- }
+ String backText = readBackwards( documentOffset,
+ doc );
+ final String prefix = CompletionUtil.stripLastWord( backText );
- this.context = new CompletionContext(backText);
- Location location = context.getLocation();
+ // if inside the keyword "rule ", no code completion
+ if ( backText.length() < 5 ) {
+ return list;
+ }
- if (location.getType() == Location.LOCATION_RULE_HEADER) {
- addRuleHeaderProposals(list, documentOffset, prefix, backText);
- } else if (location.getType() == Location.LOCATION_RHS) {
- addRHSCompletionProposals(list, documentOffset, prefix, backText,
- (String) location.getProperty(Location.LOCATION_LHS_CONTENT),
- (String) location.getProperty(Location.LOCATION_RHS_CONTENT));
- } else {
- addLHSCompletionProposals(list, documentOffset, location, prefix, backText);
- }
+ this.context = new CompletionContext( backText );
+ Location location = context.getLocation();
- filterProposalsOnPrefix(prefix, list);
- return list;
- } catch (Throwable t) {
- DroolsEclipsePlugin.log(t);
- }
- return null;
- }
+ if ( location.getType() == Location.LOCATION_RULE_HEADER ) {
+ addRuleHeaderProposals( list,
+ documentOffset,
+ prefix,
+ backText );
+ } else if ( location.getType() == Location.LOCATION_RHS ) {
+ addRHSCompletionProposals( list,
+ documentOffset,
+ prefix,
+ backText,
+ (String) location.getProperty( Location.LOCATION_LHS_CONTENT ),
+ (String) location.getProperty( Location.LOCATION_RHS_CONTENT ) );
+ } else {
+ addLHSCompletionProposals( list,
+ documentOffset,
+ location,
+ prefix,
+ backText );
+ }
- protected void addRHSCompletionProposals(List list, int documentOffset, String prefix, String backText,
- String conditions, String consequence) {
- // only add functions and keywords if at the beginning of a
- // new statement
- if (consequence == null || consequence.length() < prefix.length()) {
- // possible if doing code completion directly after "then"
- return;
- }
- String consequenceWithoutPrefix =
- consequence.substring(0,consequence.length() - prefix.length());
+ filterProposalsOnPrefix( prefix,
+ list );
+ return list;
+ } catch ( Throwable t ) {
+ DroolsEclipsePlugin.log( t );
+ }
+ return null;
+ }
+ protected void addRHSCompletionProposals(List list,
+ int documentOffset,
+ String prefix,
+ String backText,
+ String conditions,
+ String consequence) {
+ // only add functions and keywords if at the beginning of a
+ // new statement
+ if ( consequence == null || consequence.length() < prefix.length() ) {
+ // possible if doing code completion directly after "then"
+ return;
+ }
+ String consequenceWithoutPrefix = consequence.substring( 0,
+ consequence.length() - prefix.length() );
+
if ( context == null ) {
context = new CompletionContext( backText );
}
boolean startOfDialectExpression = isStartOfDialectExpression( consequenceWithoutPrefix );
- if (startOfDialectExpression) {
- addRHSKeywordCompletionProposals(list, documentOffset, prefix);
- addRHSFunctionCompletionProposals(list, documentOffset, prefix);
- }
- if ( context.isJavaDialect() ) {
+ if ( startOfDialectExpression ) {
+ addRHSKeywordCompletionProposals( list,
+ documentOffset,
+ prefix );
+ addRHSFunctionCompletionProposals( list,
+ documentOffset,
+ prefix );
+ }
+
+ //if we have 1st a dialect defined locally, or 2nd a global dialect
+ //the locally defined dialect will override the package default
+ if ( isJavaDialect() ) {
addRHSJavaCompletionProposals( list,
- documentOffset,
- prefix,
+ documentOffset,
+ prefix,
backText,
consequence );
- } else {
+ } else if ( isMvelDialect() ) {
addRHSMvelCompletionProposals( list,
- documentOffset,
+ documentOffset,
prefix,
backText,
consequence,
startOfDialectExpression );
}
- }
+ }
- protected void addLHSCompletionProposals(List list, int documentOffset,
- Location location, String prefix, String backText) {
- switch (location.getType()) {
- case Location.LOCATION_LHS_BEGIN_OF_CONDITION:
- // if we are at the beginning of a new condition
- // add drools keywords
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "and",
- "and ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "or",
- "or ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "from",
- "from ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "forall",
- "forall( )", 8, DROOLS_ICON));
- RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix
- .length(), "eval", "eval( )", 6);
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "then",
- "then" + System.getProperty("line.separator") + "\t");
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- // we do not break but also add all elements that are needed for
- // and/or
- case Location.LOCATION_LHS_BEGIN_OF_CONDITION_AND_OR:
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "not",
- "not ", DROOLS_ICON));
- // we do not break but also add all elements that are needed for
- // not
- case Location.LOCATION_LHS_BEGIN_OF_CONDITION_NOT:
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "exists",
- "exists ", DROOLS_ICON));
- // we do not break but also add all elements that are needed for
- // exists
- case Location.LOCATION_LHS_FROM_ACCUMULATE:
- case Location.LOCATION_LHS_FROM_COLLECT:
- case Location.LOCATION_LHS_BEGIN_OF_CONDITION_EXISTS:
- // and add imported classes
- Iterator iterator = getImports().iterator();
- while (iterator.hasNext()) {
- String name = (String) iterator.next();
- int index = name.lastIndexOf(".");
- if (index != -1) {
- String className = name.substring(index + 1);
- RuleCompletionProposal p = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), className, className + "( )",
- className.length() + 2);
- p.setPriority(-1);
- p.setImage(CLASS_ICON);
- list.add(p);
- }
- }
- iterator = getClassesInPackage().iterator();
- while (iterator.hasNext()) {
- String name = (String) iterator.next();
- int index = name.lastIndexOf(".");
- if (index != -1) {
- String className = name.substring(index + 1);
- RuleCompletionProposal p = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), className, className + "( )",
- className.length() + 2);
- p.setPriority(-1);
- p.setImage(CLASS_ICON);
- list.add(p);
- }
- }
- iterator = getTemplates().iterator();
- while (iterator.hasNext()) {
- String name = (String) iterator.next();
- RuleCompletionProposal p = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), name, name + "( )",
- name.length() + 2);
- p.setPriority(-1);
- p.setImage(CLASS_ICON);
- list.add(p);
- }
- break;
- case Location.LOCATION_LHS_INSIDE_CONDITION_START:
- String className = (String) location
- .getProperty(Location.LOCATION_PROPERTY_CLASS_NAME);
- String propertyName = (String) location
- .getProperty(Location.LOCATION_PROPERTY_PROPERTY_NAME);
- if (className != null) {
- boolean isTemplate = addFactTemplatePropertyProposals(
- documentOffset, prefix, className, list);
- if (!isTemplate) {
- ClassTypeResolver resolver = new ClassTypeResolver(
- getUniqueImports(), ProjectClassLoader
- .getProjectClassLoader(getEditor()));
- try {
- String currentClass = className;
- if (propertyName != null) {
- String[] nestedProperties = propertyName.split("\\.");
- int nbSuperProperties = nestedProperties.length - 1;
- if (propertyName.endsWith(".")) {
- nbSuperProperties++;
- }
- for (int i = 0; i < nbSuperProperties; i++) {
- String simplePropertyName = nestedProperties[i];
- currentClass = getSimplePropertyClass(currentClass, simplePropertyName);
- currentClass = convertToNonPrimitiveClass(currentClass);
- }
- }
- RuleCompletionProposal p = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "this");
- p.setImage(METHOD_ICON);
- list.add(p);
- Class clazz = resolver.resolveType(currentClass);
- if (clazz != null) {
- if (Map.class.isAssignableFrom(clazz)) {
- p = new RuleCompletionProposal(documentOffset - prefix.length(),
- prefix.length(), "this['']", "this['']", 6);
- p.setImage(METHOD_ICON);
- list.add(p);
- }
- ClassFieldInspector inspector = new ClassFieldInspector(clazz);
- Map types = inspector.getFieldTypes();
- Iterator iterator2 = inspector.getFieldNames().keySet().iterator();
- while (iterator2.hasNext()) {
- String name = (String) iterator2.next();
- p = new RuleCompletionProposal(documentOffset - prefix.length(),
- prefix.length(), name, name + " ");
- p.setImage(METHOD_ICON);
- list.add(p);
- Class type = (Class) types.get(name);
- if (type != null && Map.class.isAssignableFrom(type)) {
- name += "['']";
- p = new RuleCompletionProposal(documentOffset - prefix.length(),
- prefix.length(), name, name, name.length() - 2);
- p.setImage(METHOD_ICON);
- list.add(p);
- }
- }
- }
- } catch (IOException exc) {
- // Do nothing
- } catch (ClassNotFoundException exc) {
- // Do nothing
- }
- }
- }
- break;
- case Location.LOCATION_LHS_INSIDE_CONDITION_OPERATOR:
- className = (String) location
- .getProperty(Location.LOCATION_PROPERTY_CLASS_NAME);
- String property = (String) location
- .getProperty(Location.LOCATION_PROPERTY_PROPERTY_NAME);
- String type = getPropertyClass(className, property);
+ private boolean isJavaDialect() {
+ // java is the default dialect, so no package dialect means java
+ // conditions are ordered from the more specific to the more general
+ if ( context.isJavaDialect() ) {
+ return true;
+ } else if ( context.isDefaultDialect() && (!(getAttributes().containsKey( DIALECT )) || hasPackageDialect( "java" )) ) {
+ return true;
+ }
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "==",
- "== ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "!=",
- "!= ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), ":", ": ",
- DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "->",
- "-> ( )", 5, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "memberOf",
- "memberOf ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "not memberOf",
- "not memberOf ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "in",
- "in ( )", 5, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "not in",
- "not in ( )", 9, DROOLS_ICON));
+ return false;
+ }
- if (isComparable(type)) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "<",
- "< ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "<=",
- "<= ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), ">",
- "> ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), ">=",
- ">= ", DROOLS_ICON));
- }
- if (type.equals("java.lang.String")) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "matches",
- "matches \"\"", 9, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "not matches", "not matches \"\"", 13, DROOLS_ICON));
- }
- if (isSubtypeOf(type, "java.util.Collection")) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "contains", "contains ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "not contains", "not contains ", DROOLS_ICON));
- }
- break;
- case Location.LOCATION_LHS_INSIDE_CONDITION_ARGUMENT:
- // determine type
- className = (String) location
- .getProperty(Location.LOCATION_PROPERTY_CLASS_NAME);
- property = (String) location
- .getProperty(Location.LOCATION_PROPERTY_PROPERTY_NAME);
- String operator = (String) location
- .getProperty(Location.LOCATION_PROPERTY_OPERATOR);
- type = getPropertyClass(className, property);
+ private boolean isMvelDialect() {
+ if ( context.isMvelDialect() ) {
+ return true;
+ } else if ( context.isDefaultDialect() && hasPackageDialect( "mvel" ) ) {
+ return true;
+ }
+ return false;
+ }
- if ("in".equals(operator)) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "()",
- "( )", 2, DROOLS_ICON));
- break;
- }
+ private boolean hasPackageDialect(String dialect) {
+ String globalDialect = (String) getAttributes().get( DIALECT );
+ if ( globalDialect != null && dialect.equalsIgnoreCase( globalDialect ) ) {
+ return true;
+ }
+ return false;
+ }
- if ("contains".equals(operator) || "excludes".equals(operator)) {
- type = "java.lang.Object";
- }
+ protected void addLHSCompletionProposals(List list,
+ int documentOffset,
+ Location location,
+ String prefix,
+ String backText) {
+ switch ( location.getType() ) {
+ case Location.LOCATION_LHS_BEGIN_OF_CONDITION :
+ // if we are at the beginning of a new condition
+ // add drools keywords
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "and",
+ "and ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "or",
+ "or ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "from",
+ "from ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "forall",
+ "forall( )",
+ 8,
+ DROOLS_ICON ) );
+ RuleCompletionProposal prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "eval",
+ "eval( )",
+ 6 );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "then",
+ "then" + System.getProperty( "line.separator" ) + "\t" );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ // we do not break but also add all elements that are needed for
+ // and/or
+ case Location.LOCATION_LHS_BEGIN_OF_CONDITION_AND_OR :
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "not",
+ "not ",
+ DROOLS_ICON ) );
+ // we do not break but also add all elements that are needed for
+ // not
+ case Location.LOCATION_LHS_BEGIN_OF_CONDITION_NOT :
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "exists",
+ "exists ",
+ DROOLS_ICON ) );
+ // we do not break but also add all elements that are needed for
+ // exists
+ case Location.LOCATION_LHS_FROM_ACCUMULATE :
+ case Location.LOCATION_LHS_FROM_COLLECT :
+ case Location.LOCATION_LHS_BEGIN_OF_CONDITION_EXISTS :
+ // and add imported classes
+ Iterator iterator = getImports().iterator();
+ while ( iterator.hasNext() ) {
+ String name = (String) iterator.next();
+ int index = name.lastIndexOf( "." );
+ if ( index != -1 ) {
+ String className = name.substring( index + 1 );
+ RuleCompletionProposal p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ className,
+ className + "( )",
+ className.length() + 2 );
+ p.setPriority( -1 );
+ p.setImage( CLASS_ICON );
+ list.add( p );
+ }
+ }
+ iterator = getClassesInPackage().iterator();
+ while ( iterator.hasNext() ) {
+ String name = (String) iterator.next();
+ int index = name.lastIndexOf( "." );
+ if ( index != -1 ) {
+ String className = name.substring( index + 1 );
+ RuleCompletionProposal p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ className,
+ className + "( )",
+ className.length() + 2 );
+ p.setPriority( -1 );
+ p.setImage( CLASS_ICON );
+ list.add( p );
+ }
+ }
+ iterator = getTemplates().iterator();
+ while ( iterator.hasNext() ) {
+ String name = (String) iterator.next();
+ RuleCompletionProposal p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ name,
+ name + "( )",
+ name.length() + 2 );
+ p.setPriority( -1 );
+ p.setImage( CLASS_ICON );
+ list.add( p );
+ }
+ break;
+ case Location.LOCATION_LHS_INSIDE_CONDITION_START :
+ String className = (String) location.getProperty( Location.LOCATION_PROPERTY_CLASS_NAME );
+ String propertyName = (String) location.getProperty( Location.LOCATION_PROPERTY_PROPERTY_NAME );
+ if ( className != null ) {
+ boolean isTemplate = addFactTemplatePropertyProposals( documentOffset,
+ prefix,
+ className,
+ list );
+ if ( !isTemplate ) {
+ ClassTypeResolver resolver = new ClassTypeResolver( getUniqueImports(),
+ ProjectClassLoader.getProjectClassLoader( getEditor() ) );
+ try {
+ String currentClass = className;
+ if ( propertyName != null ) {
+ String[] nestedProperties = propertyName.split( "\\." );
+ int nbSuperProperties = nestedProperties.length - 1;
+ if ( propertyName.endsWith( "." ) ) {
+ nbSuperProperties++;
+ }
+ for ( int i = 0; i < nbSuperProperties; i++ ) {
+ String simplePropertyName = nestedProperties[i];
+ currentClass = getSimplePropertyClass( currentClass,
+ simplePropertyName );
+ currentClass = convertToNonPrimitiveClass( currentClass );
+ }
+ }
+ RuleCompletionProposal p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "this" );
+ p.setImage( METHOD_ICON );
+ list.add( p );
+ Class clazz = resolver.resolveType( currentClass );
+ if ( clazz != null ) {
+ if ( Map.class.isAssignableFrom( clazz ) ) {
+ p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "this['']",
+ "this['']",
+ 6 );
+ p.setImage( METHOD_ICON );
+ list.add( p );
+ }
+ ClassFieldInspector inspector = new ClassFieldInspector( clazz );
+ Map types = inspector.getFieldTypes();
+ Iterator iterator2 = inspector.getFieldNames().keySet().iterator();
+ while ( iterator2.hasNext() ) {
+ String name = (String) iterator2.next();
+ p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ name,
+ name + " " );
+ p.setImage( METHOD_ICON );
+ list.add( p );
+ Class type = (Class) types.get( name );
+ if ( type != null && Map.class.isAssignableFrom( type ) ) {
+ name += "['']";
+ p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ name,
+ name,
+ name.length() - 2 );
+ p.setImage( METHOD_ICON );
+ list.add( p );
+ }
+ }
+ }
+ } catch ( IOException exc ) {
+ // Do nothing
+ } catch ( ClassNotFoundException exc ) {
+ // Do nothing
+ }
+ }
+ }
+ break;
+ case Location.LOCATION_LHS_INSIDE_CONDITION_OPERATOR :
+ className = (String) location.getProperty( Location.LOCATION_PROPERTY_CLASS_NAME );
+ String property = (String) location.getProperty( Location.LOCATION_PROPERTY_PROPERTY_NAME );
+ String type = getPropertyClass( className,
+ property );
- if ("memberOf".equals(operator)) {
- type = "java.util.Collection";
- }
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "==",
+ "== ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "!=",
+ "!= ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ ":",
+ ": ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "->",
+ "-> ( )",
+ 5,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "memberOf",
+ "memberOf ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "not memberOf",
+ "not memberOf ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "in",
+ "in ( )",
+ 5,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "not in",
+ "not in ( )",
+ 9,
+ DROOLS_ICON ) );
- boolean isObject = false;
- if ("java.lang.Object".equals(type)) {
- isObject = true;
- }
+ if ( isComparable( type ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "<",
+ "< ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "<=",
+ "<= ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ ">",
+ "> ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ ">=",
+ ">= ",
+ DROOLS_ICON ) );
+ }
+ if ( type.equals( "java.lang.String" ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "matches",
+ "matches \"\"",
+ 9,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "not matches",
+ "not matches \"\"",
+ 13,
+ DROOLS_ICON ) );
+ }
+ if ( isSubtypeOf( type,
+ "java.util.Collection" ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "contains",
+ "contains ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "not contains",
+ "not contains ",
+ DROOLS_ICON ) );
+ }
+ break;
+ case Location.LOCATION_LHS_INSIDE_CONDITION_ARGUMENT :
+ // determine type
+ className = (String) location.getProperty( Location.LOCATION_PROPERTY_CLASS_NAME );
+ property = (String) location.getProperty( Location.LOCATION_PROPERTY_PROPERTY_NAME );
+ String operator = (String) location.getProperty( Location.LOCATION_PROPERTY_OPERATOR );
+ type = getPropertyClass( className,
+ property );
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "null",
- "null ", DROOLS_ICON));
- if ("boolean".equals(type)) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "true", "true ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "false", "false ", DROOLS_ICON));
- }
- if (isObject || "java.lang.String".equals(type)) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "\"\"", "\"\"", 1, DROOLS_ICON));
- }
- if (isObject || "java.util.Date".equals(type)) {
- list
- .add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "\"dd-mmm-yyyy\"", "\"dd-mmm-yyyy\"", 1,
- DROOLS_ICON));
- }
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "()",
- "( )", 2, DROOLS_ICON));
- // add parameters with possibly matching type
- if (context == null) {
- context = new CompletionContext(backText);
- }
+ if ( "in".equals( operator ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "()",
+ "( )",
+ 2,
+ DROOLS_ICON ) );
+ break;
+ }
- if (context.getRule() != null) {
- Map result = new HashMap();
- addRuleParameters(result, context.getRule().getLhs()
- .getDescrs());
- Iterator iterator2 = result.entrySet().iterator();
- while (iterator2.hasNext()) {
- Map.Entry entry = (Map.Entry) iterator2.next();
- String paramName = (String) entry.getKey();
- String paramType = (String) entry.getValue();
- if (isSubtypeOf(paramType, type)) {
- RuleCompletionProposal proposal = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), paramName);
- proposal.setPriority(-1);
- proposal.setImage(VARIABLE_ICON);
- list.add(proposal);
- }
- }
- }
- // add globals with possibly matching type
- List globals = getGlobals();
- if (globals != null) {
- for (iterator = globals.iterator(); iterator.hasNext(); ) {
- GlobalDescr global = (GlobalDescr) iterator.next();
- if (isSubtypeOf(global.getType(), type)) {
- RuleCompletionProposal proposal = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), global.getIdentifier());
- proposal.setPriority(-1);
- proposal.setImage(VARIABLE_ICON);
- list.add(proposal);
- }
- }
- }
- break;
- case Location.LOCATION_LHS_INSIDE_EVAL:
- String content = (String) location
- .getProperty(Location.LOCATION_EVAL_CONTENT);
- list.addAll(getJavaCompletionProposals(documentOffset, content, prefix,
- getRuleParameters(backText)));
- break;
- case Location.LOCATION_LHS_INSIDE_CONDITION_END:
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "&&", "&& ",
- DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "||", "|| ",
- DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), ",", ", ",
- DROOLS_ICON));
- break;
- case Location.LOCATION_LHS_FROM:
- String fromText = (String) location
- .getProperty(Location.LOCATION_FROM_CONTENT);
- int index = fromText.indexOf('.');
- if (index == -1) {
- // add accumulate and collect keyword
- list
- .add(new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(),
- "accumulate",
- "accumulate ( , init ( ), action ( ), result ( ) )",
- 13, DROOLS_ICON));
- PackageBuilderConfiguration config = new PackageBuilderConfiguration(
- ProjectClassLoader.getProjectClassLoader(getEditor()), null);
- Map accumulateFunctions = config.getAccumulateFunctionsMap();
- for (Iterator iterator2 = accumulateFunctions.keySet().iterator(); iterator2.hasNext(); ) {
- String accumulateFunction = (String) iterator2.next();
- list.add(new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(),
- "accumulate " + accumulateFunction,
- "accumulate ( , " + accumulateFunction + "( ) )",
- 13, DROOLS_ICON));
- }
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "collect", "collect ( )", 10, DROOLS_ICON));
- // add all functions
- if ("".equals(fromText)) {
- List functions = getFunctions();
- iterator = functions.iterator();
- while (iterator.hasNext()) {
- String name = (String) iterator.next() + "()";
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- name, name, name.length() - 1);
- prop.setPriority(-1);
- prop.setImage(METHOD_ICON);
- list.add(prop);
- }
- }
- list.addAll(getJavaCompletionProposals(documentOffset, fromText, prefix,
- getRuleParameters(backText)));
- }
- break;
- case Location.LOCATION_LHS_FROM_ACCUMULATE_INIT_INSIDE:
- content = (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT);
- list.addAll(getJavaCompletionProposals(documentOffset, content, prefix,
- getRuleParameters(backText)));
- break;
- case Location.LOCATION_LHS_FROM_ACCUMULATE_ACTION_INSIDE:
- content = (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT);
- content += (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_ACTION_CONTENT);
- list.addAll(getJavaCompletionProposals(documentOffset, content, prefix,
- getRuleParameters(backText)));
- break;
- case Location.LOCATION_LHS_FROM_ACCUMULATE_RESULT_INSIDE:
- content = (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT);
- content += (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_ACTION_CONTENT);
- content += (String) location
- .getProperty(Location.LOCATION_PROPERTY_FROM_ACCUMULATE_RESULT_CONTENT);
- list.addAll(getJavaCompletionProposals(documentOffset, content, prefix,
- getRuleParameters(backText)));
- break;
- }
- }
+ if ( "contains".equals( operator ) || "excludes".equals( operator ) ) {
+ type = "java.lang.Object";
+ }
- private String getPropertyClass(String className, String propertyName) {
- if (className != null && propertyName != null) {
- FactTemplateDescr template = getTemplate(className);
- if (template != null) {
- Iterator iterator = template.getFields().iterator();
- while (iterator.hasNext()) {
- FieldTemplateDescr field = (FieldTemplateDescr) iterator
- .next();
- if (propertyName.equals(field.getName())) {
- String type = field.getClassType();
- if (isPrimitiveType(type)) {
- return type;
- }
- ClassTypeResolver resolver = new ClassTypeResolver(
- getUniqueImports(), ProjectClassLoader
- .getProjectClassLoader(getEditor()));
- try {
- Class clazz = resolver.resolveType(type);
- if (clazz != null) {
- return clazz.getName();
- }
- } catch (ClassNotFoundException exc) {
- exc.printStackTrace();
- // Do nothing
- }
- }
- }
- // if not found, return null
- } else {
- String[] nestedProperties = propertyName.split("\\.");
- String currentClass = className;
- for (int i = 0; i < nestedProperties.length; i++) {
- String simplePropertyName = nestedProperties[i];
- currentClass = getSimplePropertyClass(currentClass, simplePropertyName);
- }
- return currentClass;
- }
- }
- return null;
- }
+ if ( "memberOf".equals( operator ) ) {
+ type = "java.util.Collection";
+ }
- private String getSimplePropertyClass(String className, String propertyName) {
- if ("this".equals(propertyName)) {
- return className;
- }
- if (propertyName.endsWith("]")) {
- // TODO can we take advantage of generics here?
- return "java.lang.Object";
- }
- ClassTypeResolver resolver = new ClassTypeResolver(
- getUniqueImports(), ProjectClassLoader
- .getProjectClassLoader(getEditor()));
- try {
- Class clazz = resolver.resolveType(className);
- if (clazz != null) {
- Class clazzz = (Class) new ClassFieldInspector(clazz)
- .getFieldTypes().get(propertyName);
- if (clazzz != null) {
- return clazzz.getName();
- }
- }
- } catch (IOException exc) {
- // Do nothing
- } catch (ClassNotFoundException exc) {
- // Do nothing
- }
- return "java.lang.Object";
- }
+ boolean isObject = false;
+ if ( "java.lang.Object".equals( type ) ) {
+ isObject = true;
+ }
- private Map getRuleParameters(String backText) {
- Map result = new HashMap();
- // add globals
- List globals = getGlobals();
- if (globals != null) {
- for (Iterator iterator = globals.iterator(); iterator.hasNext(); ) {
- GlobalDescr global = (GlobalDescr) iterator.next();
- result.put(global.getIdentifier(), global.getType());
- }
- }
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "null",
+ "null ",
+ DROOLS_ICON ) );
+ if ( "boolean".equals( type ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "true",
+ "true ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "false",
+ "false ",
+ DROOLS_ICON ) );
+ }
+ if ( isObject || "java.lang.String".equals( type ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "\"\"",
+ "\"\"",
+ 1,
+ DROOLS_ICON ) );
+ }
+ if ( isObject || "java.util.Date".equals( type ) ) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "\"dd-mmm-yyyy\"",
+ "\"dd-mmm-yyyy\"",
+ 1,
+ DROOLS_ICON ) );
+ }
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "()",
+ "( )",
+ 2,
+ DROOLS_ICON ) );
+ // add parameters with possibly matching type
+ if ( context.getRule() != null ) {
+ Map result = new HashMap();
+ addRuleParameters( result,
+ context.getRule().getLhs().getDescrs() );
+ Iterator iterator2 = result.entrySet().iterator();
+ while ( iterator2.hasNext() ) {
+ Map.Entry entry = (Map.Entry) iterator2.next();
+ String paramName = (String) entry.getKey();
+ String paramType = (String) entry.getValue();
+ if ( isSubtypeOf( paramType,
+ type ) ) {
+ RuleCompletionProposal proposal = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ paramName );
+ proposal.setPriority( -1 );
+ proposal.setImage( VARIABLE_ICON );
+ list.add( proposal );
+ }
+ }
+ }
+ // add globals with possibly matching type
+ List globals = getGlobals();
+ if ( globals != null ) {
+ for ( iterator = globals.iterator(); iterator.hasNext(); ) {
+ GlobalDescr global = (GlobalDescr) iterator.next();
+ if ( isSubtypeOf( global.getType(),
+ type ) ) {
+ RuleCompletionProposal proposal = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ global.getIdentifier() );
+ proposal.setPriority( -1 );
+ proposal.setImage( VARIABLE_ICON );
+ list.add( proposal );
+ }
+ }
+ }
+ break;
+ case Location.LOCATION_LHS_INSIDE_EVAL :
+ String content = (String) location.getProperty( Location.LOCATION_EVAL_CONTENT );
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ content,
+ prefix,
+ getRuleParameters( backText ) ) );
+ break;
+ case Location.LOCATION_LHS_INSIDE_CONDITION_END :
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "&&",
+ "&& ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "||",
+ "|| ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ ",",
+ ", ",
+ DROOLS_ICON ) );
+ break;
+ case Location.LOCATION_LHS_FROM :
+ String fromText = (String) location.getProperty( Location.LOCATION_FROM_CONTENT );
+ int index = fromText.indexOf( '.' );
+ if ( index == -1 ) {
+ // add accumulate and collect keyword
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "accumulate",
+ "accumulate ( , init ( ), action ( ), result ( ) )",
+ 13,
+ DROOLS_ICON ) );
+ PackageBuilderConfiguration config = new PackageBuilderConfiguration( ProjectClassLoader.getProjectClassLoader( getEditor() ),
+ null );
+ Map accumulateFunctions = config.getAccumulateFunctionsMap();
+ for ( Iterator iterator2 = accumulateFunctions.keySet().iterator(); iterator2.hasNext(); ) {
+ String accumulateFunction = (String) iterator2.next();
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "accumulate " + accumulateFunction,
+ "accumulate ( , " + accumulateFunction + "( ) )",
+ 13,
+ DROOLS_ICON ) );
+ }
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "collect",
+ "collect ( )",
+ 10,
+ DROOLS_ICON ) );
+ // add all functions
+ if ( "".equals( fromText ) ) {
+ List functions = getFunctions();
+ iterator = functions.iterator();
+ while ( iterator.hasNext() ) {
+ String name = (String) iterator.next() + "()";
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ name,
+ name,
+ name.length() - 1 );
+ prop.setPriority( -1 );
+ prop.setImage( METHOD_ICON );
+ list.add( prop );
+ }
+ }
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ fromText,
+ prefix,
+ getRuleParameters( backText ) ) );
+ }
+ break;
+ case Location.LOCATION_LHS_FROM_ACCUMULATE_INIT_INSIDE :
+ content = (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT );
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ content,
+ prefix,
+ getRuleParameters( backText ) ) );
+ break;
+ case Location.LOCATION_LHS_FROM_ACCUMULATE_ACTION_INSIDE :
+ content = (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT );
+ content += (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_ACTION_CONTENT );
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ content,
+ prefix,
+ getRuleParameters( backText ) ) );
+ break;
+ case Location.LOCATION_LHS_FROM_ACCUMULATE_RESULT_INSIDE :
+ content = (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_INIT_CONTENT );
+ content += (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_ACTION_CONTENT );
+ content += (String) location.getProperty( Location.LOCATION_PROPERTY_FROM_ACCUMULATE_RESULT_CONTENT );
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ content,
+ prefix,
+ getRuleParameters( backText ) ) );
+ break;
+ }
+ }
- if (context == null) {
- context = new CompletionContext(backText);
- }
- if (context.getRule() == null) {
- return result;
- }
- // add parameters defined in conditions
- addRuleParameters(result, context.getRule().getLhs().getDescrs());
- return result;
- }
+ private String getPropertyClass(String className,
+ String propertyName) {
+ if ( className != null && propertyName != null ) {
+ FactTemplateDescr template = getTemplate( className );
+ if ( template != null ) {
+ Iterator iterator = template.getFields().iterator();
+ while ( iterator.hasNext() ) {
+ FieldTemplateDescr field = (FieldTemplateDescr) iterator.next();
+ if ( propertyName.equals( field.getName() ) ) {
+ String type = field.getClassType();
+ if ( isPrimitiveType( type ) ) {
+ return type;
+ }
+ ClassTypeResolver resolver = new ClassTypeResolver( getUniqueImports(),
+ ProjectClassLoader.getProjectClassLoader( getEditor() ) );
+ try {
+ Class clazz = resolver.resolveType( type );
+ if ( clazz != null ) {
+ return clazz.getName();
+ }
+ } catch ( ClassNotFoundException exc ) {
+ DroolsEclipsePlugin.log( exc );
+ }
+ }
+ }
+ // if not found, return null
+ } else {
+ String[] nestedProperties = propertyName.split( "\\." );
+ String currentClass = className;
+ for ( int i = 0; i < nestedProperties.length; i++ ) {
+ String simplePropertyName = nestedProperties[i];
+ currentClass = getSimplePropertyClass( currentClass,
+ simplePropertyName );
+ }
+ return currentClass;
+ }
+ }
+ return null;
+ }
- private boolean isComparable(String type) {
- if (type == null) {
- return false;
- }
- if (isPrimitiveNumericType(type)) {
- return true;
- }
- if (isObjectNumericType(type)) {
- return true;
- }
- if (isSubtypeOf(type, "java.lang.Comparable")) {
- return true;
- }
- return false;
- }
+ private String getSimplePropertyClass(String className,
+ String propertyName) {
+ if ( "this".equals( propertyName ) ) {
+ return className;
+ }
+ if ( propertyName.endsWith( "]" ) ) {
+ // TODO can we take advantage of generics here?
+ return "java.lang.Object";
+ }
+ ClassTypeResolver resolver = new ClassTypeResolver( getUniqueImports(),
+ ProjectClassLoader.getProjectClassLoader( getEditor() ) );
+ try {
+ Class clazz = resolver.resolveType( className );
+ if ( clazz != null ) {
+ Class clazzz = (Class) new ClassFieldInspector( clazz ).getFieldTypes().get( propertyName );
+ if ( clazzz != null ) {
+ return clazzz.getName();
+ }
+ }
+ } catch ( IOException exc ) {
+ // Do nothing
+ } catch ( ClassNotFoundException exc ) {
+ // Do nothing
+ }
+ return "java.lang.Object";
+ }
- private boolean isPrimitiveType(String type) {
- return isPrimitiveNumericType(type) || type.equals("boolean");
- }
+ private Map getRuleParameters(String backText) {
+ Map result = new HashMap();
+ // add globals
+ List globals = getGlobals();
+ if ( globals != null ) {
+ for ( Iterator iterator = globals.iterator(); iterator.hasNext(); ) {
+ GlobalDescr global = (GlobalDescr) iterator.next();
+ result.put( global.getIdentifier(),
+ global.getType() );
+ }
+ }
- private boolean isPrimitiveNumericType(String type) {
- return type.equals("byte") || type.equals("short")
- || type.equals("int") || type.equals("long")
- || type.equals("float") || type.equals("double")
- || type.equals("char");
- }
+ if ( context == null ) {
+ context = new CompletionContext( backText );
+ }
+ if ( context.getRule() == null ) {
+ return result;
+ }
+ // add parameters defined in conditions
+ addRuleParameters( result,
+ context.getRule().getLhs().getDescrs() );
+ return result;
+ }
- private boolean isObjectNumericType(String type) {
- return type.equals("java.lang.Byte") || type.equals("java.lang.Short")
- || type.equals("java.lang.Integer")
- || type.equals("java.lang.Long")
- || type.equals("java.lang.Float")
- || type.equals("java.lang.Double")
- || type.equals("java.lang.Char");
- }
+ private boolean isComparable(String type) {
+ if ( type == null ) {
+ return false;
+ }
+ if ( isPrimitiveNumericType( type ) ) {
+ return true;
+ }
+ if ( isObjectNumericType( type ) ) {
+ return true;
+ }
+ if ( isSubtypeOf( type,
+ "java.lang.Comparable" ) ) {
+ return true;
+ }
+ return false;
+ }
- /**
- * Returns true if the first class is the same or a subtype of the second
- * class.
- *
- * @param class1
- * @param class2
- * @return
- */
- private boolean isSubtypeOf(String class1, String class2) {
- if (class1 == null || class2 == null) {
- return false;
- }
- class1 = convertToNonPrimitiveClass(class1);
- class2 = convertToNonPrimitiveClass(class2);
- // TODO add code to take primitive types into account
- ClassTypeResolver resolver = new ClassTypeResolver(getUniqueImports(), ProjectClassLoader
- .getProjectClassLoader(getEditor()));
- try {
- Class clazz1 = resolver.resolveType(class1);
- Class clazz2 = resolver.resolveType(class2);
- if (clazz1 == null || clazz2 == null) {
- return false;
- }
- return clazz2.isAssignableFrom(clazz1);
- } catch (ClassNotFoundException exc) {
- return false;
- }
- }
+ private boolean isPrimitiveType(String type) {
+ return isPrimitiveNumericType( type ) || type.equals( "boolean" );
+ }
- private String convertToNonPrimitiveClass(String clazz) {
- if (!isPrimitiveType(clazz)) {
- return clazz;
- }
- if ("byte".equals(clazz)) {
- return "java.lang.Byte";
- } else if ("short".equals(clazz)) {
- return "java.lang.Short";
- } else if ("int".equals(clazz)) {
- return "java.lang.Integer";
- } else if ("long".equals(clazz)) {
- return "java.lang.Long";
- } else if ("float".equals(clazz)) {
- return "java.lang.Float";
- } else if ("double".equals(clazz)) {
- return "java.lang.Double";
- } else if ("char".equals(clazz)) {
- return "java.lang.Char";
- } else if ("boolean".equals(clazz)) {
- return "java.lang.Boolean";
- }
- // should never occur
- return null;
- }
+ private boolean isPrimitiveNumericType(String type) {
+ return type.equals( "byte" ) || type.equals( "short" ) || type.equals( "int" ) || type.equals( "long" ) || type.equals( "float" ) || type.equals( "double" ) || type.equals( "char" );
+ }
- private void addRHSFunctionCompletionProposals(List list, int documentOffset, String prefix) {
- Iterator iterator;
- RuleCompletionProposal prop;
- List functions = getFunctions();
- iterator = functions.iterator();
- while (iterator.hasNext()) {
- String name = (String) iterator.next() + "()";
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), name,
- name + ";", name.length() - 1);
- prop.setPriority(-1);
- prop.setImage(METHOD_ICON);
- list.add(prop);
- }
- }
+ private boolean isObjectNumericType(String type) {
+ return type.equals( "java.lang.Byte" ) || type.equals( "java.lang.Short" ) || type.equals( "java.lang.Integer" ) || type.equals( "java.lang.Long" ) || type.equals( "java.lang.Float" ) || type.equals( "java.lang.Double" )
+ || type.equals( "java.lang.Char" );
+ }
- private void addRHSKeywordCompletionProposals(
- List list, int documentOffset, String prefix) {
- RuleCompletionProposal prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix
- .length(), "update", "update();", 7);
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "retract",
- "retract();", 8);
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "insert",
- "insert();", 7);
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- prop = new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "insertLogical",
- "insertLogical();", 14);
- prop.setImage(DROOLS_ICON);
- list.add(prop);
- }
+ /**
+ * Returns true if the first class is the same or a subtype of the second
+ * class.
+ *
+ * @param class1
+ * @param class2
+ * @return
+ */
+ private boolean isSubtypeOf(String class1,
+ String class2) {
+ if ( class1 == null || class2 == null ) {
+ return false;
+ }
+ class1 = convertToNonPrimitiveClass( class1 );
+ class2 = convertToNonPrimitiveClass( class2 );
+ // TODO add code to take primitive types into account
+ ClassTypeResolver resolver = new ClassTypeResolver( getUniqueImports(),
+ ProjectClassLoader.getProjectClassLoader( getEditor() ) );
+ try {
+ Class clazz1 = resolver.resolveType( class1 );
+ Class clazz2 = resolver.resolveType( class2 );
+ if ( clazz1 == null || clazz2 == null ) {
+ return false;
+ }
+ return clazz2.isAssignableFrom( clazz1 );
+ } catch ( ClassNotFoundException exc ) {
+ return false;
+ }
+ }
- private void addRHSJavaCompletionProposals(List list, int documentOffset, String prefix, String backText,
- String consequence) {
- list.addAll(getJavaCompletionProposals(documentOffset, consequence, prefix,
- getRuleParameters(backText)));
- }
+ private String convertToNonPrimitiveClass(String clazz) {
+ if ( !isPrimitiveType( clazz ) ) {
+ return clazz;
+ }
+ if ( "byte".equals( clazz ) ) {
+ return "java.lang.Byte";
+ } else if ( "short".equals( clazz ) ) {
+ return "java.lang.Short";
+ } else if ( "int".equals( clazz ) ) {
+ return "java.lang.Integer";
+ } else if ( "long".equals( clazz ) ) {
+ return "java.lang.Long";
+ } else if ( "float".equals( clazz ) ) {
+ return "java.lang.Float";
+ } else if ( "double".equals( clazz ) ) {
+ return "java.lang.Double";
+ } else if ( "char".equals( clazz ) ) {
+ return "java.lang.Char";
+ } else if ( "boolean".equals( clazz ) ) {
+ return "java.lang.Boolean";
+ }
+ // should never occur
+ return null;
+ }
- private void addRHSMvelCompletionProposals(List list, final int documentOffset, String prefix,
- String backText, String consequence, boolean expressionStart) {
+ private void addRHSFunctionCompletionProposals(List list,
+ int documentOffset,
+ String prefix) {
+ Iterator iterator;
+ RuleCompletionProposal prop;
+ List functions = getFunctions();
+ iterator = functions.iterator();
+ while ( iterator.hasNext() ) {
+ String name = (String) iterator.next() + "()";
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ name,
+ name + ";",
+ name.length() - 1 );
+ prop.setPriority( -1 );
+ prop.setImage( METHOD_ICON );
+ list.add( prop );
+ }
+ }
- Collection mvelCompletionProposals = getMvelCompletionProposals(
- consequence, documentOffset, prefix, getRuleParameters(backText), backText,
- expressionStart);
- list.addAll(mvelCompletionProposals);
- }
+ private void addRHSKeywordCompletionProposals(List list,
+ int documentOffset,
+ String prefix) {
+ RuleCompletionProposal prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "update",
+ "update();",
+ 7 );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "retract",
+ "retract();",
+ 8 );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "insert",
+ "insert();",
+ 7 );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ prop = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "insertLogical",
+ "insertLogical();",
+ 14 );
+ prop.setImage( DROOLS_ICON );
+ list.add( prop );
+ }
- private Collection getMvelCompletionProposals(final String consequence,
+ private void addRHSJavaCompletionProposals(List list,
+ int documentOffset,
+ String prefix,
+ String backText,
+ String consequence) {
+ list.addAll( getJavaCompletionProposals( documentOffset,
+ consequence,
+ prefix,
+ getRuleParameters( backText ) ) );
+ }
+
+ private void addRHSMvelCompletionProposals(List list,
+ final int documentOffset,
+ String prefix,
+ String backText,
+ String consequence,
+ boolean expressionStart) {
+
+ Collection mvelCompletionProposals = getMvelCompletionProposals( consequence,
+ documentOffset,
+ prefix,
+ getRuleParameters( backText ),
+ backText,
+ expressionStart );
+ list.addAll( mvelCompletionProposals );
+ }
+
+ private Collection getMvelCompletionProposals(final String consequence,
final int documentOffset, final String prefix, Map params, String backText,
boolean startOfExpression) {
@@ -732,12 +947,12 @@
return proposals;
}
- // TODO: add logic from MVELConsequenceBuilder
String compilableConsequence = CompletionUtil
.getCompilableText(consequence);
compilableConsequence = MVELConsequenceBuilder
.delimitExpressions(compilableConsequence);
+
// attempt to compile and analyze
try {
DRLInfo drlInfo = DroolsEclipsePlugin.getDefault().parseResource(
@@ -747,32 +962,36 @@
params, drlInfo, compilableConsequence);
if (startOfExpression) {
- Collection jdtProps = getJavaMvelCompletionProposals("",
- prefix, documentOffset, params);
+ Collection jdtProps = getJavaMvelCompletionProposals(documentOffset, "", prefix, params);
proposals.addAll(jdtProps);
- addMvelVariables(proposals, compilationContext, documentOffset, prefix);
- addMvelInputs(proposals, compilationContext, documentOffset, prefix);
+ addMvelCompletions( proposals,
+ documentOffset,
+ prefix,
+ compilationContext.getVariables() );
+ addMvelCompletions( proposals,
+ documentOffset,
+ prefix,
+ compilationContext.getInputs() );
+
} else {
// we are completing the methods for an existing type or
- // variable
- // find the last type in the expression to complete against
+ // variable, we need find the last type in the expression to complete against
if (!"".equals(compilableConsequence.trim())) {
-
- // Class lastType = new
- // PropertyVerifier(analyzableExpression,
- // compilationContext).analyze();
- Class lastType = context.getGetMvelReturnedType();
+ Class lastType = context.getMvelReturnedType();
if (lastType == null) {
lastType = Object.class;
}
- String javaText = "\n" + lastType.getName() + " o = new "
- + lastType.getName() + "();\no.";
+ //FIXME: there is a small chance of var name collision using this arbitrary mvdrlofc as a variable name.
+ //ideally the varibale name should be inferred from the last memeber of the expression
+ String syntheticVarName = "mvdrlofc";
+ String javaText = "\n" + lastType.getName().replace( '$', '.' ) + " " + syntheticVarName +
+ ";\n" + syntheticVarName + ".";
Collection jdtProps = getJavaMvelCompletionProposals(
- javaText, prefix, documentOffset, params);
+ documentOffset, javaText, prefix, params);
proposals.addAll(jdtProps);
}
}
@@ -784,168 +1003,260 @@
return proposals;
}
- private ParserContext createMvelAnalysisContext(Map params,
- DRLInfo drlInfo, String compilableConsequence) {
+ private Map getResolvedMvelInputs(Map params) {
+ ClassTypeResolver resolver = new ClassTypeResolver( getUniqueImports(),
+ ProjectClassLoader.getProjectClassLoader( getEditor() ) );
- String currentRulename = context.getRule().getName();
- RuleInfo[] ruleInfos = drlInfo.getRuleInfos();
- RuleInfo currentRule = null;
- for (int i = 0; i < ruleInfos.length; i++) {
- if (currentRulename.equals(ruleInfos[i].getRuleName())) {
- currentRule = ruleInfos[i];
- break;
- }
- }
- // MVEL: test for null
- MVELDialect dialect = (MVELDialect) currentRule.getDialect();
+ Map resolved = new HashMap();
+ for ( Iterator iter = params.entrySet().iterator(); iter.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String inputType = (String) entry.getValue();
+ try {
+ Class type = resolver.resolveType( inputType );
+ resolved.put( entry.getKey(),
+ type );
+ } catch ( ClassNotFoundException e ) {
+ DroolsEclipsePlugin.log( e );
+ }
+ }
+ return resolved;
+ }
- ExpressionCompiler compiler = new ExpressionCompiler(
- compilableConsequence);
+ private ParserContext createMvelAnalysisContext(Map params,
+ DRLInfo drlInfo,
+ String compilableConsequence) {
- final ParserContext initialContext = new ParserContext();
- initialContext.setStrictTypeEnforcement(false);
- Map imports = dialect.getClassImportResolverFactory()
- .getImportedClasses();
- imports.putAll(dialect.getStaticMethodImportResolverFactory()
- .getImportedMethods());
- initialContext.setImports(imports);
- initialContext.setInterceptors(dialect.getInterceptors());
- initialContext.setInputs(params);
- initialContext.setCompiled(true);
+ final ParserContext initialContext = new ParserContext();
- try {
- CompiledExpression expression = compiler.compile(initialContext);
- context.setGetMvelReturnedType(expression.getKnownEgressType());
- ParserContext compilationContext = compiler.getParserContextState();
- return compilationContext;
- } catch (Exception e) {
- return initialContext;
- }
- }
+ try {
+ String currentRulename = context.getRule().getName();
+ RuleInfo[] ruleInfos = drlInfo.getRuleInfos();
+ RuleInfo currentRule = null;
+ for ( int i = 0; i < ruleInfos.length; i++ ) {
+ if ( currentRulename.equals( ruleInfos[i].getRuleName() ) ) {
+ currentRule = ruleInfos[i];
+ break;
+ }
+ }
- private void addMvelInputs(final Collection proposals,
- ParserContext compilationContext, int documentOffset, String prefix) {
- Map inputs = compilationContext.getInputs();
- for (Iterator iter = inputs.keySet().iterator(); iter.hasNext();) {
- String prop = (String) iter.next();
- RuleCompletionProposal rcp = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), prop);
- rcp.setImage(DefaultCompletionProcessor.VARIABLE_ICON);
- proposals.add(rcp);
- }
- }
+ MVELDialect dialect = (MVELDialect) currentRule.getDialect();
+ initialContext.setStrictTypeEnforcement( dialect.isStrictMode() );
- private void addMvelVariables(final Collection proposals,
- ParserContext compilationContext, int documentOffset, String prefix) {
- Map variables = compilationContext.getVariables();
- for (Iterator iter = variables.keySet().iterator(); iter.hasNext();) {
- String prop = (String) iter.next();
- RuleCompletionProposal rcp = new RuleCompletionProposal(
- documentOffset - prefix.length(), prefix.length(), prop);
- rcp.setImage(DefaultCompletionProcessor.VARIABLE_ICON);
- proposals.add(rcp);
- }
- }
+ Map imports = dialect.getClassImportResolverFactory().getImportedClasses();
+ imports.putAll( dialect.getStaticMethodImportResolverFactory().getImportedMethods() );
+ initialContext.setImports( imports );
- private void addRuleParameters(Map result, List descrs) {
- if (descrs == null) {
- return;
- }
- Iterator iterator = descrs.iterator();
- while (iterator.hasNext()) {
- BaseDescr descr = (BaseDescr) iterator.next();
- addRuleParameters(result, descr);
- }
- }
+ initialContext.setInterceptors( dialect.getInterceptors() );
+ initialContext.setInputs( getResolvedMvelInputs( params ) );
+ initialContext.setCompiled( true );
- private void addRuleParameters(Map result, BaseDescr descr) {
- if (descr == null) {
- return;
- }
- if (descr instanceof PatternDescr) {
- String name = ((PatternDescr) descr).getIdentifier();
- if (name != null) {
- result.put(name, ((PatternDescr) descr).getObjectType());
- }
- addRuleSubParameters(result, ((PatternDescr) descr).getDescrs(),
- ((PatternDescr) descr).getObjectType());
- } else if (descr instanceof AndDescr) {
- addRuleParameters(result, ((AndDescr) descr).getDescrs());
- } else if (descr instanceof OrDescr) {
- addRuleParameters(result, ((OrDescr) descr).getDescrs());
- } else if (descr instanceof ExistsDescr) {
- addRuleParameters(result, ((ExistsDescr) descr).getDescrs());
- } else if (descr instanceof NotDescr) {
- addRuleParameters(result, ((NotDescr) descr).getDescrs());
- }
- }
+ //compile the expression
+ ExpressionCompiler compiler = new ExpressionCompiler( compilableConsequence );
+ CompiledExpression expression = compiler.compile( initialContext );
+ ParserContext compilationContext = compiler.getParserContextState();
- private void addRuleSubParameters(Map result, List descrs, String clazz) {
- if (descrs == null) {
- return;
- }
- Iterator iterator = descrs.iterator();
- while (iterator.hasNext()) {
- BaseDescr descr = (BaseDescr) iterator.next();
- if (descr instanceof FieldBindingDescr) {
- FieldBindingDescr fieldDescr = (FieldBindingDescr) descr;
- String name = fieldDescr.getIdentifier();
- String field = fieldDescr.getFieldName();
- String type = getPropertyClass(clazz, field);
- if (name != null) {
- result.put(name, type);
- }
- }
- }
- }
+ Class lastType = expression.getKnownEgressType();
+ context.setMvelReturnedType( lastType );
- private void addRuleHeaderProposals(List list, int documentOffset, String prefix, String backText) {
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "salience",
- "salience ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "no-loop",
- "no-loop ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "agenda-group",
- "agenda-group ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "duration",
- "duration ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "auto-focus",
- "auto-focus ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "when", "when"
- + System.getProperty("line.separator") + "\t ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(),
- "activation-group", "activation-group ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "date-effective",
- "date-effective \"dd-MMM-yyyy\"", 16, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "date-expires",
- "date-expires \"dd-MMM-yyyy\"", 14, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "enabled",
- "enabled false", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "ruleflow-group",
- "ruleflow-group \"\"", 16, DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "lock-on-active",
- "lock-on-active ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "dialect \"java\"",
- "dialect \"java\" ", DROOLS_ICON));
- list.add(new RuleCompletionProposal(documentOffset - prefix.length(), prefix.length(), "dialect \"mvel\"",
- "dialect \"mvel\" ", DROOLS_ICON));
- }
- private boolean addFactTemplatePropertyProposals(int documentOffset, String prefix,
- String templateName, List list) {
- FactTemplateDescr descr = getTemplate(templateName);
- if (descr == null) {
- return false;
- }
- Iterator iterator = descr.getFields().iterator();
- while (iterator.hasNext()) {
- FieldTemplateDescr field = (FieldTemplateDescr) iterator.next();
- String fieldName = field.getName();
- RuleCompletionProposal p = new RuleCompletionProposal(documentOffset - prefix.length(), prefix
- .length(), fieldName, fieldName + " ");
- p.setImage(METHOD_ICON);
- list.add(p);
- }
- return true;
- }
+ if ( "java.lang.Object".equals( lastType.getName() ) ) {
+ // attempt to use the property verifier to get
+ // a better type resolution (a recommend by cbrock, though egress gives consistent results
+ String lastExpression = CompletionUtil.getLastLine( compilableConsequence );
+ lastType = new PropertyVerifier( lastExpression,
+ compilationContext ).analyze();
+ }
+ return compilationContext;
+ } catch ( Exception e ) {
+ return initialContext;
+ }
+ }
+
+ private void addMvelCompletions(final Collection proposals,
+ int documentOffset,
+ String prefix,
+ Map inputs) {
+ for ( Iterator iter = inputs.entrySet().iterator(); iter.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String prop = (String) entry.getKey();
+ Class type = (Class) entry.getValue();
+ String display = prop + " - " + type.getName().replace( '$',
+ '.' );
+
+ RuleCompletionProposal rcp = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ display,
+ prop );
+ rcp.setImage( DefaultCompletionProcessor.VARIABLE_ICON );
+ proposals.add( rcp );
+ }
+ }
+
+ private void addRuleParameters(Map result,
+ List descrs) {
+ if ( descrs == null ) {
+ return;
+ }
+ Iterator iterator = descrs.iterator();
+ while ( iterator.hasNext() ) {
+ BaseDescr descr = (BaseDescr) iterator.next();
+ addRuleParameters( result,
+ descr );
+ }
+ }
+
+ private void addRuleParameters(Map result,
+ BaseDescr descr) {
+ if ( descr == null ) {
+ return;
+ }
+ if ( descr instanceof PatternDescr ) {
+ String name = ((PatternDescr) descr).getIdentifier();
+ if ( name != null ) {
+ result.put( name,
+ ((PatternDescr) descr).getObjectType() );
+ }
+ addRuleSubParameters( result,
+ ((PatternDescr) descr).getDescrs(),
+ ((PatternDescr) descr).getObjectType() );
+ } else if ( descr instanceof AndDescr ) {
+ addRuleParameters( result,
+ ((AndDescr) descr).getDescrs() );
+ } else if ( descr instanceof OrDescr ) {
+ addRuleParameters( result,
+ ((OrDescr) descr).getDescrs() );
+ } else if ( descr instanceof ExistsDescr ) {
+ addRuleParameters( result,
+ ((ExistsDescr) descr).getDescrs() );
+ } else if ( descr instanceof NotDescr ) {
+ addRuleParameters( result,
+ ((NotDescr) descr).getDescrs() );
+ }
+ }
+
+ private void addRuleSubParameters(Map result,
+ List descrs,
+ String clazz) {
+ if ( descrs == null ) {
+ return;
+ }
+ Iterator iterator = descrs.iterator();
+ while ( iterator.hasNext() ) {
+ BaseDescr descr = (BaseDescr) iterator.next();
+ if ( descr instanceof FieldBindingDescr ) {
+ FieldBindingDescr fieldDescr = (FieldBindingDescr) descr;
+ String name = fieldDescr.getIdentifier();
+ String field = fieldDescr.getFieldName();
+ String type = getPropertyClass( clazz,
+ field );
+ if ( name != null ) {
+ result.put( name,
+ type );
+ }
+ }
+ }
+ }
+
+ private void addRuleHeaderProposals(List list,
+ int documentOffset,
+ String prefix,
+ String backText) {
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "salience",
+ "salience ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "no-loop",
+ "no-loop ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "agenda-group",
+ "agenda-group ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "duration",
+ "duration ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "auto-focus",
+ "auto-focus ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "when",
+ "when" + System.getProperty( "line.separator" ) + "\t ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "activation-group",
+ "activation-group ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "date-effective",
+ "date-effective \"dd-MMM-yyyy\"",
+ 16,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "date-expires",
+ "date-expires \"dd-MMM-yyyy\"",
+ 14,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "enabled",
+ "enabled false",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "ruleflow-group",
+ "ruleflow-group \"\"",
+ 16,
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "lock-on-active",
+ "lock-on-active ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "dialect \"java\"",
+ "dialect \"java\" ",
+ DROOLS_ICON ) );
+ list.add( new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ "dialect \"mvel\"",
+ "dialect \"mvel\" ",
+ DROOLS_ICON ) );
+ }
+
+ private boolean addFactTemplatePropertyProposals(int documentOffset,
+ String prefix,
+ String templateName,
+ List list) {
+ FactTemplateDescr descr = getTemplate( templateName );
+ if ( descr == null ) {
+ return false;
+ }
+ Iterator iterator = descr.getFields().iterator();
+ while ( iterator.hasNext() ) {
+ FieldTemplateDescr field = (FieldTemplateDescr) iterator.next();
+ String fieldName = field.getName();
+ RuleCompletionProposal p = new RuleCompletionProposal( documentOffset - prefix.length(),
+ prefix.length(),
+ fieldName,
+ fieldName + " " );
+ p.setImage( METHOD_ICON );
+ list.add( p );
+ }
+ return true;
+ }
+
}
Modified: labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProposal.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProposal.java 2007-08-05 00:56:21 UTC (rev 14040)
+++ labs/jbossrules/trunk/drools-eclipse/drools-eclipse-plugin/src/main/java/org/drools/eclipse/editors/completion/RuleCompletionProposal.java 2007-08-05 02:32:30 UTC (rev 14041)
@@ -24,7 +24,7 @@
private int cursorPosition;
private Image image;
private int priority;
-
+
/** This is used when the stuff that is displayed, is the stuff that is used. */
public RuleCompletionProposal(int replacementOffset, int replacementLength, String content) {
this(replacementOffset, replacementLength, content, content);
@@ -73,7 +73,7 @@
public String getContent() {
return content;
}
-
+
public void setImage(Image image) {
this.image = image;
}
@@ -89,7 +89,8 @@
public String toString() {
return content;
}
-
+
+ //TODO:fixme now that we mix,JDT and own propsals, comparison is all wrong, resulting in wrong ordering of mixed proposals (such as with mvel
public static class RuleCompletionProposalComparator implements Comparator {
public int compare(Object arg0, Object arg1) {
if (arg0 instanceof RuleCompletionProposal) {
More information about the jboss-svn-commits
mailing list