001: package org.drools.eclipse.editors.outline;
002:
003: import java.util.HashMap;
004: import java.util.Iterator;
005: import java.util.Map;
006: import java.util.regex.Matcher;
007: import java.util.regex.Pattern;
008:
009: import org.drools.compiler.DroolsParserException;
010: import org.drools.eclipse.DRLInfo;
011: import org.drools.eclipse.DroolsEclipsePlugin;
012: import org.drools.eclipse.core.DroolsElement;
013: import org.drools.eclipse.core.DroolsModelBuilder;
014: import org.drools.eclipse.core.Package;
015: import org.drools.eclipse.core.RuleSet;
016: import org.drools.eclipse.core.ui.DroolsContentProvider;
017: import org.drools.eclipse.core.ui.DroolsLabelProvider;
018: import org.drools.eclipse.core.ui.DroolsTreeSorter;
019: import org.drools.eclipse.core.ui.FilterActionGroup;
020: import org.drools.eclipse.editors.AbstractRuleEditor;
021: import org.drools.lang.descr.AttributeDescr;
022: import org.drools.lang.descr.PackageDescr;
023: import org.drools.lang.descr.RuleDescr;
024: import org.eclipse.jface.viewers.ISelectionChangedListener;
025: import org.eclipse.jface.viewers.SelectionChangedEvent;
026: import org.eclipse.jface.viewers.StructuredSelection;
027: import org.eclipse.jface.viewers.TreeViewer;
028: import org.eclipse.swt.widgets.Composite;
029: import org.eclipse.swt.widgets.Control;
030: import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
031:
032: /**
033: * Simple outline view of a DRL file. At present this is not wired in with the Parser, so it is fault
034: * tolerant of incorrect syntax.
035: * Should provide navigation assistance in large rule files.
036: *
037: * @author "Jeff Brown" <brown_j@ociweb.com>
038: * @author <a href="mailto:kris_verlaenen@hotmail.com">kris verlaenen </a>
039: */
040: public class RuleContentOutlinePage extends ContentOutlinePage {
041:
042: private AbstractRuleEditor editor;
043: private RuleSet ruleSet = DroolsModelBuilder.createRuleSet();
044: private Map rules;
045:
046: ///////////////////////////////////
047: // Patterns that the parser uses
048: ///////////////////////////////////
049: private static final Pattern RULE_PATTERN1 = Pattern.compile(
050: "\\n\\s*rule\\s+\"([^\"]+)\"", Pattern.DOTALL);
051:
052: private static final Pattern RULE_PATTERN2 = Pattern.compile(
053: "\\n\\s*rule\\s+([^\\s;#\"]+)", Pattern.DOTALL);
054:
055: private static final Pattern PACKAGE_PATTERN = Pattern.compile(
056: "\\s*package\\s+([^\\s;#]+);?", Pattern.DOTALL);
057:
058: private static final Pattern FUNCTION_PATTERN = Pattern.compile(
059: "\\n\\s*function\\s+(\\S+)\\s+(\\S+)\\(.*\\)",
060: Pattern.DOTALL);
061:
062: private static final Pattern TEMPLATE_PATTERN = Pattern.compile(
063: "\\n\\s*template\\s+([^\\s;#\"]+)", Pattern.DOTALL);
064:
065: private static final Pattern IMPORT_PATTERN = Pattern.compile(
066: "\\n\\s*import\\s+([^\\s;#]+);?", Pattern.DOTALL);
067:
068: private static final Pattern EXPANDER_PATTERN = Pattern.compile(
069: "\\n\\s*expander\\s+([^\\s;#]+);?", Pattern.DOTALL);
070:
071: private static final Pattern GLOBAL_PATTERN = Pattern.compile(
072: "\\n\\s*global\\s+(\\S+)\\s+([^\\s;#]+);?", Pattern.DOTALL);
073:
074: private static final Pattern QUERY_PATTERN1 = Pattern.compile(
075: "\\n\\s*query\\s+\"([^\"]+)\"", Pattern.DOTALL);
076:
077: private static final Pattern QUERY_PATTERN2 = Pattern.compile(
078: "\\n\\s*query\\s+([^\\s;#\"]+)", Pattern.DOTALL);
079:
080: public RuleContentOutlinePage(AbstractRuleEditor editor) {
081: this .editor = editor;
082: }
083:
084: public void createControl(Composite parent) {
085: super .createControl(parent);
086: TreeViewer viewer = getTreeViewer();
087: viewer.setContentProvider(new DroolsContentProvider());
088: viewer.setLabelProvider(new DroolsLabelProvider());
089: viewer.setSorter(new DroolsTreeSorter());
090: viewer.setInput(ruleSet);
091: FilterActionGroup filterActionGroup = new FilterActionGroup(
092: viewer,
093: "org.drools.eclipse.editors.outline.RuleContentOutlinePage");
094: filterActionGroup.fillActionBars(getSite().getActionBars());
095: update();
096:
097: // add the listener for navigation of the rule document.
098: super
099: .addSelectionChangedListener(new ISelectionChangedListener() {
100: public void selectionChanged(
101: SelectionChangedEvent event) {
102: Object selectionObj = event.getSelection();
103: if (selectionObj != null
104: && selectionObj instanceof StructuredSelection) {
105: StructuredSelection sel = (StructuredSelection) selectionObj;
106: DroolsElement element = (DroolsElement) sel
107: .getFirstElement();
108: if (element != null) {
109: editor.selectAndReveal(element
110: .getOffset(), element
111: .getLength());
112: }
113: }
114: }
115: });
116: }
117:
118: /**
119: * Updates the outline page.
120: */
121: public void update() {
122: TreeViewer viewer = getTreeViewer();
123: if (viewer != null) {
124: Control control = viewer.getControl();
125: if (control != null && !control.isDisposed()) {
126: initRules();
127: populatePackageTreeNode();
128: viewer.refresh();
129: control.setRedraw(false);
130: viewer.expandToLevel(2);
131: control.setRedraw(true);
132: }
133: }
134: }
135:
136: /**
137: * populates the PackageTreeNode with all of its child elements
138: *
139: * @param packageTreeNode the node to populate
140: */
141: public void populatePackageTreeNode() {
142: String ruleFileContents = editor.getContent();
143: populatePackageTreeNode(ruleFileContents);
144: }
145:
146: void populatePackageTreeNode(String ruleFileContents) {
147: DroolsModelBuilder.clearRuleSet(ruleSet);
148: Matcher matcher = PACKAGE_PATTERN.matcher(ruleFileContents);
149: String packageName = null;
150: int startChar = 0;
151: int endChar = 0;
152: if (matcher.find()) {
153: packageName = matcher.group(1);
154: startChar = matcher.start(1);
155: endChar = matcher.end(1);
156: }
157: Package pkg = DroolsModelBuilder.addPackage(ruleSet,
158: packageName, startChar, endChar - startChar);
159:
160: matcher = RULE_PATTERN1.matcher(ruleFileContents);
161: while (matcher.find()) {
162: String ruleName = matcher.group(1);
163: DroolsModelBuilder.addRule(pkg, ruleName, null, matcher
164: .start(1), matcher.end(1) - matcher.start(1),
165: extractAttributes((RuleDescr) rules.get(ruleName)));
166: }
167: matcher = RULE_PATTERN2.matcher(ruleFileContents);
168: while (matcher.find()) {
169: String ruleName = matcher.group(1);
170: DroolsModelBuilder.addRule(pkg, ruleName, null, matcher
171: .start(1), matcher.end(1) - matcher.start(1),
172: extractAttributes((RuleDescr) rules.get(ruleName)));
173: }
174: matcher = FUNCTION_PATTERN.matcher(ruleFileContents);
175: while (matcher.find()) {
176: String functionName = matcher.group(2);
177: DroolsModelBuilder.addFunction(pkg, functionName + "()",
178: null, matcher.start(2), matcher.end(2)
179: - matcher.start(2));
180: }
181: matcher = EXPANDER_PATTERN.matcher(ruleFileContents);
182: if (matcher.find()) {
183: String expanderName = matcher.group(1);
184: DroolsModelBuilder
185: .addExpander(pkg, expanderName, null, matcher
186: .start(1), matcher.end(1)
187: - matcher.start(1));
188: }
189: matcher = IMPORT_PATTERN.matcher(ruleFileContents);
190: while (matcher.find()) {
191: String importName = matcher.group(1);
192: DroolsModelBuilder.addImport(pkg, importName, null, matcher
193: .start(1), matcher.end(1) - matcher.start(1));
194: }
195: matcher = GLOBAL_PATTERN.matcher(ruleFileContents);
196: while (matcher.find()) {
197: String globalType = matcher.group(1);
198: String globalName = matcher.group(2);
199: String name = globalName + " : " + globalType;
200: DroolsModelBuilder.addGlobal(pkg, name, null, matcher
201: .start(2), matcher.end(2) - matcher.start(2));
202: }
203: matcher = QUERY_PATTERN1.matcher(ruleFileContents);
204: while (matcher.find()) {
205: String queryName = matcher.group(1);
206: DroolsModelBuilder.addQuery(pkg, queryName, null, matcher
207: .start(1), matcher.end(1) - matcher.start(1));
208: }
209: matcher = QUERY_PATTERN2.matcher(ruleFileContents);
210: while (matcher.find()) {
211: String queryName = matcher.group(1);
212: DroolsModelBuilder.addQuery(pkg, queryName, null, matcher
213: .start(1), matcher.end(1) - matcher.start(1));
214: }
215: matcher = TEMPLATE_PATTERN.matcher(ruleFileContents);
216: while (matcher.find()) {
217: String templateName = matcher.group(1);
218: DroolsModelBuilder
219: .addTemplate(pkg, templateName, null, matcher
220: .start(1), matcher.end(1)
221: - matcher.start(1));
222: }
223: }
224:
225: RuleSet getRuleSet() {
226: return ruleSet;
227: }
228:
229: private Map extractAttributes(RuleDescr ruleDescr) {
230: Map attributes = null;
231: if (ruleDescr != null) {
232: attributes = new HashMap();
233: for (Iterator iterator = ruleDescr.getAttributes()
234: .iterator(); iterator.hasNext();) {
235: AttributeDescr attribute = (AttributeDescr) iterator
236: .next();
237: if (attribute != null && attribute.getName() != null) {
238: attributes.put(attribute.getName(), attribute
239: .getValue());
240: }
241: }
242: }
243: return attributes;
244: }
245:
246: public void initRules() {
247: rules = new HashMap();
248: try {
249: DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
250: .parseResource(editor, true, false);
251: if (drlInfo != null) {
252: PackageDescr packageDescr = drlInfo.getPackageDescr();
253: for (Iterator iterator = packageDescr.getRules()
254: .iterator(); iterator.hasNext();) {
255: RuleDescr ruleDescr = (RuleDescr) iterator.next();
256: rules.put(ruleDescr.getName(), ruleDescr);
257: }
258: }
259: } catch (DroolsParserException e) {
260: DroolsEclipsePlugin.log(e);
261: }
262: }
263:
264: }
|