001: package org.drools.eclipse.editors;
002:
003: import java.util.ArrayList;
004: import java.util.HashMap;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Map;
008: import java.util.Set;
009:
010: import org.drools.compiler.DroolsParserException;
011: import org.drools.eclipse.DRLInfo;
012: import org.drools.eclipse.DroolsEclipsePlugin;
013: import org.drools.eclipse.debug.core.IDroolsDebugConstants;
014: import org.drools.lang.descr.AttributeDescr;
015: import org.drools.lang.descr.BaseDescr;
016: import org.drools.lang.descr.FactTemplateDescr;
017: import org.drools.lang.descr.FunctionDescr;
018: import org.drools.lang.descr.FunctionImportDescr;
019: import org.drools.lang.descr.GlobalDescr;
020: import org.drools.lang.descr.ImportDescr;
021: import org.drools.lang.descr.PackageDescr;
022: import org.eclipse.core.resources.IMarker;
023: import org.eclipse.core.resources.IProject;
024: import org.eclipse.core.runtime.CoreException;
025: import org.eclipse.core.runtime.IProgressMonitor;
026: import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
027: import org.eclipse.jdt.core.CompletionRequestor;
028: import org.eclipse.jdt.core.IJavaProject;
029: import org.eclipse.jdt.core.JavaCore;
030: import org.eclipse.jface.text.BadLocationException;
031: import org.eclipse.jface.text.IDocument;
032: import org.eclipse.ui.IEditorInput;
033: import org.eclipse.ui.IFileEditorInput;
034:
035: /**
036: * Generic rule editor for drools.
037: * @author Michael Neale
038: */
039: public class DRLRuleEditor extends AbstractRuleEditor {
040:
041: protected List imports;
042: protected List functions;
043: protected Map templates;
044: protected List globals;
045: protected String packageName;
046: protected List classesInPackage;
047: protected Map attributes;
048:
049: public DRLRuleEditor() {
050: }
051:
052: public List getImports() {
053: if (imports == null || isDirty()) {
054: loadImportsAndFunctions();
055: }
056: return imports;
057: }
058:
059: public List getFunctions() {
060: if (functions == null) {
061: loadImportsAndFunctions();
062: }
063: return functions;
064: }
065:
066: public Set getTemplates() {
067: if (templates == null) {
068: loadImportsAndFunctions();
069: }
070: return templates.keySet();
071: }
072:
073: public Map getAttributes() {
074: if (attributes == null) {
075: loadImportsAndFunctions();
076: }
077: return attributes;
078: }
079:
080: public FactTemplateDescr getTemplate(String name) {
081: if (templates == null) {
082: loadImportsAndFunctions();
083: }
084: return (FactTemplateDescr) templates.get(name);
085: }
086:
087: public List getGlobals() {
088: if (globals == null) {
089: loadImportsAndFunctions();
090: }
091: return globals;
092: }
093:
094: public String getPackage() {
095: if (packageName == null) {
096: loadImportsAndFunctions();
097: }
098: return packageName;
099: }
100:
101: public List getClassesInPackage() {
102: if (classesInPackage == null) {
103: classesInPackage = getAllClassesInPackage(getPackage());
104: }
105: return classesInPackage;
106: }
107:
108: protected List getAllClassesInPackage(String packageName) {
109: List list = new ArrayList();
110: if (packageName != null) {
111: IEditorInput input = getEditorInput();
112: if (input instanceof IFileEditorInput) {
113: IProject project = ((IFileEditorInput) input).getFile()
114: .getProject();
115: IJavaProject javaProject = JavaCore.create(project);
116: list = getAllClassesInPackage(packageName, javaProject);
117: }
118: }
119: return list;
120: }
121:
122: public static List getAllClassesInPackage(String packageName,
123: IJavaProject javaProject) {
124: final List list = new ArrayList();
125: CompletionRequestor requestor = new CompletionRequestor() {
126: public void accept(
127: org.eclipse.jdt.core.CompletionProposal proposal) {
128: String className = new String(proposal.getCompletion());
129: if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.TYPE_REF) {
130: list.add(className);
131: }
132: // ignore all other proposals
133: }
134: };
135:
136: try {
137: javaProject.newEvaluationContext().codeComplete(
138: packageName + ".", packageName.length() + 1,
139: requestor);
140: } catch (Throwable t) {
141: DroolsEclipsePlugin.log(t);
142: }
143: return list;
144: }
145:
146: protected List getAllStaticMethodsInClass(String className) {
147: final List list = new ArrayList();
148: if (className != null) {
149: IEditorInput input = getEditorInput();
150: if (input instanceof IFileEditorInput) {
151: IProject project = ((IFileEditorInput) input).getFile()
152: .getProject();
153: IJavaProject javaProject = JavaCore.create(project);
154:
155: CompletionRequestor requestor = new CompletionRequestor() {
156: public void accept(
157: org.eclipse.jdt.core.CompletionProposal proposal) {
158: String functionName = new String(proposal
159: .getCompletion());
160: if (proposal.getKind() == org.eclipse.jdt.core.CompletionProposal.METHOD_REF) {
161: list.add(functionName.substring(0,
162: functionName.length() - 2)); // remove the ()
163: }
164: // ignore all other proposals
165: }
166: };
167:
168: try {
169: javaProject.newEvaluationContext().codeComplete(
170: className + ".", className.length() + 1,
171: requestor);
172: } catch (Throwable t) {
173: DroolsEclipsePlugin.log(t);
174: }
175: }
176: }
177: return list;
178: }
179:
180: protected void loadImportsAndFunctions() {
181: try {
182: DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
183: .parseResource(this , true, false);
184: PackageDescr descr = drlInfo.getPackageDescr();
185: // package
186: this .packageName = drlInfo.getPackageName();
187: // imports
188: List allImports = descr.getImports();
189: this .imports = new ArrayList();
190: if (packageName != null) {
191: imports.addAll(getAllClassesInPackage(packageName));
192: }
193: Iterator iterator = allImports.iterator();
194: while (iterator.hasNext()) {
195: String importName = ((ImportDescr) iterator.next())
196: .getTarget();
197: if (importName.endsWith(".*")) {
198: String packageName = importName.substring(0,
199: importName.length() - 2);
200: imports.addAll(getAllClassesInPackage(packageName));
201: } else {
202: imports.add(importName);
203: }
204: }
205: // functions
206: List functionDescrs = descr.getFunctions();
207: List functionImports = descr.getFunctionImports();
208: functions = new ArrayList(functionDescrs.size());
209: iterator = functionDescrs.iterator();
210: while (iterator.hasNext()) {
211: functions.add(((FunctionDescr) iterator.next())
212: .getName());
213: }
214: iterator = functionImports.iterator();
215: while (iterator.hasNext()) {
216: String functionImport = ((FunctionImportDescr) iterator
217: .next()).getTarget();
218: if (functionImport.endsWith(".*")) {
219: String className = functionImport.substring(0,
220: functionImport.length() - 2);
221: functions
222: .addAll(getAllStaticMethodsInClass(className));
223: } else {
224: int index = functionImport.lastIndexOf('.');
225: if (index != -1) {
226: functions.add(functionImport
227: .substring(index + 1));
228: }
229: }
230: }
231: // templates
232: List templateDescrs = descr.getFactTemplates();
233: templates = new HashMap(templateDescrs.size());
234: iterator = templateDescrs.iterator();
235: while (iterator.hasNext()) {
236: FactTemplateDescr template = (FactTemplateDescr) iterator
237: .next();
238: templates.put(template.getName(), template);
239: }
240: // globals
241: List globalDescrs = descr.getGlobals();
242: globals = new ArrayList();
243: iterator = globalDescrs.iterator();
244: while (iterator.hasNext()) {
245: GlobalDescr global = (GlobalDescr) iterator.next();
246: globals.add(global);
247: }
248:
249: //attributes
250: this .attributes = new HashMap();
251: for (Iterator attrIter = descr.getAttributes().iterator(); attrIter
252: .hasNext();) {
253: AttributeDescr attribute = (AttributeDescr) attrIter
254: .next();
255: if (attribute != null && attribute.getName() != null) {
256: attributes.put(attribute.getName(), attribute
257: .getValue());
258: }
259: }
260:
261: } catch (DroolsParserException e) {
262: DroolsEclipsePlugin.log(e);
263: }
264: }
265:
266: public Object getAdapter(Class adapter) {
267: if (adapter.equals(IToggleBreakpointsTarget.class)) {
268: return getBreakpointAdapter();
269: }
270: return super .getAdapter(adapter);
271: }
272:
273: private Object getBreakpointAdapter() {
274: return new DroolsLineBreakpointAdapter();
275: }
276:
277: public void doSave(IProgressMonitor monitor) {
278: super .doSave(monitor);
279: // remove cached content
280: imports = null;
281: functions = null;
282: templates = null;
283: globals = null;
284: packageName = null;
285: classesInPackage = null;
286: }
287:
288: public void gotoMarker(IMarker marker) {
289: try {
290: if (marker.getType().equals(
291: IDroolsDebugConstants.DROOLS_MARKER_TYPE)) {
292: int line = marker.getAttribute(
293: IDroolsDebugConstants.DRL_LINE_NUMBER, -1);
294: if (line > -1)
295: --line;
296: try {
297: IDocument document = getDocumentProvider()
298: .getDocument(getEditorInput());
299: selectAndReveal(document.getLineOffset(line),
300: document.getLineLength(line));
301: } catch (BadLocationException exc) {
302: DroolsEclipsePlugin.log(exc);
303: }
304: } else {
305: super .gotoMarker(marker);
306: }
307: } catch (CoreException exc) {
308: DroolsEclipsePlugin.log(exc);
309: }
310: }
311:
312: public BaseDescr getDescr(int offset) {
313: try {
314: DRLInfo info = DroolsEclipsePlugin.getDefault()
315: .parseResource(this , true, false);
316: return DescrUtil.getDescr(info.getPackageDescr(), offset);
317: } catch (DroolsParserException exc) {
318: return null;
319: }
320: }
321: }
|