001: package org.drools.eclipse.debug.core;
002:
003: import java.util.HashMap;
004: import java.util.Map;
005:
006: import org.drools.eclipse.DRLInfo;
007: import org.drools.eclipse.DroolsEclipsePlugin;
008: import org.drools.eclipse.DRLInfo.FunctionInfo;
009: import org.drools.eclipse.DRLInfo.RuleInfo;
010: import org.drools.rule.builder.dialect.mvel.MVELDialect;
011: import org.eclipse.core.resources.IMarker;
012: import org.eclipse.core.resources.IResource;
013: import org.eclipse.core.runtime.CoreException;
014: import org.eclipse.core.runtime.IStatus;
015: import org.eclipse.core.runtime.Status;
016: import org.eclipse.jdt.internal.debug.core.breakpoints.JavaLineBreakpoint;
017:
018: public class DroolsLineBreakpoint extends JavaLineBreakpoint {
019:
020: private static final String DIALECT = "org.drools.eclipse.debug.core.breakpointDialect";
021:
022: /**
023: * Default constructor is required for the breakpoint manager
024: * to re-create persisted breakpoints. After instantiating a breakpoint,
025: * the <code>setMarker(...)</code> method is called to restore
026: * this breakpoint's attributes.
027: */
028: public DroolsLineBreakpoint() {
029: super ();
030: }
031:
032: /**
033: * Constructs a line breakpoint on the given resource at the given
034: * line number.
035: *
036: * @param resource file on which to set the breakpoint
037: * @param lineNumber line number of the breakpoint
038: * @throws CoreException if unable to create the breakpoint
039: */
040: public DroolsLineBreakpoint(IResource resource, int lineNumber)
041: throws CoreException {
042: super (resource, "", -1, -1, -1, 0, true,
043: createAttributesMap(lineNumber),
044: IDroolsDebugConstants.DROOLS_MARKER_TYPE);
045: setJavaBreakpointProperties();
046: }
047:
048: private static Map createAttributesMap(int lineNumber) {
049: Map map = new HashMap();
050: map.put(IDroolsDebugConstants.DRL_LINE_NUMBER, new Integer(
051: lineNumber));
052: return map;
053: }
054:
055: public int getDRLLineNumber() {
056: return getMarker().getAttribute(
057: IDroolsDebugConstants.DRL_LINE_NUMBER, -1);
058: }
059:
060: public String getModelIdentifier() {
061: return IDroolsDebugConstants.ID_DROOLS_DEBUG_MODEL;
062: }
063:
064: public String getDialectName() {
065: return getMarker().getAttribute(DIALECT, "Unknown");
066: }
067:
068: public Map getFileRuleMappings() {
069: String packedInfo = getMarker().getAttribute(
070: IDroolsDebugConstants.DRL_RULES, "");
071: return unpackRuleMapping(packedInfo);
072: }
073:
074: public void setJavaBreakpointProperties() throws CoreException {
075: IMarker marker = getMarker();
076: int drlLineNumber = getDRLLineNumber();
077: if (marker.exists()) {
078: try {
079: DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
080: .parseResource(marker.getResource(), true);
081:
082: RuleInfo[] ruleInfos = drlInfo.getRuleInfos();
083:
084: StringBuffer rb = new StringBuffer();
085: for (int i = 0; i < ruleInfos.length; i++) {
086: int line = ruleInfos[i]
087: .getConsequenceDrlLineNumber();
088: String ruleid = ruleInfos[i].getClassName() + ":"
089: + line;
090: rb.append(ruleid);
091: if (i < ruleInfos.length - 1) {
092: rb.append(";");
093: }
094: }
095:
096: marker.setAttribute(IDroolsDebugConstants.DRL_RULES, rb
097: .toString());
098:
099: marker.setAttribute(TYPE_NAME, getRuleClassName(
100: drlInfo, marker.getResource().toString(),
101: drlLineNumber));
102: int ruleLineNumber = getRuleLineNumber(drlInfo, marker
103: .getResource().toString(), drlLineNumber);
104: marker
105: .setAttribute(IMarker.LINE_NUMBER,
106: ruleLineNumber);
107: marker.setAttribute(DIALECT, getDialect(drlInfo,
108: drlLineNumber));
109:
110: } catch (Throwable t) {
111: throw new CoreException(new Status(IStatus.ERROR,
112: DroolsEclipsePlugin.getUniqueIdentifier(), 0,
113: "Cannot determine ruleInfo "
114: + marker.getResource() + " "
115: + drlLineNumber, t));
116: }
117: }
118: }
119:
120: private String getDialect(DRLInfo info, int drlLineNumber) {
121: if (info != null) {
122: return info.getRuleInfo(drlLineNumber).getDialect().getId();
123: }
124: return null;
125: }
126:
127: private String getRuleClassName(DRLInfo drlInfo, String resource,
128: int lineNumber) throws CoreException {
129: if (drlInfo != null) {
130: RuleInfo ruleInfo = drlInfo.getRuleInfo(lineNumber);
131: if (ruleInfo != null) {
132: return ruleInfo.getClassName();
133: }
134: FunctionInfo functionInfo = drlInfo
135: .getFunctionInfo(lineNumber);
136: if (functionInfo != null) {
137: return functionInfo.getClassName();
138: }
139: }
140: throw new CoreException(new Status(IStatus.ERROR,
141: DroolsEclipsePlugin.getUniqueIdentifier(), 0,
142: "Cannot determine ruleClassName for " + resource + " "
143: + lineNumber, null));
144: }
145:
146: private int getRuleLineNumber(DRLInfo drlInfo, String resource,
147: int lineNumber) throws CoreException {
148: if (drlInfo != null) {
149: RuleInfo ruleInfo = drlInfo.getRuleInfo(lineNumber);
150: if (ruleInfo != null) {
151: if (ruleInfo.getConsequenceDrlLineNumber() < lineNumber) {
152:
153: int line = ruleInfo.getConsequenceJavaLineNumber()
154: + (lineNumber - ruleInfo
155: .getConsequenceDrlLineNumber());
156: if (ruleInfo.getDialect().getId().equals(
157: MVELDialect.ID)) {
158: return line;
159: }
160: return line + 1;
161: }
162: }
163: FunctionInfo functionInfo = drlInfo
164: .getFunctionInfo(lineNumber);
165: if (functionInfo != null) {
166: return functionInfo.getJavaLineNumber()
167: + (lineNumber - functionInfo.getDrlLineNumber());
168: }
169: }
170: throw new CoreException(new Status(IStatus.ERROR,
171: DroolsEclipsePlugin.getUniqueIdentifier(), 0,
172: "Cannot determine ruleLineNumber for " + resource + " "
173: + lineNumber, null));
174: }
175:
176: public String getRuleName() {
177: IMarker marker = getMarker();
178: if (marker.exists()) {
179: try {
180: return (String) marker.getAttribute(TYPE_NAME);
181: } catch (CoreException e) {
182: DroolsEclipsePlugin.log(e);
183: }
184: }
185: return null;
186: }
187:
188: private final static Map unpackRuleMapping(String input) {
189: Map map = new HashMap();
190: String[] rules = input.split("\\;");
191: for (int i = 0; i < rules.length; i++) {
192: if (rules[i].length() > 0) {
193: String[] inf = rules[i].split("\\:");
194: map.put(inf[0], Integer.valueOf(inf[1]));
195: }
196: }
197: return map;
198: }
199:
200: }
|