[jboss-svn-commits] JBL Code SVN: r28954 - in labs/jbossrules/trunk: drools-assistant and 23 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Aug 16 20:35:58 EDT 2009


Author: lucazamador
Date: 2009-08-16 20:35:57 -0400 (Sun, 16 Aug 2009)
New Revision: 28954

Added:
   labs/jbossrules/trunk/drools-assistant/
   labs/jbossrules/trunk/drools-assistant/pom.xml
   labs/jbossrules/trunk/drools-assistant/src/
   labs/jbossrules/trunk/drools-assistant/src/main/
   labs/jbossrules/trunk/drools-assistant/src/main/java/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleRefactorAssistant.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleSuggestionAssistant.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/AbstractParserEngine.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DRLParserEngine.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DSLParserEngine.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/RuleRefactorInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLContentTypeEnum.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLRuleRefactorInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleBasicContentInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleDRLContentInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleLineContentInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/dsl/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/dsl/DSLRuleRefactorInfo.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/AssistantOption.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/RenameAssistantOption.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/ReplaceAssistantOption.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleAssistantProcessor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleRefactorProcessor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DRLRefactorProcessor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DSLRefactorProcessor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/AbstractRuleRefactor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DRLRuleRefactor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DSLRuleRefactor.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/FixImport.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/Variable.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableBinding.java
   labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableRename.java
   labs/jbossrules/trunk/drools-assistant/src/test/
   labs/jbossrules/trunk/drools-assistant/src/test/java/
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLAssistantTest.java
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLParserEngineTest.java
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DSLParserEngineTest.java
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/FixImportTest.java
   labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/VariableBindingTest.java
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/DRLProjectDetector.java
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RefactoringContent.java
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileMoveParticipant.java
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileRenameParticipant.java
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleSourceFieldRenameParticipant.java
Modified:
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/META-INF/MANIFEST.MF
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/plugin.xml
Log:
drools assistant initial import
added 3 extensions points to plugin to xml to use eclipse ltk refactoring
type rename, field rename, package & files move refactoring (without quick assistant/fix) only throught refactoring dialog


Property changes on: labs/jbossrules/trunk/drools-assistant
___________________________________________________________________
Name: svn:ignore
   + .project


Added: labs/jbossrules/trunk/drools-assistant/pom.xml
===================================================================
--- labs/jbossrules/trunk/drools-assistant/pom.xml	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/pom.xml	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,23 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+		<artifactId>drools</artifactId>
+		<groupId>org.drools</groupId>
+		<version>5.1.0.SNAPSHOT</version>
+  </parent>
+  <artifactId>drools-assistant</artifactId>
+  <packaging>jar</packaging>
+  <version>5.1.0.SNAPSHOT</version>
+  <name>Drools :: Assistant</name>
+  <dependencies>
+  	<dependency>
+  		<groupId>junit</groupId>
+  		<artifactId>junit</artifactId>
+  		<version>3.8.1</version>
+  		<type>jar</type>
+  		<scope>test</scope>
+  		<optional>false</optional>
+  	</dependency>
+  </dependencies>
+</project>

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleRefactorAssistant.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleRefactorAssistant.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleRefactorAssistant.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,5 @@
+package org.drools.assistant;
+
+public interface RuleRefactorAssistant {
+	public String bindPatternToVariable(String backText);
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleSuggestionAssistant.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleSuggestionAssistant.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/RuleSuggestionAssistant.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,5 @@
+package org.drools.assistant;
+
+public interface RuleSuggestionAssistant {
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/AbstractParserEngine.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/AbstractParserEngine.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/AbstractParserEngine.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,17 @@
+package org.drools.assistant.engine;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+
+public abstract class AbstractParserEngine {
+	
+	protected RuleRefactorInfo ruleRefactorInfo;
+	protected Pattern pattern;
+	protected Matcher matcher;
+	protected String rule;
+	
+	public abstract RuleRefactorInfo parse();
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DRLParserEngine.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DRLParserEngine.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DRLParserEngine.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,131 @@
+package org.drools.assistant.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.info.drl.DRLContentTypeEnum;
+import org.drools.assistant.info.drl.DRLRuleRefactorInfo;
+import org.drools.assistant.info.drl.RuleLineContentInfo;
+
+/**
+ * A simple DRL parser implemented with regular expressions to get the offset of rule components
+ * 
+ * @author lucas
+ *
+ */
+public class DRLParserEngine extends AbstractParserEngine {
+	
+	private static final String RULE_DECLARATION = "(rule|RULE)";
+	private static final String PACKAGE_DECLARATION = "(package|PACKAGE)";
+	private static final String IMPORT_DECLARATION = "(import|IMPORT)";
+	private static final String GLOBAL_DECLARATION = "(global|GLOBAL)";
+	private static final String RULE_WHEN_DECLARATION = "(when|WHEN)";
+	private static final String RULE_THEN_DECLARATION = "(then|THEN)";
+	private static final String RULE_END_DECLARATION = "(end|END)";
+	
+	private static final String OPTIONAL_TAB = "[\t]*";
+	
+	private static final String FULLY_QUALIFIED_NAME = "[\\w\\.]*";
+	private static final String ONE_OR_MORE_SPACES = "[\\s]+";
+	private static final String RULE_NAME = "\"[\\s\\w]*\"";
+	
+	// Regulars expressions to match DRL Rule 
+	private static final String PACKAGE_PATTERN = PACKAGE_DECLARATION + ONE_OR_MORE_SPACES + FULLY_QUALIFIED_NAME + ";?"; // OK
+	private static final String IMPORT_PATTERN = IMPORT_DECLARATION + ONE_OR_MORE_SPACES + FULLY_QUALIFIED_NAME + ";"; // OK
+	private static final String GLOBAL_PATTERN = GLOBAL_DECLARATION + ONE_OR_MORE_SPACES + FULLY_QUALIFIED_NAME + ONE_OR_MORE_SPACES + "[\\w]*" + ONE_OR_MORE_SPACES + ""; // OK
+
+	private static final String RULE_NAME_PATTERN = RULE_DECLARATION + ONE_OR_MORE_SPACES + RULE_NAME;
+	private static final String RULE_LHS_PATTERN = "[\\t\\s]*" + RULE_WHEN_DECLARATION + ONE_OR_MORE_SPACES + OPTIONAL_TAB + "[\\w\\W]*" + "(?=" + RULE_THEN_DECLARATION + ")";
+	private static final String RULE_RHS_PATTERN = "[\\t\\s]*" + RULE_THEN_DECLARATION + ONE_OR_MORE_SPACES + "[\\w\\W]*" + RULE_END_DECLARATION;
+	
+	private static final Pattern rulePattern = Pattern.compile("rule.+?end\\s*$", Pattern.MULTILINE | Pattern.DOTALL);
+	
+	public DRLParserEngine(String rule) {
+		this.ruleRefactorInfo = new DRLRuleRefactorInfo();
+		this.rule = rule;
+	}
+	
+	public RuleRefactorInfo parse() {
+		detectPackage(rule);
+		detectGlobals(rule);
+		detectImports(rule);
+		detectRules(rule);
+		return ruleRefactorInfo;
+	}
+	
+	private void detectPackage(CharSequence rule) {
+		pattern = Pattern.compile(PACKAGE_PATTERN);
+		matcher = pattern.matcher(rule);
+		if (matcher.find())
+			((DRLRuleRefactorInfo) ruleRefactorInfo).addContent(DRLContentTypeEnum.PACKAGE, matcher.start(), matcher.group());
+	}
+
+	private void detectImports(CharSequence rule) {
+		pattern = Pattern.compile(IMPORT_PATTERN);
+		matcher = pattern.matcher(rule);
+		while (matcher.find())
+			((DRLRuleRefactorInfo) ruleRefactorInfo).addContent(DRLContentTypeEnum.IMPORT, matcher.start(), matcher.group());
+	}
+	
+	private void detectGlobals(CharSequence rule) {
+		pattern = Pattern.compile(GLOBAL_PATTERN);
+		matcher = pattern.matcher(rule);
+		while (matcher.find())
+			((DRLRuleRefactorInfo) ruleRefactorInfo).addContent(DRLContentTypeEnum.GLOBAL, matcher.start(), matcher.group());
+	}
+	
+	private void detectRules(CharSequence rule) {
+		Matcher ruleMatcher = rulePattern.matcher(rule);
+		while (ruleMatcher.find()) {
+			for( int position = 0; position < ruleMatcher.groupCount()+1; position++ ){
+				String value = ruleMatcher.group(position);
+				int offset = ruleMatcher.start();
+				String ruleName = detectRuleName(value);
+				List<RuleLineContentInfo> lhs = detectLHS(value, offset);
+				// TODO: remove this awful line... need to optimize the lhs regex
+				lhs.remove(lhs.size()-1);
+				List<RuleLineContentInfo> rhs = detectRHS(value, offset);
+				((DRLRuleRefactorInfo) ruleRefactorInfo).addContent(DRLContentTypeEnum.RULE, offset, value, ruleName, lhs, rhs);
+			}
+		}
+	}
+	
+	private String detectRuleName(CharSequence rule) {
+		pattern = Pattern.compile(RULE_NAME_PATTERN);
+		matcher = pattern.matcher(rule);
+		if (matcher.find())
+			return matcher.group();
+		return null;
+	}
+	
+	private List<RuleLineContentInfo> detectLHS(CharSequence rule, int ruleOffset) {
+		pattern = Pattern.compile(RULE_LHS_PATTERN);
+		matcher = pattern.matcher(rule);
+		if (matcher.find())
+			return detectLines(matcher.group(), matcher.start() + ruleOffset, DRLContentTypeEnum.RULE_LHS_LINE);
+		return null;
+	}
+	
+	private List<RuleLineContentInfo> detectRHS(CharSequence rule, int ruleOffset) {
+		pattern = Pattern.compile(RULE_RHS_PATTERN);
+		matcher = pattern.matcher(rule);
+		if (matcher.find())
+			return detectLines(matcher.group(), matcher.start() + ruleOffset, DRLContentTypeEnum.RULE_RHS_LINE);
+		return null;
+	}
+	
+	private List<RuleLineContentInfo> detectLines(CharSequence rule, int lineOffset, DRLContentTypeEnum type) {
+		List<RuleLineContentInfo> ruleLines = new ArrayList<RuleLineContentInfo>();
+		pattern = Pattern.compile(".*");
+		matcher = pattern.matcher(rule);
+		while (matcher.find()) {
+			if (matcher.start()!=matcher.end())
+				ruleLines.add(new RuleLineContentInfo(matcher.start()+lineOffset, matcher.group(), type));
+		}
+		return ruleLines;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DSLParserEngine.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DSLParserEngine.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/engine/DSLParserEngine.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,43 @@
+package org.drools.assistant.engine;
+
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.info.dsl.DSLRuleRefactorInfo;
+
+public class DSLParserEngine extends AbstractParserEngine {
+	
+	private static final String WHEN_PATTERN = "(\\[when\\]|\\[consequence\\]).*";
+	private static final String THEN_PATTERN = "\\[then\\].*";
+
+	
+	public DSLParserEngine(String rule) {
+		this.ruleRefactorInfo = new DSLRuleRefactorInfo();
+		this.rule = rule;
+	}
+	
+	@Override
+	public RuleRefactorInfo parse() {
+		detectWHEN();
+		detectTHEN();
+		return ruleRefactorInfo;
+	}
+
+	
+	private void detectWHEN() {
+		pattern = Pattern.compile(WHEN_PATTERN);
+		matcher = pattern.matcher(rule);
+		System.out.println("--------------when--------------");
+		while (matcher.find())
+			System.out.println(matcher.group() + "\n\tstart at index " + matcher.start());
+	}
+	
+	private void detectTHEN() {
+		pattern = Pattern.compile(THEN_PATTERN);
+		matcher = pattern.matcher(rule);
+		System.out.println("--------------then--------------");
+		while (matcher.find())
+			System.out.println(matcher.group() + "\n\tstart at index " + matcher.start());
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/RuleRefactorInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/RuleRefactorInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/RuleRefactorInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,8 @@
+package org.drools.assistant.info;
+
+
+public interface RuleRefactorInfo {
+	
+//	public AbstractRuleBasicContentInfo getContentAt(int offset);
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLContentTypeEnum.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLContentTypeEnum.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLContentTypeEnum.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,15 @@
+package org.drools.assistant.info.drl;
+
+public enum DRLContentTypeEnum {
+	
+	PACKAGE,
+	IMPORT,
+	GLOBAL,
+	RULE,
+	RULE_LHS_LINE,
+	RULE_RHS_LINE;
+	
+	DRLContentTypeEnum() {
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLRuleRefactorInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLRuleRefactorInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/DRLRuleRefactorInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,80 @@
+package org.drools.assistant.info.drl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+
+public class DRLRuleRefactorInfo implements RuleRefactorInfo {
+
+	private Map<Integer, RuleBasicContentInfo> contents;
+	
+	public DRLRuleRefactorInfo() {
+		contents = new TreeMap<Integer, RuleBasicContentInfo>();
+	}
+	
+	public void addContent(DRLContentTypeEnum type, Integer offset, String content) {
+		this.contents.put(offset, new RuleBasicContentInfo(offset, content, type));
+	}
+	
+	public void addContent(DRLContentTypeEnum type, int offset, String content, String ruleName, List<RuleLineContentInfo> lhs, List<RuleLineContentInfo> rhs) {
+		RuleDRLContentInfo contentInfo = new RuleDRLContentInfo(offset, content, type, ruleName, lhs, rhs);
+		for (RuleLineContentInfo ruleLine : contentInfo.getLHSRuleLines())
+			ruleLine.setRule(contentInfo);
+		for (RuleLineContentInfo ruleLine : contentInfo.getRHSRuleLines())
+			ruleLine.setRule(contentInfo);
+		this.contents.put(offset, contentInfo);
+	}
+	
+	public RuleBasicContentInfo getContentAt(int offset) {
+		if (contents.containsKey(offset))
+			return contents.get(offset);
+		int previousKey = 0;
+		for (Integer key : contents.keySet()) {
+			if (key > offset) {
+				RuleBasicContentInfo info = contents.get(previousKey);
+				if ((previousKey + info.getContentLength()) >= offset) {
+					if (info.getType().equals(DRLContentTypeEnum.RULE))
+						return searchInsideTheRule(offset, (RuleDRLContentInfo) info);
+					return info;
+				}
+				return null;
+			}
+			previousKey = key;
+		}
+		RuleBasicContentInfo info = contents.get(previousKey);
+		if (info.getType().equals(DRLContentTypeEnum.RULE))
+			return searchInsideTheRule(offset, (RuleDRLContentInfo) info);
+		return (info.getContentLength() + previousKey > offset)?info:null;
+	}
+	
+	private RuleBasicContentInfo searchInsideTheRule(int offset, RuleDRLContentInfo info) {
+		// search if inside the rulename
+		if (offset <= info.getRuleNameLength() + info.getOffset())
+			return null;
+		// search in LHS
+		for(RuleLineContentInfo ruleLine : info.getLHSRuleLines()) {
+			if (offset <= ruleLine.getOffset() + ruleLine.getContentLength())
+				return ruleLine;
+		}
+		// search in RHS
+		for(RuleLineContentInfo ruleLine : info.getRHSRuleLines()) {
+			if (offset <= ruleLine.getOffset() + ruleLine.getContentLength())
+				return ruleLine;
+		}
+		return null;
+	}
+	
+	public List<RuleBasicContentInfo> getImports() {
+		List<RuleBasicContentInfo> imports = new ArrayList<RuleBasicContentInfo>();
+		for (Integer key : contents.keySet()) {
+			RuleBasicContentInfo info = contents.get(key);
+			if (info.getType().equals(DRLContentTypeEnum.IMPORT))
+				imports.add(info);
+		}
+		return imports;
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleBasicContentInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleBasicContentInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleBasicContentInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,27 @@
+package org.drools.assistant.info.drl;
+
+public class RuleBasicContentInfo {
+
+	private Integer offset;
+	private String content;
+	private DRLContentTypeEnum type;
+	
+	public RuleBasicContentInfo(Integer offset, String content, DRLContentTypeEnum type) {
+		this.offset = offset;
+		this.content = content;
+		this.type = type;
+	}
+	public Integer getOffset() {
+		return offset;
+	}
+	public String getContent() {
+		return content;
+	}
+	public int getContentLength() {
+		return content.length();
+	}
+	public DRLContentTypeEnum getType() {
+		return type;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleDRLContentInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleDRLContentInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleDRLContentInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,53 @@
+package org.drools.assistant.info.drl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RuleDRLContentInfo extends RuleBasicContentInfo {
+	
+	private String ruleName;
+	private List<RuleLineContentInfo> lhs;
+	private List<RuleLineContentInfo> rhs;
+
+	public RuleDRLContentInfo(Integer offset, String content, DRLContentTypeEnum type, String ruleName, List<RuleLineContentInfo> lhs, List<RuleLineContentInfo> rhs) {
+		super(offset, content, type);
+		this.setRuleName(ruleName);
+		this.lhs = lhs;
+		this.rhs = rhs;
+	}
+
+	public void setRuleName(String ruleName) {
+		this.ruleName = ruleName;
+	}
+
+	public String getRuleName() {
+		return ruleName;
+	}
+	
+	public Integer getRuleNameLength() {
+		return ruleName.length();
+	}
+	
+	public void addLHSRuleLine(RuleLineContentInfo ruleLine) {
+		this.lhs.add(ruleLine);
+	}
+
+	public List<RuleLineContentInfo> getLHSRuleLines() {
+		return lhs;
+	}
+	
+	public void addRHSRuleLine(RuleLineContentInfo ruleLine) {
+		this.rhs.add(ruleLine);
+	}
+
+	public List<RuleLineContentInfo> getRHSRuleLines() {
+		return rhs;
+	}
+	
+	public List<RuleLineContentInfo> getAllLines() {
+		List<RuleLineContentInfo> all = new ArrayList<RuleLineContentInfo>(lhs);
+		all.addAll(rhs);
+		return all;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleLineContentInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleLineContentInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/drl/RuleLineContentInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,19 @@
+package org.drools.assistant.info.drl;
+
+public class RuleLineContentInfo extends RuleBasicContentInfo {
+
+	private RuleDRLContentInfo rule;
+	
+	public RuleLineContentInfo(Integer offset, String content, DRLContentTypeEnum type) {
+		super(offset, content, type);
+	}
+
+	public void setRule(RuleDRLContentInfo rule) {
+		this.rule = rule;
+	}
+
+	public RuleDRLContentInfo getRule() {
+		return rule;
+	}
+
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/dsl/DSLRuleRefactorInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/dsl/DSLRuleRefactorInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/info/dsl/DSLRuleRefactorInfo.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,25 @@
+package org.drools.assistant.info.dsl;
+
+import java.util.List;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+
+public class DSLRuleRefactorInfo implements RuleRefactorInfo {
+
+	private List<String> when;
+	private List<String> then;
+	
+	public List<String> getWhen() {
+		return when;
+	}
+	public void setWhen(List<String> when) {
+		this.when = when;
+	}
+	public List<String> getThen() {
+		return then;
+	}
+	public void setThen(List<String> then) {
+		this.then = then;
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/AssistantOption.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/AssistantOption.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/AssistantOption.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,42 @@
+package org.drools.assistant.option;
+
+public abstract class AssistantOption {
+	
+	protected String display;
+	protected String content;
+	protected Integer length;
+	protected Integer offset;
+	protected Integer position;
+
+	public String getDisplay() {
+		return display;
+	}
+	public void setDisplay(String display) {
+		this.display = display;
+	}
+	public String getContent() {
+		return content;
+	}
+	public void setContent(String content) {
+		this.content = content;
+	}
+	public Integer getLength() {
+		return length;
+	}
+	public void setLength(Integer length) {
+		this.length = length;
+	}
+	public Integer getOffset() {
+		return offset;
+	}
+	public void setOffset(Integer offset) {
+		this.offset = offset;
+	}
+	public void setPosition(Integer position) {
+		this.position = position;
+	}
+	public Integer getPosition() {
+		return position;
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/RenameAssistantOption.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/RenameAssistantOption.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/RenameAssistantOption.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,22 @@
+package org.drools.assistant.option;
+
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+
+public class RenameAssistantOption extends AssistantOption {
+	
+	private RuleBasicContentInfo contentInfo;
+	
+	public RenameAssistantOption(String display, String content, RuleBasicContentInfo contentInfo, Integer position) {
+		this.display = display;
+		this.content = content;
+		this.contentInfo = contentInfo;
+		this.offset = position;
+		// FIXME: weird assignation
+		this.position = position;
+	}
+
+	public RuleBasicContentInfo getContentInfo() {
+		return contentInfo;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/ReplaceAssistantOption.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/ReplaceAssistantOption.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/option/ReplaceAssistantOption.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,13 @@
+package org.drools.assistant.option;
+
+public class ReplaceAssistantOption extends AssistantOption {
+	
+	public ReplaceAssistantOption(String display, String content, Integer offset, Integer length, Integer position) {
+		this.display = display;
+		this.content = content;
+		this.offset = offset;
+		this.length = length;
+		this.position = position;
+	}
+	
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleAssistantProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleAssistantProcessor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleAssistantProcessor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,11 @@
+package org.drools.assistant.processor;
+
+import java.util.List;
+
+import org.drools.assistant.option.AssistantOption;
+
+public abstract class AbstractRuleAssistantProcessor {
+	
+	public abstract List<AssistantOption> getRuleAssistant(String text, Integer offset);
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleRefactorProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleRefactorProcessor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/AbstractRuleRefactorProcessor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,14 @@
+package org.drools.assistant.processor;
+
+import org.drools.assistant.engine.AbstractParserEngine;
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.refactor.AbstractRuleRefactor;
+
+public abstract class AbstractRuleRefactorProcessor extends AbstractRuleAssistantProcessor {
+
+	protected AbstractRuleRefactor ruleRefactorEngine;
+	protected AbstractParserEngine ruleParserEngine;
+	
+	protected abstract RuleRefactorInfo generateRuleRefactorInfo(String text);
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DRLRefactorProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DRLRefactorProcessor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DRLRefactorProcessor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,41 @@
+package org.drools.assistant.processor;
+
+import java.util.List;
+
+import org.drools.assistant.engine.DRLParserEngine;
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.RenameAssistantOption;
+import org.drools.assistant.refactor.DRLRuleRefactor;
+import org.drools.assistant.refactor.drl.VariableRename;
+
+public class DRLRefactorProcessor extends AbstractRuleRefactorProcessor {
+	
+	private static DRLRefactorProcessor instance;
+	
+	@Override
+	public List<AssistantOption> getRuleAssistant(String text, Integer offset) {
+		RuleRefactorInfo ruleRefactorInfo = generateRuleRefactorInfo(text);
+		ruleRefactorEngine = new DRLRuleRefactor(ruleRefactorInfo);
+		return ruleRefactorEngine.execute(offset);
+	}
+	
+	@Override
+	protected RuleRefactorInfo generateRuleRefactorInfo(String text) {
+		ruleParserEngine = new DRLParserEngine(text);
+		RuleRefactorInfo info = ruleParserEngine.parse();
+		return info;
+	}
+	
+	public AssistantOption executeVariableRename(RenameAssistantOption assistantOption, String newVariableName) {
+		return VariableRename.execute(assistantOption, newVariableName);
+	}
+
+
+	public static DRLRefactorProcessor getInstance() {
+		if (instance==null)
+			instance = new DRLRefactorProcessor();
+		return instance;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DSLRefactorProcessor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DSLRefactorProcessor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/processor/DSLRefactorProcessor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,25 @@
+package org.drools.assistant.processor;
+
+import java.util.List;
+
+import org.drools.assistant.engine.DSLParserEngine;
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.refactor.DSLRuleRefactor;
+
+public class DSLRefactorProcessor extends AbstractRuleRefactorProcessor {
+
+	@Override
+	public List<AssistantOption> getRuleAssistant(String text, Integer offset) {
+		RuleRefactorInfo ruleRefactorInfo = this.generateRuleRefactorInfo(text);
+		ruleRefactorEngine = new DSLRuleRefactor(ruleRefactorInfo);
+		return ruleRefactorEngine.execute(offset);
+	}
+	
+	@Override
+	protected RuleRefactorInfo generateRuleRefactorInfo(String text) {
+		ruleParserEngine = new DSLParserEngine(text);
+		return ruleParserEngine.parse();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/AbstractRuleRefactor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/AbstractRuleRefactor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/AbstractRuleRefactor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,24 @@
+package org.drools.assistant.refactor;
+
+import java.util.List;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.option.AssistantOption;
+
+public abstract class AbstractRuleRefactor {
+
+	protected RuleRefactorInfo ruleRefactorInfo;
+	protected List<AssistantOption> options;
+	protected AssistantOption option;
+	protected int offset;
+	
+	public abstract List<AssistantOption> execute(int offset);
+	
+	protected abstract AssistantOption bindVariable(RuleBasicContentInfo contentInfo);
+	
+	protected abstract AssistantOption fixImports(RuleBasicContentInfo contentInfo);
+	
+	protected abstract AssistantOption renameVariable(RuleBasicContentInfo contentInfo);
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DRLRuleRefactor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DRLRuleRefactor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DRLRuleRefactor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,73 @@
+package org.drools.assistant.refactor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.info.drl.DRLContentTypeEnum;
+import org.drools.assistant.info.drl.DRLRuleRefactorInfo;
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.RenameAssistantOption;
+import org.drools.assistant.option.ReplaceAssistantOption;
+import org.drools.assistant.refactor.drl.FixImport;
+import org.drools.assistant.refactor.drl.VariableBinding;
+import org.drools.assistant.refactor.drl.VariableRename;
+
+public class DRLRuleRefactor extends AbstractRuleRefactor {
+
+	public DRLRuleRefactor(RuleRefactorInfo refactorInfo) {
+		this.ruleRefactorInfo = refactorInfo;
+		this.options = new ArrayList<AssistantOption>();
+	}
+
+	@Override
+	public List<AssistantOption> execute(int offset) {
+		this.offset = offset;
+		RuleBasicContentInfo contentInfo = ((DRLRuleRefactorInfo)ruleRefactorInfo).getContentAt(offset);
+		if (contentInfo==null)
+			return this.options;
+		if ((option = this.bindVariable(contentInfo))!=null)
+			this.options.add(option);
+		if ((option = this.fixImports(contentInfo))!=null)
+			this.options.add(option);
+		if ((option = this.renameVariable(contentInfo))!=null)
+			this.options.add(option);
+		return this.options;
+	}
+
+	@Override
+	protected AssistantOption bindVariable(RuleBasicContentInfo contentInfo) {
+		if (contentInfo==null) return null;
+		if (!contentInfo.getType().equals(DRLContentTypeEnum.RULE_LHS_LINE))
+			return null;
+		String response = VariableBinding.execute(contentInfo, offset-contentInfo.getOffset());
+		if (response.equals(contentInfo.getContent()))
+			return null;
+		return new ReplaceAssistantOption("assign to variable", response, contentInfo.getOffset(), contentInfo.getContentLength(), offset);
+	}
+
+	@Override
+	protected AssistantOption fixImports(RuleBasicContentInfo contentInfo) {
+		if (contentInfo==null) return null;
+		if (!contentInfo.getType().equals(DRLContentTypeEnum.RULE_LHS_LINE) &&
+				!contentInfo.getType().equals(DRLContentTypeEnum.RULE_RHS_LINE))
+			return null;
+		List<RuleBasicContentInfo> imports = ((DRLRuleRefactorInfo)ruleRefactorInfo).getImports();
+		FixImport.execute(contentInfo, imports);
+		return null;
+	}
+
+	@Override
+	protected AssistantOption renameVariable(RuleBasicContentInfo contentInfo) {
+		if (contentInfo==null) return null;
+		if (!contentInfo.getType().equals(DRLContentTypeEnum.RULE_LHS_LINE) &&
+				!contentInfo.getType().equals(DRLContentTypeEnum.RULE_RHS_LINE))
+			return null;
+		String variable;
+		if ((variable = VariableRename.isPossible(contentInfo, offset-contentInfo.getOffset()))!=null)
+			return new RenameAssistantOption("rename variable", variable, contentInfo, contentInfo.getOffset());
+		return null;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DSLRuleRefactor.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DSLRuleRefactor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/DSLRuleRefactor.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,44 @@
+package org.drools.assistant.refactor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.assistant.info.RuleRefactorInfo;
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.ReplaceAssistantOption;
+
+public class DSLRuleRefactor extends AbstractRuleRefactor {
+	
+	private List<AssistantOption> options;
+	
+	public DSLRuleRefactor(RuleRefactorInfo ruleRefactorInfo) {
+		this.ruleRefactorInfo = ruleRefactorInfo;
+		this.options = new ArrayList<AssistantOption>();
+	}
+	
+	@Override
+	public List<AssistantOption> execute(int offset) {
+		if ((option = this.bindVariable(null))!=null)
+			this.options.add(option);
+		if ((option = this.fixImports(null))!=null)
+			this.options.add(option);
+		return this.options;
+	}
+
+	@Override
+	protected ReplaceAssistantOption bindVariable(RuleBasicContentInfo contentInfo) {
+		return null;
+	}
+
+	@Override
+	protected ReplaceAssistantOption fixImports(RuleBasicContentInfo contentInfo) {
+		return null;
+	}
+
+	@Override
+	protected ReplaceAssistantOption renameVariable(RuleBasicContentInfo contentInfo) {
+		return null;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/FixImport.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/FixImport.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/FixImport.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,70 @@
+package org.drools.assistant.refactor.drl;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.info.drl.RuleDRLContentInfo;
+import org.drools.assistant.info.drl.RuleLineContentInfo;
+
+public class FixImport {
+	
+	private static final String CLASS_PATTERN = "[\\s\\t:,]+[a-zA-Z]*\\(";
+	
+	private static final String[] KEYWORDS = {"new", "update", "insert"};
+	
+	private static final Pattern pattern = Pattern.compile(CLASS_PATTERN);
+	private static Matcher matcher;
+	
+	private static List<String> classes = new ArrayList<String>();
+	private static List<String> classloaderClasses = new ArrayList<String>();
+	
+	// detect all the Class Name and compare with the current imports
+	// how detect the Classes loaded into the ClassLoader?
+	public static void execute(RuleBasicContentInfo contentInfo, List<RuleBasicContentInfo> imports) {
+		classloaderClasses.clear();
+		classes.clear();
+		RuleDRLContentInfo ruleInfo = ((RuleLineContentInfo)contentInfo).getRule();
+		String rule = "";
+		for (RuleLineContentInfo ruleLineContentInfo : ruleInfo.getLHSRuleLines())
+			rule = rule.concat(ruleLineContentInfo.getContent() + "\n");
+		for (RuleLineContentInfo ruleLineContentInfo : ruleInfo.getRHSRuleLines())
+			rule = rule.concat(ruleLineContentInfo.getContent() + "\n");
+		matcher = pattern.matcher(rule);
+		String className;
+		while (matcher.find()) {
+			className = matcher.group().replaceAll(":", "").replaceAll("\\(", "").replaceAll("\\t", "").replaceAll("\\n", "").trim();
+			addClass(className);
+		}
+		hookClassLoader(ClassLoader.getSystemClassLoader());
+	}
+	
+	private static void addClass(String className) {
+		for (int i = 0; i < KEYWORDS.length; i++)
+			if (KEYWORDS[i].equals(className))
+				return;
+		if (!classes.contains(className))
+			classes.add(className);
+	}
+	
+	private static void hookClassLoader(ClassLoader currLoader) {
+		try {
+			Field field = ClassLoader.class.getDeclaredField ("classes");
+			field.setAccessible(true);
+			Vector<?> currClasses = (Vector<?>)field.get( currLoader );
+			for (int position = 0; position < currClasses.size(); position++) {
+				Class<?> object = (Class<?>) currClasses.get(position);
+				if (!classloaderClasses.contains(object.getCanonicalName()))
+					classloaderClasses.add(object.getCanonicalName());
+			}
+		}
+		catch ( java.lang.Exception ex ) {
+			System.out.println( "Can't hook " + currLoader + ": " + ex );
+		}
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/Variable.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/Variable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/Variable.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,41 @@
+package org.drools.assistant.refactor.drl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.info.drl.RuleLineContentInfo;
+
+public abstract class Variable {
+	
+	private static final String VARIABLE_PATTERN = "[\\$\\d\\w]*\\s*:";
+	private static final Pattern pattern = Pattern.compile(VARIABLE_PATTERN);
+	private static List<String> variables = new ArrayList<String>();
+	private static Matcher matcher;
+	
+	protected static void detectCurrentVariables(RuleBasicContentInfo contentInfo) {
+		variables.clear();
+		String lhs = "";
+		List<RuleLineContentInfo> ruleLines = ((RuleLineContentInfo)contentInfo).getRule().getLHSRuleLines();
+		for (RuleLineContentInfo ruleLineContentInfo : ruleLines)
+			lhs = lhs.concat(ruleLineContentInfo.getContent());
+		matcher = pattern.matcher(lhs);
+		String varname;
+		while (matcher.find()) {
+			varname = matcher.group().replace(":", "").trim();
+			addVariableName(varname);
+		}
+	}
+	
+	protected static boolean existsVariableWithSameName(String varname) {
+		return variables.contains(varname);
+	}
+	
+	private static void addVariableName(String variableName) {
+		if (!variables.contains(variableName))
+			variables.add(variableName);
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableBinding.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableBinding.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableBinding.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,88 @@
+package org.drools.assistant.refactor.drl;
+
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+
+
+public class VariableBinding extends Variable {
+	
+	private static final String DEFAULT_VARIABLE_NAME = "$default";
+	
+	public static String execute(RuleBasicContentInfo contentInfo, int offset) {
+		detectCurrentVariables(contentInfo);
+		return execute(contentInfo.getContent(), offset);
+	}
+
+	public static String execute(String line, int offset) {
+		if (offset > line.length())
+			return line;
+		int position;
+		for (position = offset-1; position >= 0; position--) {
+			if (line.charAt(position)==' ' || line.charAt(position)=='(' || line.charAt(position)=='\t' || line.charAt(position)==',') {
+				String left = line.substring(0, position+1);
+				String right = line.substring(position+1, line.length());
+				if (!VariableBinding.isVariableOrParameter(right, left) && !VariableBinding.hasVariableAssigned(left))
+					return left + getVariableName(right) + right; 
+				return line;
+			}
+		}
+		// search to the right the first : before ( and ,
+		for (position = 0; position < line.length(); position++) {
+			if (line.charAt(position)==':')
+				return line;
+			if (line.charAt(position)=='(' || line.charAt(position)==',')
+				return getVariableName(line) + line;
+		}
+		return line;
+	}
+	
+	// detect if already has an assigned variable or is the right side of the comparator parameter
+	private static boolean isVariableOrParameter(String right, String left) {
+		int position;
+		for (position = 0; position <= right.length()-1; position++) {
+			if (right.charAt(position)==',' || right.charAt(position)=='(')
+				break;
+			if (right.charAt(position)==':')
+				return true;
+		}
+		for (position = left.length()-1; position >=0; position--) {
+			if (left.charAt(position)=='>' || left.charAt(position)=='<' || left.charAt(position)=='=')
+				return true;
+			if (left.charAt(position)==',')
+				return false;
+		}
+		return false;
+	}
+	
+	private static String getVariableName(String right) {
+		for (int position = 0; position < right.length(); position++) {
+			if (right.charAt(position)=='(' || right.charAt(position)==')' || right.charAt(position)==',' ||
+				right.charAt(position)=='<' || right.charAt(position)=='>' || right.charAt(position)=='=') {
+				String varname = "$" + right.substring(0, position).toLowerCase().trim();
+				return generateVariableName(varname);
+			}
+		}
+		return DEFAULT_VARIABLE_NAME;
+	}
+	
+	private static boolean hasVariableAssigned(String line) {
+		for (int position = line.length()-1; position >=0; position--) {
+			if (line.charAt(position)==':')
+				return true;
+			if (line.charAt(position)==',' || line.charAt(position)=='(')
+				return false;
+		}
+		return false;
+	}
+	
+	private static String generateVariableName(String varname) {
+		if (!existsVariableWithSameName(varname))
+			return varname + " : ";
+		// generate a pseudo-random variable name
+		for (int count=1; count <= 100; count++) {
+			if (!existsVariableWithSameName(varname+count))
+				return varname+count + " : ";
+		}
+		return varname;
+	}
+	
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableRename.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableRename.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/main/java/org/drools/assistant/refactor/drl/VariableRename.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,105 @@
+package org.drools.assistant.refactor.drl;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.info.drl.RuleDRLContentInfo;
+import org.drools.assistant.info.drl.RuleLineContentInfo;
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.RenameAssistantOption;
+
+public class VariableRename extends Variable {
+
+	public static AssistantOption execute(RenameAssistantOption assistantOption, String newVariableName) {
+		detectCurrentVariables(assistantOption.getContentInfo());
+		if (existsVariableWithSameName(newVariableName))
+			return null;
+		RuleDRLContentInfo ruleDRLContentInfo = ((RuleLineContentInfo)assistantOption.getContentInfo()).getRule();
+		String rule = getAllRuleLines(ruleDRLContentInfo);
+		Integer offset = getOffsetFirstLine(ruleDRLContentInfo);
+		String content = replaceAllVariables(rule, assistantOption.getContent(), newVariableName);
+		assistantOption.setContent(content);
+		assistantOption.setOffset(offset);
+		assistantOption.setLength(rule.length());
+		return assistantOption;
+	}
+	
+	public static String isPossible(RuleBasicContentInfo contentInfo, int offset) {
+		String line = contentInfo.getContent();
+		int offsetStart = detectVariableOffsetStart(line, offset);
+		if (offsetStart==-1)
+			return null;
+		String right = line.substring(offsetStart);
+		String variableName = detectVariableToReplace(right);
+		if (variableName==null)
+			return null;
+		RuleDRLContentInfo ruleContentInfo = ((RuleLineContentInfo)contentInfo).getRule();
+		String allRule = getAllRuleLines(ruleContentInfo);
+		return hasMoreVariableToReplace(allRule, variableName)?variableName:null;
+	}
+	
+	private static Integer getOffsetFirstLine(RuleDRLContentInfo ruleContentInfo) {
+		List<RuleLineContentInfo> lhsLines = ruleContentInfo.getLHSRuleLines();
+		return lhsLines.get(0).getOffset();
+	}
+	
+	private static String getAllRuleLines(RuleDRLContentInfo ruleContentInfo) {
+		String rule = "";
+		for (RuleLineContentInfo ruleLine : ruleContentInfo.getAllLines())
+			rule = rule.concat(ruleLine.getContent())+"\n";
+		return rule.substring(0, rule.length()-1);
+	}
+	
+	private static boolean hasMoreVariableToReplace(String line, String variableName) {
+		variableName = createPatternToFoundAndReplace(variableName);
+		Pattern pattern = Pattern.compile(variableName+"\\b");
+		Matcher matcher = pattern.matcher(line);
+		int variableCount = 0;
+		while (matcher.find())
+			variableCount++;
+		return variableCount > 1;
+	}
+	
+	private static String detectVariableToReplace(String right) {
+		for (int position = 0; position < right.length(); position++) {
+			if (right.charAt(position)==':' || right.charAt(position)=='.' || right.charAt(position)==')')
+				return right.substring(0, position).trim();
+			if (right.charAt(position)==',' || right.charAt(position)=='(')
+				return null;
+		}
+		return null;
+	}
+	
+	private static String createPatternToFoundAndReplace(String varname) {
+		for (int position = 0; position < varname.length(); position++)
+			if (varname.charAt(position)=='$')
+				return varname.substring(0, position) + "\\$" + varname.substring(position+1, varname.length());
+		return varname;
+	}
+	
+	private static String replaceAllVariables(String rule, String variableName, String newVariableName) {
+		newVariableName = createPatternToFoundAndReplace(newVariableName);
+		variableName = createPatternToFoundAndReplace(variableName);
+		if(variableName.charAt(0)=='$' || variableName.charAt(0)=='\\')
+			return rule.replaceAll("\\B("+variableName+")\\b", newVariableName);
+		rule = rule.replaceAll("\\b"+variableName+"\\s*\\:\\s*", newVariableName + " : ");
+		rule = rule.replaceAll("\\b"+variableName+"\\.", newVariableName + ".");
+		rule = rule.replaceAll("\\b"+variableName+"\\s*\\,\\s*", newVariableName + " , ");
+		rule = rule.replaceAll("\\b"+variableName+"\\s*\\)\\s*", newVariableName + " ) ");
+		rule = rule.replaceAll("\\b"+variableName+"\\s*\\+\\s*", newVariableName + " + ");
+		return rule;
+	}
+	
+	private static int detectVariableOffsetStart(String line, int offset) {
+		for (int position = offset; position > 0; position--) {
+			if (line.charAt(position)==',' || line.charAt(position)=='(')
+				return position+1;
+			if (line.charAt(position)==':' || line.charAt(position)=='.')
+				return -1;
+		}
+		return 0;
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLAssistantTest.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLAssistantTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLAssistantTest.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,76 @@
+package org.drools.assistant;
+
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.ReplaceAssistantOption;
+import org.drools.assistant.processor.AbstractRuleAssistantProcessor;
+import org.drools.assistant.processor.DRLRefactorProcessor;
+
+public class DRLAssistantTest extends TestCase {
+
+	private AbstractRuleAssistantProcessor ruleAssistant;
+	private String rule;
+
+	@Override
+	protected void setUp() throws Exception {
+		ruleAssistant = new DRLRefactorProcessor();
+		rule = 	"package org.drools.assistant.test;\n\n" +
+		"import org.drools.assistant.test.model.Company;\n" +
+		"IMPORT org.drools.assistant.test.model.Employee;\n\n" +
+		"import function org.drools.assistant.model.Class1.anotherFunction \n" +
+		"import		function org.drools.assistant.model.Class1.mathFunction \n" +
+		"global     org.drools.assistant.test.model.Class2    results \n"+
+		"GLOBAL org.drools.assistant.test.model.Class3 current\n"+ 
+		"expander help-expander.dsl\n" +
+		"query \"all clients\"\n" +
+		"	result : Clients()\n" +
+		"end\n" +
+		"query \"new query\"\n" +
+		"	objects : Clients()\n" +
+		"end\n" +
+		"function String hello(String name) {\n"+
+		"    return \"Hello \"+name+\"!\";\n"+
+		"}\n" +
+		"function String helloWithAge(String name, Integer age) {\n"+
+		"    return \"Hello2 \"+name+\"! \" + age;\n"+
+		"}\n" +
+		"rule   \"My Test Rule\"\n" +
+		"when\n"+ 
+		"	$employee : Employee($company : company, $company1 : oldcompany, $age : age > 80, salary > 400)\n" +
+		"	$result : Company(company==$company, retireAge <= $age)\n" + 
+		"then\n"+ 
+		"	System.out.println(\"can retire\")\n" +
+		"end\n"+
+		"rule   \"My Second Rule\"\n" +
+		"when\n"+ 
+		"	Driver(licence = 1234, $name : name)\n" +
+		"	$car : Car(company : $company, ownerLicense == licence, year == 2009)\n" + 
+		"then\n"+ 
+		"	System.out.println(\"licence 1234 has a new car\")\n" +
+		"end\n";
+	}
+
+	public void testAssignSalaryFieldToVariable() throws Exception {
+		List<AssistantOption> options = ruleAssistant.getRuleAssistant(rule, 780);
+		assertEquals(options.size(), 1);
+		ReplaceAssistantOption assistantOption = (ReplaceAssistantOption) options.get(0);
+		Assert.assertEquals("\t$employee : Employee($company : company, $company1 : oldcompany, $age : age > 80, salary $ : > 400)", assistantOption.getContent());
+	}
+
+	public void testDontAssignFieldInsideRHS() throws Exception {
+		List<AssistantOption> options = ruleAssistant.getRuleAssistant(rule, 840);
+		assertEquals(options.size(), 0);
+	}
+
+	public void testAssignLicenseFromSecondRule() throws Exception {
+		List<AssistantOption> options = ruleAssistant.getRuleAssistant(rule, 930);
+		assertEquals(options.size(), 1);
+		ReplaceAssistantOption assistantOption = (ReplaceAssistantOption) options.get(0);
+		Assert.assertEquals("\tDriver($licence : licence = 1234, $name : name)", assistantOption.getContent());
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLParserEngineTest.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLParserEngineTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DRLParserEngineTest.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,126 @@
+package org.drools.assistant;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.drools.assistant.engine.DRLParserEngine;
+import org.drools.assistant.info.drl.DRLContentTypeEnum;
+import org.drools.assistant.info.drl.DRLRuleRefactorInfo;
+import org.drools.assistant.info.drl.RuleBasicContentInfo;
+import org.drools.assistant.info.drl.RuleLineContentInfo;
+
+public class DRLParserEngineTest extends TestCase {
+
+	private String rule;
+	private DRLParserEngine engine;
+	private DRLRuleRefactorInfo info;
+
+	@Override
+	protected void setUp() throws Exception {
+		rule = 	"package org.drools.assistant.test;\n\n" +
+		"import org.drools.assistant.test.model.Company;\n" +
+		"import org.drools.assistant.test.model.Employee;\n\n" +
+		"import function org.drools.assistant.model.Class1.anotherFunction \n" +
+		"import		function org.drools.assistant.model.Class1.mathFunction \n" +
+		"global     org.drools.assistant.test.model.Class2    results \n"+
+		"global org.drools.assistant.test.model.Class3 current\n"+ 
+		"expander help-expander.dsl\n" +
+		"query \"all clients\"\n" +
+		"	result : Clients()\n" +
+		"end\n" +
+		"query \"new query\"\n" +
+		"	objects : Clients()\n" +
+		"end\n" +
+		"function String hello(String name) {\n"+
+		"    return \"Hello \"+name+\"!\";\n"+
+		"}\n" +
+		"function String helloWithAge(String name, Integer age) {\n"+
+		"    return \"Hello2 \"+name+\"! \" + age;\n"+
+		"}\n" +
+		"\trule   \"My Test Rule\"\n" +
+		"when\n"+ 
+		"	$employee : Employee($company : company, $age : age > 80, salary > 400)\n" +
+		"	$result : Company(company == $company, retireAge <= $age)\n" + 
+		"then\n"+ 
+		"	System.out.println(\"can retire\")\n" +
+		"end\n";
+
+		engine = new DRLParserEngine(rule);
+
+	}
+
+	public void testExecuteEngine() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(123);
+		Assert.assertEquals(true, content!=null);
+	}
+
+	public void testImport() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(9);
+		Assert.assertEquals(true, content!=null);
+	}
+
+	public void testNothingInteresting() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(199);
+		Assert.assertEquals(true, content==null);
+	}
+
+	public void testInsideTheRuleName() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(670);
+		Assert.assertEquals(true, content==null);
+	}
+
+	public void testInsideLHSRule() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(790);
+		Assert.assertEquals(true, content!=null);
+	}
+
+	public void testInsideRHSRule() {
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(830);
+		Assert.assertEquals(true, content!=null);
+	}
+
+	public void testSampleDRL() {
+		rule = "package com.sample\n\n" +
+		"import com.sample.DroolsTest.Message;\n" +
+		"import com.sample.Prueba;\n\n" +
+		"\trule \"Hello World\"\n" +
+		"\twhen\n" +
+		"\t\tm : Message( status == Message.HELLO, myMessage : message )\n" +
+		"\t\tPrueba()\n" +
+		"\tthen\n" +
+		"\t\tSystem.out.println( myMessage );\n" +
+		"\t\tm.setMessage( \"Goodbye cruel world\" );\n" +
+		"\t\tm.setStatus( Message.GOODBYE );\n" +
+		"\t\tupdate( m );\n" +
+		"end\n"+
+		"rule \"GoodBye World\"\n" +
+		"\twhen\n" +
+		"\t\tm : Message( status == Message.GOODBYE, myMessage : message )\n" +
+		"\t\tPrueba()\n" +
+		"\tthen\n" +
+		"\t\tSystem.out.println( myMessage );\n" +
+		"\t\tm.setMessage( \"Bon Giorno\" );\n" +
+		"end";
+		engine = new DRLParserEngine(rule);
+		info = (DRLRuleRefactorInfo) engine.parse();
+		RuleBasicContentInfo content = info.getContentAt(173);
+
+		Assert.assertEquals(true, content!=null);
+		Assert.assertEquals(DRLContentTypeEnum.RULE_LHS_LINE, content.getType());
+		Assert.assertEquals("rule \"Hello World\"", ((RuleLineContentInfo)content).getRule().getRuleName());
+		Assert.assertEquals("\t\tPrueba()", content.getContent());
+
+		content = info.getContentAt(343);
+		Assert.assertEquals(true, content!=null);
+		Assert.assertEquals(DRLContentTypeEnum.RULE_LHS_LINE, content.getType());
+		Assert.assertEquals("rule \"GoodBye World\"", ((RuleLineContentInfo)content).getRule().getRuleName());
+		Assert.assertEquals("\twhen", content.getContent());
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DSLParserEngineTest.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DSLParserEngineTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/DSLParserEngineTest.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,30 @@
+package org.drools.assistant;
+
+import org.drools.assistant.engine.DSLParserEngine;
+
+import junit.framework.TestCase;
+
+public class DSLParserEngineTest extends TestCase {
+
+	DSLParserEngine dslParserEngine;
+	private String rule;
+
+	@Override
+	protected void setUp() throws Exception {
+		rule = "#This is a starter DSL to show off some of the features. Make sure you change it to be what you need !.\n" +
+		"[when]There is an Instance with field of \"{value}\"=i: Instance(field==\"{value}\")\n" +
+		"[when]Instance is at least {number} and field is \"{value}\"=i: Instance(number > {number}, location==\"{value}\")\n" +
+		"[then]Log : \"{message}\"=System.out.println(\"{message}\");\n" +
+		"[then]Set field of instance to \"{value}\"=i.setField(\"{value}\");\n" +
+		"[then]Create instance : \"{value}\"=insert(new Instance(\"{value}\"));\n" +
+		"[when]There is no current Instance with field : \"{value}\"=not Instance(field == \"{value}\")\n" +
+		"[then]Report error : \"{error}\"=System.err.println(\"{error}\");\n" +
+		"[then]Retract the fact : '{variable}'=retract({variable}); //this would retract bound variable {variable}\n";
+
+		dslParserEngine = new DSLParserEngine(rule);
+	}
+
+	public void testExecute() {
+//		dslParserEngine.parse();
+	}
+}

Added: labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/FixImportTest.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/FixImportTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/FixImportTest.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,41 @@
+package org.drools.assistant;
+
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.drools.assistant.option.AssistantOption;
+import org.drools.assistant.option.ReplaceAssistantOption;
+import org.drools.assistant.processor.AbstractRuleAssistantProcessor;
+import org.drools.assistant.processor.DRLRefactorProcessor;
+
+public class FixImportTest extends TestCase {
+
+	private AbstractRuleAssistantProcessor ruleAssistant;
+	private String rule;
+
+	protected void setUp() throws Exception {
+		ruleAssistant = new DRLRefactorProcessor();
+		rule = "package com.sample\n\n" +
+		"import com.sample.DroolsTest.Message;\n" +
+		"rule \"Hello World\"\n" +
+		"\twhen\n" +
+		"\t\tm : Message( status == Message.HELLO, myMessage : message )\n" +
+		"\t\tPrueba()\n" +
+		"\tthen\n" +
+		"\t\tSystem.out.println( myMessage );\n" +
+		"\t\tm.setMessage( \"Goodbye cruel world\" );\n" +
+		"\t\tm.setStatus( Message.GOODBYE );\n" +
+		"\t\tupdate( m );\n" +
+		"end";
+	}
+
+	public void testFirstTest() {
+		List<AssistantOption> options = ruleAssistant.getRuleAssistant(rule, 150);
+		assertEquals(1, options.size());
+		ReplaceAssistantOption assistantOption = (ReplaceAssistantOption) options.get(0);
+		Assert.assertEquals("\t\t$prueba : Prueba()", assistantOption.getContent());
+	}
+
+}

Added: labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/VariableBindingTest.java
===================================================================
--- labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/VariableBindingTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-assistant/src/test/java/org/drools/assistant/VariableBindingTest.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,98 @@
+package org.drools.assistant;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.drools.assistant.refactor.drl.VariableBinding;
+
+public class VariableBindingTest extends TestCase {
+
+	private String line;
+	private String response;
+
+	@Override
+	protected void setUp() throws Exception {
+		line = "\tEmployee($company : company, $age : age > 80, salary > 400)";
+	}
+
+	public void testFieldWithVariableAssignedTest1() {
+		response = VariableBinding.execute(line, 24);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+	public void testClassNameWithoutVariableAssigned() {
+		response = VariableBinding.execute(line, 4);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testFieldWithVariableAssignedTest2() {
+		response = VariableBinding.execute(line, 39);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+	public void testAssignVariableInsideTheComparator() {
+		response = VariableBinding.execute(line, 50);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testInsideFieldComparator() {
+		response = VariableBinding.execute(line, 58);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+	public void testComplexLineTestMustAssign() {
+		line = "$ma20 : Double() from accumulate( $r2:ClosePrice(close, this != $r1, this after [0ms,20ms] $r1) , average ( $value ))";
+		response = VariableBinding.execute(line, 53);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testComplexLineTestDontMustAssign() {
+		line = "$ma20 : Double() from accumulate( $r2:ClosePrice($close : close, this != $r1, this after [0ms,20ms] $r1) , average ( $value ))";
+		response = VariableBinding.execute(line, 61);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+	public void testComplexLineClosePriceMustAssign() {
+		line = "$ma20 : Double() from accumulate( ClosePrice($close : close, this != $r1, this after [0ms,20ms] $r1) , average ( $value ))";
+		response = VariableBinding.execute(line, 43);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testComplexLineClosePriceDontMustAssign() {
+		line = "$ma20 : Double() from accumulate( $cp : ClosePrice($close : close, this != $r1, this after [0ms,20ms] $r1) , average ( $value ))";
+		response = VariableBinding.execute(line, 36);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+//	public void testThisDontWorks() {
+//		line = "$ma20 : Double() from accumulate( $r2:ClosePrice($close : close, this != $r1, this after [0ms,20ms] $r1) , average ( $value ))";
+//		response = VariableBinding.execute(line, 121);
+//		System.out.println(response);
+//		Assert.assertEquals(true, response.equals(line));
+//	}
+
+	public void testSampleDRL() {
+		line = "\t\tMessage( status == Message.HELLO, myMessage : message )\n";
+		response = VariableBinding.execute(line, 3);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testWithoutSpacesOrTab() {
+		line = "Message( status == Message.HELLO, myMessage : message )\n";
+		response = VariableBinding.execute(line, 0);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+	public void testWithoutSpacesOrTabButWithVariableAssigned() {
+		line = "m : Message( status == Message.HELLO, myMessage : message )\n";
+		response = VariableBinding.execute(line, 1);
+		Assert.assertEquals(true, response.equals(line));
+	}
+
+	public void testWithoutSpaceOnLeftOfField() {
+		line = "m : Message( status == Message.HELLO,message )\n";
+		response = VariableBinding.execute(line, 37);
+		Assert.assertEquals(false, response.equals(line));
+	}
+
+}

Modified: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/META-INF/MANIFEST.MF
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/META-INF/MANIFEST.MF	2009-08-16 23:28:53 UTC (rev 28953)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/META-INF/MANIFEST.MF	2009-08-17 00:35:57 UTC (rev 28954)
@@ -26,7 +26,9 @@
  org.eclipse.ui.views.properties.tabbed,
  org.eclipse.ui.workbench.texteditor,
  org.eclipse.gef,
- com.ibm.icu
+ com.ibm.icu,
+ org.eclipse.ltk.core.refactoring;bundle-version="3.4.0",
+ org.eclipse.ltk.ui.refactoring;bundle-version="3.4.0"
 Eclipse-LazyStart: true
 Eclipse-BuddyPolicy: registered
 Bundle-ClassPath: .,

Modified: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/plugin.xml
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/plugin.xml	2009-08-16 23:28:53 UTC (rev 28953)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/plugin.xml	2009-08-17 00:35:57 UTC (rev 28954)
@@ -635,6 +635,37 @@
             class="org.drools.eclipse.util.SOAPlatform4RuntimeRecognizer">
       </recognizer>
    </extension>
+   <extension
+         point="org.eclipse.ltk.core.refactoring.moveParticipants">
+      <moveParticipant
+            class="org.drools.eclipse.refactoring.RuleIFileMoveParticipant"
+            id="org.drools.eclipse.refactoring.moveParticipant"
+            name="RuleMoveParticipant">
+         <enablement></enablement>
+      </moveParticipant>
+   </extension>
+   <extension
+         point="org.eclipse.ltk.core.refactoring.renameParticipants">
+      <renameParticipant
+            class="org.drools.eclipse.refactoring.RuleIFileRenameParticipant"
+            id="org.drools.eclipse.refactoring.renameIFileParticipant"
+            name="RuleIFileRenameParticipant">
+            <enablement>
+               <instanceof
+                     value="org.eclipse.core.resources.IFile">
+               </instanceof>
+      		</enablement>
+      </renameParticipant>
+      <renameParticipant
+            class="org.drools.eclipse.refactoring.RuleSourceFieldRenameParticipant"
+            id="org.drools.eclipse.refactoring.renameSourceFieldParticipant"
+            name="RuleSourceFieldRenameParticipant">
+         <enablement>
+            <instanceof
+                  value="org.eclipse.jdt.internal.core.SourceField">
+            </instanceof></enablement>
+      </renameParticipant>
+   </extension>
    
    <!-- tabbed properties
    <extension point="org.eclipse.ui.views.properties.tabbed.propertyContributor">

Added: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/DRLProjectDetector.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/DRLProjectDetector.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/DRLProjectDetector.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,46 @@
+package org.drools.eclipse.refactoring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * To detect the DRL files in the project
+ * @author Lucas Amador
+ *
+ */
+public class DRLProjectDetector {
+
+	private List<IFile> resources;
+
+	public DRLProjectDetector() {
+		resources = new ArrayList<IFile>();
+	}
+
+	public List<IFile> detect(IProject project) throws CoreException {
+		detect(project.members());
+		return resources;
+	}
+
+	private void detect(IResource[] members) throws CoreException {
+		for (int i = 0; i < members.length; i++) {
+			if (members[i] instanceof IFolder) {
+				IFolder folder = (IFolder)members[i];
+				if (!folder.isDerived())
+					detect(((IFolder)members[i]).members());
+			}
+			if (members[i] instanceof IFile) {
+				IFile file = (IFile)members[i];
+				if (file.getFileExtension().equalsIgnoreCase("drl"))
+					if (file.isAccessible() && !file.isReadOnly() && !file.isDerived())
+						resources.add(file);
+			}
+		}
+	}
+
+}

Added: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RefactoringContent.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RefactoringContent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RefactoringContent.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,44 @@
+package org.drools.eclipse.refactoring;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * Store the files content changes when multiple files are refactored at same time.
+ * 
+ * @author Lucas Amador
+ *
+ */
+public class RefactoringContent {
+
+	private Integer processorHashcode;
+	private Map<IFile, String> fileContents;
+
+	public RefactoringContent() {
+		this.processorHashcode = -1;
+		this.fileContents = new HashMap<IFile, String>();
+	}
+
+	public void setProcessorHashcode(Integer processorHashcode) {
+		this.processorHashcode = processorHashcode;
+	}
+
+	public Integer getProcessorHashcode() {
+		return processorHashcode;
+	}
+
+	public String getIFileContent(IFile file) {
+		return this.fileContents.get(file);
+	}
+
+	public void updateContent(IFile file, String content) {
+		this.fileContents.put(file, content);
+	}
+
+	public void clear() {
+		this.fileContents.clear();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileMoveParticipant.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileMoveParticipant.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileMoveParticipant.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,200 @@
+package org.drools.eclipse.refactoring;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IPackageDeclaration;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor;
+import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaMoveProcessor;
+import org.eclipse.jdt.internal.corext.refactoring.reorg.MoveModifications;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
+import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
+import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * Participant to generate refactoring when types are moved or a package is renamed
+ * 
+ * @author Lucas Amador
+ *
+ */
+ at SuppressWarnings("restriction")
+public class RuleIFileMoveParticipant extends MoveParticipant {
+
+	public static final String NAME = "Rule Move Refactoring";
+
+	private static RefactoringContent refactoringContent = new RefactoringContent();
+	private DRLProjectDetector drlProjectDetector = new DRLProjectDetector();
+	private Matcher matcher;
+
+	private IFile file;
+	private RefactoringProcessor processor;
+	private String newName;
+	private String currentName;
+
+	private String className;
+	
+	@Override
+	public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
+		RefactoringStatus status = new RefactoringStatus();
+		if (file==null || file.isReadOnly())
+			status.addFatalError("File don't exists or is read only");
+		return status;
+	}
+
+	@Override
+	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+		CompositeChange changes = new CompositeChange("Reorganize DRL " + currentName + "." + className + " imports ");
+		String content;
+		for (IFile drlFile : drlProjectDetector.detect(file.getProject())) {
+
+			content = refactoringContent.getIFileContent(drlFile);
+			if (content==null && (content = readFile(drlFile))==null)
+				continue;
+
+			String toReplace = currentName + "." + className;
+			String replaceWith = newName + "." + className;
+
+			Pattern pattern = Pattern.compile(toReplace);
+			matcher = pattern.matcher(content);
+
+			if (matcher.find()) {
+				TextFileChange change = new TextFileChange(drlFile.getName(), drlFile);
+				MultiTextEdit mte = new MultiTextEdit();
+				change.setEdit(mte);
+				ReplaceEdit replace = new ReplaceEdit(matcher.start(), toReplace.length(), replaceWith);
+				mte.addChild(replace);
+				changes.add(change);
+				refactoringContent.updateContent(drlFile, content.replace(toReplace, replaceWith));
+			}
+		}
+		return (changes.getChildren().length > 0)?changes:null;
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	protected boolean initialize(Object element) {
+		if (element instanceof IFile) {
+			IFile file = (IFile)element;
+			if (file.getType()==IFile.FILE) {
+				if (file.getFileExtension().equalsIgnoreCase("java")) {
+					this.processor = getProcessor();
+					this.file = file;
+					this.className = file.getName().replace("."+file.getFileExtension(), "");
+					if (processor.hashCode()!=refactoringContent.getProcessorHashcode()) {
+						refactoringContent.setProcessorHashcode(processor.hashCode());
+						refactoringContent.clear();
+					}
+					if (processor instanceof JavaRenameProcessor) {
+						newName = ((JavaRenameProcessor)processor).getNewElementName();
+						currentName = ((JavaRenameProcessor)processor).getCurrentElementName();
+						return true;
+					}
+					else if (processor instanceof JavaMoveProcessor) {
+						try {
+							MoveModifications moveModifications = getNewName();
+							getCurrentName(moveModifications);
+						} catch (SecurityException e) {
+							return false;
+						} catch (NoSuchFieldException e) {
+							return false;
+						} catch (IllegalArgumentException e) {
+							return false;
+						} catch (IllegalAccessException e) {
+							return false;
+						} catch (JavaModelException e) {
+							return false;
+						}
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	private String readFile(IFile file) throws CoreException {
+		InputStream inputStream = file.getContents();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+		StringBuilder sb = new StringBuilder();
+		String buffer = null;
+		try {
+			while ((buffer = reader.readLine()) != null)
+				sb.append(buffer + "\n");
+		}
+		catch (IOException e) {
+			return null;
+		}
+		finally {
+			try {
+				inputStream.close();
+			}
+			catch (IOException e) {
+				// Nothing
+			}
+		}
+		return sb.toString();
+	}
+
+	@SuppressWarnings("unchecked")
+	private MoveModifications getNewName() throws NoSuchFieldException, IllegalAccessException {
+		Field fMovePolicyPrivateField = processor.getClass().getDeclaredField("fMovePolicy");
+		fMovePolicyPrivateField.setAccessible(true);
+		Object movePolicy = fMovePolicyPrivateField.get(processor);
+
+		Field fModificationsPrivateField = movePolicy.getClass().getDeclaredField("fModifications");
+		fModificationsPrivateField.setAccessible(true);
+		MoveModifications moveModifications = (MoveModifications) fModificationsPrivateField.get(movePolicy);
+		Field fMoveArgumentsPrivateField = moveModifications.getClass().getDeclaredField("fMoveArguments");
+		fMoveArgumentsPrivateField.setAccessible(true);
+		ArrayList<MoveArguments> moveArguments = (ArrayList<MoveArguments>) fMoveArgumentsPrivateField.get(moveModifications);
+		PackageFragment packageFragment = (PackageFragment) moveArguments.get(0).getDestination();
+
+		String[] names = packageFragment.names;
+		String newPackageName = "";
+		for (int i = 0; i < names.length; i++)
+			newPackageName = newPackageName.concat(names[i]+".");
+
+		newName = newPackageName.substring(0, newPackageName.length()-1);
+		return moveModifications;
+	}
+
+	@SuppressWarnings("unchecked")
+	private void getCurrentName(MoveModifications moveModifications) throws NoSuchFieldException, IllegalAccessException, JavaModelException {
+		Field fMovesPrivateField = moveModifications.getClass().getDeclaredField("fMoves");
+		fMovesPrivateField.setAccessible(true);
+		ArrayList<Object> fmoves = (ArrayList<Object>) fMovesPrivateField.get(moveModifications);
+		for (Object fmove : fmoves) {
+			if (fmove instanceof CompilationUnit) {
+				CompilationUnit cu = (CompilationUnit)fmove;
+				IPackageDeclaration[] packageDeclarations = cu.getPackageDeclarations();
+				for (int i = 0; i < packageDeclarations.length; i++)
+					currentName = packageDeclarations[i].getElementName();
+			}
+		}
+	}
+
+}

Added: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileRenameParticipant.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileRenameParticipant.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleIFileRenameParticipant.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,131 @@
+package org.drools.eclipse.refactoring;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * Participant to generate refactoring when a type is renamed.
+ * 
+ * @author Lucas Amador
+ *
+ */
+ at SuppressWarnings("restriction")
+public class RuleIFileRenameParticipant extends RenameParticipant {
+
+	public static final String NAME = "Rule File Rename Refactoring";
+
+	private DRLProjectDetector drlProjectDetector = new DRLProjectDetector();
+	private Matcher matcher;
+
+	private RefactoringProcessor processor;
+	private List<IFile> drlFiles;
+	private IFile file;
+	private String newName;
+	private String currentName;
+
+	@Override
+	public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
+		RefactoringStatus status = new RefactoringStatus();
+		if (file==null || file.isReadOnly())
+			status.addFatalError("File don't exists or is read only");
+		return status;
+	}
+
+	@Override
+	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+		CompositeChange changes = null;
+		String content;
+		changes = new CompositeChange("Reorganize DRL " + currentName + " Type ");
+		drlFiles = drlProjectDetector.detect(file.getProject());
+		for (IFile drlFile : drlFiles) {
+
+			if ((content = readFile(drlFile))==null)
+				return null;
+
+			Pattern pattern = Pattern.compile("(?<=\\.|\\s)" + currentName + "(?=\\(|\\n|\\s)");
+			matcher = pattern.matcher(content);
+
+			TextFileChange change = new TextFileChange(drlFile.getName(), drlFile);
+			MultiTextEdit mte = new MultiTextEdit();
+			change.setEdit(mte);
+			while (matcher.find()) {
+				ReplaceEdit replace = new ReplaceEdit(matcher.start(), currentName.length(), newName);
+				mte.addChild(replace);
+			}
+			if (change.getEdit().getChildrenSize() > 0)
+				changes.add(change);
+		}
+		if (changes.getChildren().length==0)
+			return null;
+		return (changes.getChildren().length > 0)?changes:null;
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+
+	@Override
+	protected boolean initialize(Object element) {
+		if (element instanceof IFile) {
+			IFile file = (IFile)element;
+			if (file.getType()==IFile.FILE) {
+				if (file.getFileExtension().equalsIgnoreCase("java")) {
+					this.processor = getProcessor();
+					this.file = file;
+					if (this.processor instanceof JavaRenameProcessor) {
+						newName = ((JavaRenameProcessor)processor).getNewElementName().replace(".java", "");
+						currentName = ((JavaRenameProcessor)processor).getCurrentElementName();
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	private String readFile(IFile file) throws CoreException {
+		InputStream inputStream = file.getContents();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+		StringBuilder sb = new StringBuilder();
+		String buffer = null;
+		try {
+			while ((buffer = reader.readLine()) != null)
+				sb.append(buffer + "\n");
+		}
+		catch (IOException e) {
+			return null;
+		}
+		finally {
+			try {
+				inputStream.close();
+			}
+			catch (IOException e) {
+				// Nothing
+			}
+		}
+		return sb.toString();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleSourceFieldRenameParticipant.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleSourceFieldRenameParticipant.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/refactoring/RuleSourceFieldRenameParticipant.java	2009-08-17 00:35:57 UTC (rev 28954)
@@ -0,0 +1,219 @@
+package org.drools.eclipse.refactoring;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.core.SourceField;
+import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
+import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor;
+import org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * Participant to generate refactoring when a field is renamed.
+ * This isn't executed by the RefactoringProcessor when a field is refactored with
+ * the rename hotkey into the editor. Only is called when the Rename field dialog is used.
+ * 
+ * @author Lucas Amador
+ *
+ */
+ at SuppressWarnings("restriction")
+public class RuleSourceFieldRenameParticipant extends RenameParticipant {
+
+	public static final String NAME = "Rule Source Field Rename Refactoring";
+
+	private static final String FIELD_NAME = "(?<=:\\s)FIELD_NAME|FIELD_NAME(?=\\s=)";
+	private static final String VARIABLE_ASSIGNED = "[\\w]*(?=\\s*:\\s*TYPE\\s*\\()";
+	private static final String GETTER_NAME = "(?<=VARIABLE_NAME\\.)CURRENT_GETTER_NAME(?=\\s*\\()";
+	private static final String SETTER_NAME = "(?<=VARIABLE_NAME\\.)CURRENT_SETTER_NAME(?=\\s*\\()";
+
+	private DRLProjectDetector drlProjectDetector = new DRLProjectDetector();
+	private Matcher matcher;
+
+	private RefactoringProcessor processor;
+	private List<IFile> drlFiles;
+	private SourceField sourceField;
+	private String newName;
+	private String currentName;
+
+	@Override
+	public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
+		RefactoringStatus status = new RefactoringStatus();
+		try {
+			IFile file = getSourceFieldIFile();
+			if (file==null || file.isReadOnly())
+				return status;
+			drlFiles = drlProjectDetector.detect(file.getProject());
+			String content = null;
+			// if at least one file have a reference to the renamed field => apply refactoring
+			for (IFile drlFile : drlFiles) {
+
+				if ((content = readFile(drlFile))==null)
+					return null;
+
+				Pattern pattern = Pattern.compile("(?<=:\\s)" + currentName + "|" + currentName + "(?=\\s=)");
+				matcher = pattern.matcher(content);
+
+				if (matcher.find()) {
+					RenameFieldProcessor renameFieldProcessor = (RenameFieldProcessor)processor;
+					if (!renameFieldProcessor.getRenameGetter())
+						status.addInfo("The getter must be also updated to refactor the DRL files.");
+					return status;
+				}
+
+			}
+		} catch (CoreException e) {
+			throw new OperationCanceledException(e.getMessage());
+		}
+		return status;
+	}
+
+	@Override
+	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+		CompositeChange changes = null;
+		String content;
+		changes = new CompositeChange("Fix " + currentName + " field on DRL files");
+		IFile file = getSourceFieldIFile();
+		String typeName = sourceField.getParent().getElementName();
+		if (file!=null) {
+			RenameFieldProcessor renameFieldProcessor = (RenameFieldProcessor)processor;
+			for (IFile drlFile : drlFiles) {
+
+				if ((content = readFile(drlFile))==null)
+					return null;
+
+				TextFileChange change = new TextFileChange(drlFile.getName(), drlFile);
+				MultiTextEdit mte = new MultiTextEdit();
+				change.setEdit(mte);
+
+				// rename the field name
+				Pattern pattern = Pattern.compile(FIELD_NAME.replaceAll("FIELD_NAME", currentName));
+				matcher = pattern.matcher(content);
+				while (matcher.find()) {
+					ReplaceEdit replace = new ReplaceEdit(matcher.start(), currentName.length(), newName);
+					mte.addChild(replace);
+				}
+
+				// search all the variables of the type to replace the getters/setters
+				pattern = Pattern.compile(VARIABLE_ASSIGNED.replace("TYPE", typeName));
+				matcher = pattern.matcher(content);
+				while (matcher.find()) {
+					if (matcher.group().length() > 0) {
+						String variableNameAssigned = matcher.group();
+						if (renameFieldProcessor.getRenameGetter()) {
+							String newGetterName = renameFieldProcessor.getNewGetterName();
+							String currentGetterName = renameFieldProcessor.getGetter().getElementName();
+							String regexp = GETTER_NAME.replace("VARIABLE_NAME", variableNameAssigned).replace("CURRENT_GETTER_NAME", currentGetterName);
+							createFieldRenameChanges(mte, content, regexp, currentGetterName, newGetterName);
+						}
+						if (renameFieldProcessor.getRenameSetter()) {
+							String newSetterName = renameFieldProcessor.getNewSetterName();
+							String currentSetterName = renameFieldProcessor.getSetter().getElementName();
+							String regexp = SETTER_NAME.replace("VARIABLE_NAME", variableNameAssigned).replace("CURRENT_SETTER_NAME", currentSetterName);
+							createFieldRenameChanges(mte, content, regexp, currentSetterName, newSetterName);
+						}
+					}
+				}
+
+				if (change.getEdit().getChildrenSize() > 0)
+					changes.add(change);
+
+			}
+		}
+		return (changes.getChildren().length > 0)?changes:null;
+	}
+
+	private void createFieldRenameChanges(MultiTextEdit mte, String content, String regexp, String currentName, String newName) {
+		Pattern pattern = Pattern.compile(regexp);
+		Matcher setterMatcher = pattern.matcher(content);
+		ReplaceEdit replace = null;
+		while (setterMatcher.find()) {
+			replace = new ReplaceEdit(setterMatcher.start(), currentName.length(), newName);
+			mte.addChild(replace);
+		}
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	// TODO: Search the Native way to find the SourceField IFile
+	private IFile getSourceFieldIFile() {
+		Field fReferences;
+		try {
+			fReferences = processor.getClass().getDeclaredField("fReferences");
+			fReferences.setAccessible(true);
+			SearchResultGroup object[] = (SearchResultGroup[]) fReferences.get(processor);
+			for (SearchResultGroup searchResultGroup : object) {
+				if (searchResultGroup.getResource() instanceof IFile)
+					return (IFile) searchResultGroup.getResource();
+			}
+		} catch (SecurityException e) {
+			return null;
+		} catch (NoSuchFieldException e) {
+			return null;
+		} catch (IllegalArgumentException e) {
+			return null;
+		} catch (IllegalAccessException e) {
+			return null;
+		}
+		return null;
+	}
+
+	@Override
+	protected boolean initialize(Object element) {
+		if (element instanceof SourceField) {
+			this.sourceField = (SourceField) element;
+			this.processor = getProcessor();
+			if (this.processor instanceof JavaRenameProcessor) {
+				newName = ((JavaRenameProcessor)processor).getNewElementName();
+				currentName = ((JavaRenameProcessor)processor).getCurrentElementName();
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private String readFile(IFile file) throws CoreException {
+		InputStream inputStream = file.getContents();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+		StringBuilder sb = new StringBuilder();
+		String buffer = null;
+		try {
+			while ((buffer = reader.readLine()) != null)
+				sb.append(buffer + "\n");
+		}
+		catch (IOException e) {
+			return null;
+		}
+		finally {
+			try {
+				inputStream.close();
+			}
+			catch (IOException e) {
+				// Nothing
+			}
+		}
+		return sb.toString();
+	}
+
+}



More information about the jboss-svn-commits mailing list