/*
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.eclipse.debug;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.drools.core.audit.WorkingMemoryLog;
import org.drools.core.audit.event.ActivationLogEvent;
import org.drools.core.audit.event.LogEvent;
import org.drools.core.audit.event.ObjectLogEvent;
import org.drools.core.audit.event.RuleBaseLogEvent;
import org.drools.core.audit.event.RuleFlowGroupLogEvent;
import org.drools.core.audit.event.RuleFlowLogEvent;
import org.drools.core.audit.event.RuleFlowNodeLogEvent;
import org.drools.eclipse.DroolsEclipsePlugin;
import org.drools.eclipse.DroolsPluginImages;
import org.drools.eclipse.debug.actions.DeleteLogAction;
import org.drools.eclipse.debug.actions.FileAuditDropAdapter;
import org.drools.eclipse.debug.actions.OpenLogAction;
import org.drools.eclipse.debug.actions.RefreshLogAction;
import org.drools.eclipse.debug.actions.ShowEventCauseAction;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.StreamException;
public class AuditView extends AbstractDebugView {
private static final String LOG_FILE_NAME = "LogFileName";
private static final String CAUSE_EVENT_COLOR = "CauseEventColor";
private String logFileName;
private IAction deleteAction;
private IAction refreshAction;
private boolean drools4 = false;
protected Viewer createViewer(Composite parent) {
final TreeViewer variablesViewer = new TreeViewer(parent);
variablesViewer.setContentProvider(new AuditViewContentProvider());
variablesViewer.setLabelProvider(new AuditLabelProvider());
variablesViewer.setUseHashlookup(true);
variablesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
getViewer().refresh();
}
});
int ops = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] transfers = new Transfer[] { FileTransfer.getInstance()};
variablesViewer.addDropSupport(ops, transfers, new FileAuditDropAdapter(variablesViewer,this));
return variablesViewer;
}
public void setLogFile(String logFileName) {
this.logFileName = logFileName;
refresh();
deleteAction.setEnabled(logFileName != null);
refreshAction.setEnabled(logFileName != null);
}
@SuppressWarnings("unchecked")
public void refresh() {
drools4 = false;
boolean phreak = false;
if (logFileName == null) {
getViewer().setInput(null);
return;
}
List<LogEvent> eventList = new ArrayList<LogEvent>();
try {
XStream xstream = new XStream();
ObjectInputStream in = xstream.createObjectInputStream( new FileReader(logFileName) );
try {
while (true) {
Object object = in.readObject();
if (object instanceof WorkingMemoryLog) {
WorkingMemoryLog log = (WorkingMemoryLog) object;
eventList = log.getEvents();
phreak = log.getEngine().equalsIgnoreCase("PHREAK");
break;
}
if (object instanceof LogEvent) {
eventList.add((LogEvent) object);
} else if (object instanceof List) {
drools4 = true;
eventList.addAll((List<LogEvent>) object);
} else {
throw new IllegalArgumentException("Unexpected element in log: " + object);
}
}
} catch (StreamException e) {
if (!(e.getCause() instanceof EOFException)) {
throw e;
}
} catch (EOFException e) {
// do nothing
}
} catch (FileNotFoundException e) {
setLogFile(null);
} catch (Throwable t) {
DroolsEclipsePlugin.log(t);
}
if (phreak) {
getViewer().setInput(createPhreakEventList(eventList));
} else if (drools4) {
getViewer().setInput(createDrools4EventList(eventList));
} else {
getViewer().setInput(createEventList(eventList));
}
// TODO: this is necessary because otherwise, the show cause action
// cannot find the cause event if it hasn't been shown yet
((TreeViewer) getViewer()).expandAll();
}
protected List<Event> createPhreakEventList(List<LogEvent> logEvents) {
Map<Long, Event> objectMap = new HashMap<Long, Event>();
Map<String, Event> activationMap = new HashMap<String, Event>();
Stack<Event> beforeEvents = new Stack<Event>();
List<Event> events = new ArrayList<Event>();
for (LogEvent logEvent : logEvents) {
Event event = new Event(logEvent.getType());
switch (logEvent.getType()) {
case LogEvent.INSERTED:
ObjectLogEvent objectEvent = (ObjectLogEvent) logEvent;
event.setString("Object inserted (" + objectEvent.getFactId() + "): " + objectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
objectMap.put( objectEvent.getFactId(), event );
break;
case LogEvent.UPDATED:
objectEvent = (ObjectLogEvent) logEvent;
event.setString("Object updated (" + objectEvent.getFactId() + "): " + objectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
objectMap.put( objectEvent.getFactId(), event );
break;
case LogEvent.RETRACTED:
objectEvent = (ObjectLogEvent) logEvent;
event.setString("Object removed (" + objectEvent.getFactId() + "): " + objectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
objectMap.put( objectEvent.getFactId(), event );
break;
case LogEvent.ACTIVATION_CREATED:
ActivationLogEvent activationEvent = (ActivationLogEvent) logEvent;
event.setString("Activation created: Rule " + activationEvent.getRule() + " " + activationEvent.getDeclarations());
Event mostRecentObjEvent = null;
for (Long fhId : getEventFactHandleIds(activationEvent)) {
Event objEvent = objectMap.get(fhId);
if (objEvent != null && (mostRecentObjEvent == null || mostRecentObjEvent.recency < objEvent.recency)) {
mostRecentObjEvent = objEvent;
}
}
if (mostRecentObjEvent != null) {
mostRecentObjEvent.addSubEvent(event);
}
activationMap.put(activationEvent.getActivationId(), event);
break;
case LogEvent.ACTIVATION_CANCELLED:
activationEvent = (ActivationLogEvent) logEvent;
event.setString("Activation cancelled: Rule " + activationEvent.getRule() + " " + activationEvent.getDeclarations());
mostRecentObjEvent = null;
for (Long fhId : getEventFactHandleIds(activationEvent)) {
Event objEvent = objectMap.get(fhId);
if (objEvent != null && (mostRecentObjEvent == null || mostRecentObjEvent.recency < objEvent.recency)) {
mostRecentObjEvent = objEvent;
}
}
if (mostRecentObjEvent != null) {
mostRecentObjEvent.addSubEvent(event);
}
event.setCauseEvent(activationMap.get(activationEvent.getActivationId()));
break;
case LogEvent.BEFORE_ACTIVATION_FIRE:
activationEvent = (ActivationLogEvent) logEvent;
event.setString("Activation executed: Rule " + activationEvent.getRule() + " " + activationEvent.getDeclarations());
events.add(event);
beforeEvents.push(event);
event.setCauseEvent(activationMap.get(activationEvent.getActivationId()));
break;
case LogEvent.AFTER_ACTIVATION_FIRE:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_CREATED:
RuleFlowLogEvent ruleFlowEvent = (RuleFlowLogEvent) logEvent;
event.setString("Process started: " + ruleFlowEvent.getProcessName() + "[" + ruleFlowEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_CREATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_COMPLETED:
ruleFlowEvent = (RuleFlowLogEvent) logEvent;
event.setString("Process completed: " + ruleFlowEvent.getProcessName() + "[" + ruleFlowEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_COMPLETED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_NODE_TRIGGERED:
RuleFlowNodeLogEvent ruleFlowNodeEvent = (RuleFlowNodeLogEvent) logEvent;
event.setString("Process node triggered: " + ruleFlowNodeEvent.getNodeName() + " in process " + ruleFlowNodeEvent.getProcessName() + "[" + ruleFlowNodeEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_NODE_TRIGGERED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_GROUP_ACTIVATED:
RuleFlowGroupLogEvent ruleFlowGroupEvent = (RuleFlowGroupLogEvent) logEvent;
event.setString("RuleFlow Group activated: " + ruleFlowGroupEvent.getGroupName() + "[size=" + ruleFlowGroupEvent.getSize() + "]");
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_GROUP_ACTIVATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_GROUP_DEACTIVATED:
ruleFlowGroupEvent = (RuleFlowGroupLogEvent) logEvent;
event.setString("RuleFlow Group deactivated: " + ruleFlowGroupEvent.getGroupName() + "[size=" + ruleFlowGroupEvent.getSize() + "]");
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_GROUP_DEACTIVATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_PACKAGE_ADDED:
RuleBaseLogEvent ruleBaseEvent = (RuleBaseLogEvent) logEvent;
event.setString("Package added: " + ruleBaseEvent.getPackageName());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_PACKAGE_ADDED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_PACKAGE_REMOVED:
ruleBaseEvent = (RuleBaseLogEvent) logEvent;
event.setString("Package removed: " + ruleBaseEvent.getPackageName());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_PACKAGE_REMOVED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULE_ADDED:
ruleBaseEvent = (RuleBaseLogEvent) logEvent;
event.setString("Rule added: " + ruleBaseEvent.getRuleName());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULE_ADDED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULE_REMOVED:
ruleBaseEvent = (RuleBaseLogEvent) logEvent;
event.setString("Rule removed: " + ruleBaseEvent.getRuleName());
if (!beforeEvents.isEmpty()) {
beforeEvents.peek().addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULE_REMOVED:
beforeEvents.pop();
break;
default:
// do nothing
break;
}
}
return events;
}
private Long[] getEventFactHandleIds(ActivationLogEvent event) {
String[] ids = event.getFactHandleIds().split(",");
Long[] longIds = new Long[ids.length];
for (int i = 0; i < ids.length; i++) {
longIds[i] = Long.parseLong(ids[i]);
}
return longIds;
}
protected List<Event> createEventList(List<LogEvent> logEvents) {
Iterator<LogEvent> iterator = logEvents.iterator();
List<Event> events = new ArrayList<Event>();
Stack<Event> beforeEvents = new Stack<Event>();
List<Event> newActivations = new ArrayList<Event>();
Map<String, Event> activationMap = new HashMap<String, Event>();
Map<Long, Event> objectMap = new HashMap<Long, Event>();
while (iterator.hasNext()) {
LogEvent inEvent = (LogEvent) iterator.next();
Event event = new Event(inEvent.getType());
switch (inEvent.getType()) {
case LogEvent.INSERTED:
ObjectLogEvent inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object inserted (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
objectMap.put(new Long(((ObjectLogEvent) inEvent).getFactId()), event);
break;
case LogEvent.UPDATED:
inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object updated (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
Event assertEvent = (Event) objectMap.get(new Long(((ObjectLogEvent) inEvent).getFactId()));
if (assertEvent != null) {
event.setCauseEvent(assertEvent);
}
break;
case LogEvent.RETRACTED:
inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object removed (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
assertEvent = (Event) objectMap.get(new Long(((ObjectLogEvent) inEvent).getFactId()));
if (assertEvent != null) {
event.setCauseEvent(assertEvent);
}
break;
case LogEvent.ACTIVATION_CREATED:
ActivationLogEvent inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation created: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
newActivations.add(event);
activationMap.put(((ActivationLogEvent) inEvent).getActivationId(), event);
break;
case LogEvent.ACTIVATION_CANCELLED:
inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation cancelled: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
newActivations.add(event);
event.setCauseEvent((Event) activationMap.get(((ActivationLogEvent) inEvent).getActivationId()));
break;
case LogEvent.BEFORE_ACTIVATION_FIRE:
inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation executed: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
events.add(event);
beforeEvents.push(event);
event.setCauseEvent((Event) activationMap.get(((ActivationLogEvent) inEvent).getActivationId()));
break;
case LogEvent.AFTER_ACTIVATION_FIRE:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_CREATED:
RuleFlowLogEvent inRuleFlowEvent = (RuleFlowLogEvent) inEvent;
event.setString("Process started: " + inRuleFlowEvent.getProcessName() + "[" + inRuleFlowEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_CREATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_COMPLETED:
inRuleFlowEvent = (RuleFlowLogEvent) inEvent;
event.setString("Process completed: " + inRuleFlowEvent.getProcessName() + "[" + inRuleFlowEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_COMPLETED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_NODE_TRIGGERED:
RuleFlowNodeLogEvent inRuleFlowNodeEvent = (RuleFlowNodeLogEvent) inEvent;
event.setString("Process node triggered: " + inRuleFlowNodeEvent.getNodeName() + " in process " + inRuleFlowNodeEvent.getProcessName() + "[" + inRuleFlowNodeEvent.getProcessId() + "]");
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_NODE_TRIGGERED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_GROUP_ACTIVATED:
RuleFlowGroupLogEvent inRuleFlowGroupEvent = (RuleFlowGroupLogEvent) inEvent;
event.setString("RuleFlow Group activated: " + inRuleFlowGroupEvent.getGroupName() + "[size=" + inRuleFlowGroupEvent.getSize() + "]");
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_GROUP_ACTIVATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULEFLOW_GROUP_DEACTIVATED:
inRuleFlowGroupEvent = (RuleFlowGroupLogEvent) inEvent;
event.setString("RuleFlow Group deactivated: " + inRuleFlowGroupEvent.getGroupName() + "[size=" + inRuleFlowGroupEvent.getSize() + "]");
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULEFLOW_GROUP_DEACTIVATED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_PACKAGE_ADDED:
RuleBaseLogEvent ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Package added: " + ruleBaseEvent.getPackageName());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_PACKAGE_ADDED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_PACKAGE_REMOVED:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Package removed: " + ruleBaseEvent.getPackageName());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_PACKAGE_REMOVED:
beforeEvents.pop();
break;
case LogEvent.BEFORE_RULE_ADDED:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Rule added: " + ruleBaseEvent.getRuleName());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULE_ADDED:
if (!beforeEvents.isEmpty()) {
Event beforeEvent = (Event) beforeEvents.pop();
beforeEvent.addSubEvents(newActivations);
newActivations.clear();
}
break;
case LogEvent.BEFORE_RULE_REMOVED:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Rule removed: " + ruleBaseEvent.getRuleName());
if (!beforeEvents.isEmpty()) {
((Event) beforeEvents.peek()).addSubEvent(event);
} else {
events.add(event);
}
beforeEvents.push(event);
break;
case LogEvent.AFTER_RULE_REMOVED:
if (!beforeEvents.isEmpty()) {
Event beforeEvent = (Event) beforeEvents.pop();
beforeEvent.addSubEvents(newActivations);
newActivations.clear();
}
break;
default:
// do nothing
break;
}
}
return events;
}
protected List createDrools4EventList(List logEvents) {
Iterator iterator = logEvents.iterator();
List events = new ArrayList();
Event currentBeforeActivationEvent = null;
Event currentBeforePackageEvent = null;
List newActivations = new ArrayList();
Map activationMap = new HashMap();
Map objectMap = new HashMap();
while (iterator.hasNext()) {
LogEvent inEvent = (LogEvent) iterator.next();
Event event = new Event(inEvent.getType());
switch (inEvent.getType()) {
case LogEvent.INSERTED:
ObjectLogEvent inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object inserted (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
objectMap.put(new Long(((ObjectLogEvent) inEvent).getFactId()), event);
break;
case LogEvent.UPDATED:
inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object updated (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
Event assertEvent = (Event) objectMap.get(new Long(((ObjectLogEvent) inEvent).getFactId()));
if (assertEvent != null) {
event.setCauseEvent(assertEvent);
}
break;
case LogEvent.RETRACTED:
inObjectEvent = (ObjectLogEvent) inEvent;
event.setString("Object removed (" + inObjectEvent.getFactId() + "): " + inObjectEvent.getObjectToString());
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
assertEvent = (Event) objectMap.get(new Long(((ObjectLogEvent) inEvent).getFactId()));
if (assertEvent != null) {
event.setCauseEvent(assertEvent);
}
break;
case LogEvent.ACTIVATION_CREATED:
ActivationLogEvent inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation created: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
newActivations.add(event);
activationMap.put(((ActivationLogEvent) inEvent).getActivationId(), event);
break;
case LogEvent.ACTIVATION_CANCELLED:
inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation cancelled: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
newActivations.add(event);
event.setCauseEvent((Event) activationMap.get(((ActivationLogEvent) inEvent).getActivationId()));
break;
case LogEvent.BEFORE_ACTIVATION_FIRE:
inActivationEvent = (ActivationLogEvent) inEvent;
event.setString("Activation executed: Rule " + inActivationEvent.getRule() + " " + inActivationEvent.getDeclarations());
events.add(event);
currentBeforeActivationEvent = event;
event.setCauseEvent((Event) activationMap.get(((ActivationLogEvent) inEvent).getActivationId()));
break;
case LogEvent.AFTER_ACTIVATION_FIRE:
currentBeforeActivationEvent = null;
break;
case 8:
RuleFlowLogEvent inRuleFlowEvent = (RuleFlowLogEvent) inEvent;
event.setString("RuleFlow started: " + inRuleFlowEvent.getProcessName() + "[" + inRuleFlowEvent.getProcessId() + "]");
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
break;
case 9:
inRuleFlowEvent = (RuleFlowLogEvent) inEvent;
event.setString("RuleFlow completed: " + inRuleFlowEvent.getProcessName() + "[" + inRuleFlowEvent.getProcessId() + "]");
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
break;
case 10:
RuleFlowGroupLogEvent inRuleFlowGroupEvent = (RuleFlowGroupLogEvent) inEvent;
event.setString("RuleFlowGroup activated: " + inRuleFlowGroupEvent.getGroupName() + "[size=" + inRuleFlowGroupEvent.getSize() + "]");
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
break;
case 11:
inRuleFlowGroupEvent = (RuleFlowGroupLogEvent) inEvent;
event.setString("RuleFlowGroup deactivated: " + inRuleFlowGroupEvent.getGroupName() + "[size=" + inRuleFlowGroupEvent.getSize() + "]");
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
break;
case 12:
RuleBaseLogEvent ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Package added: " + ruleBaseEvent.getPackageName());
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
currentBeforePackageEvent = event;
break;
case 13:
currentBeforePackageEvent = null;
break;
case 14:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Package removed: " + ruleBaseEvent.getPackageName());
if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
currentBeforePackageEvent = event;
break;
case 15:
currentBeforePackageEvent = null;
break;
case 17:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Rule added: " + ruleBaseEvent.getRuleName());
if (currentBeforePackageEvent != null) {
currentBeforePackageEvent.addSubEvent(event);
} else if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
break;
case 19:
ruleBaseEvent = (RuleBaseLogEvent) inEvent;
event.setString("Rule removed: " + ruleBaseEvent.getRuleName());
if (currentBeforePackageEvent != null) {
currentBeforePackageEvent.addSubEvent(event);
} else if (currentBeforeActivationEvent != null) {
currentBeforeActivationEvent.addSubEvent(event);
} else {
events.add(event);
}
event.addSubEvents(newActivations);
newActivations.clear();
break;
}
}
return events;
}
public void deleteLog() {
if (logFileName != null) {
File file = new File(logFileName);
try {
file.delete();
// TODO delete file cause this doesn't seem to work
setLogFile(null);
refresh();
} catch (Throwable t) {
t.printStackTrace();
DroolsEclipsePlugin.log(t);
}
}
}
protected void becomesVisible() {
refresh();
}
protected String getHelpContextId() {
return null;
}
public Event getSelectedEvent() {
ISelection selection = getViewer().getSelection();
if (selection instanceof IStructuredSelection) {
Object selected = ((IStructuredSelection) selection).getFirstElement();
if (selected instanceof Event) {
return (Event) selected;
}
}
return null;
}
public void showEvent(Event event) {
((TreeViewer) getViewer()).reveal(event);
}
protected void fillContextMenu(IMenuManager menu) {
Event selected = getSelectedEvent();
if (selected != null) {
Event causeEvent = selected.getCauseEvent();
if (causeEvent != null) {
menu.add(getAction("ShowEventCause"));
}
}
menu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
}
protected void createActions() {
deleteAction = new DeleteLogAction(this);
setAction("ClearLog", deleteAction);
deleteAction.setEnabled(logFileName != null);
refreshAction = new RefreshLogAction(this);
setAction("RefreshLog", refreshAction);
refreshAction.setEnabled(logFileName != null);
IAction action = new OpenLogAction(this);
setAction("OpenLog", action);
action = new ShowEventCauseAction(this);
setAction("ShowEventCause", action);
}
protected void configureToolBar(IToolBarManager tbm) {
tbm.add(getAction("OpenLog"));
tbm.add(getAction("RefreshLog"));
tbm.add(getAction("ClearLog"));
}
public void saveState(IMemento memento) {
memento.putString(LOG_FILE_NAME, logFileName);
}
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
if (memento != null) {
logFileName = memento.getString(LOG_FILE_NAME);
}
}
public static class Event {
private static long counter = 0;
private final long recency = counter++;
private String toString;
private int type;
private List<Event> subEvents = new ArrayList<Event>();
private Event causeEvent;
public Event(int type) {
this.type = type;
}
public void setString(String toString) {
this.toString = toString;
}
public String toString() {
return toString;
}
public int getType() {
return type;
}
public void addSubEvent(Event subEvent) {
subEvents.add(subEvent);
}
public void addSubEvents(Collection<Event> subEvents) {
this.subEvents.addAll(subEvents);
}
public Object[] getSubEvents() {
return subEvents.toArray();
}
public boolean hasSubEvents() {
return !subEvents.isEmpty();
}
public void setCauseEvent(Event causeEvent) {
this.causeEvent = causeEvent;
}
public Event getCauseEvent() {
return causeEvent;
}
}
public class AuditLabelProvider extends LabelProvider implements IColorProvider {
public Color getForeground(Object element) {
return null;
}
public Color getBackground(Object element) {
Event selected = getSelectedEvent();
if (selected != null) {
if (element.equals(selected.getCauseEvent())) {
Color color = DroolsEclipsePlugin.getDefault().getColor(CAUSE_EVENT_COLOR);
if (color == null) {
color = new Color(getControl().getDisplay(), 0, 255, 0);
DroolsEclipsePlugin.getDefault().setColor(CAUSE_EVENT_COLOR, color);
}
return color;
}
}
return null;
}
public Image getImage(Object element) {
if (element instanceof Event) {
int type = ((Event) element).getType();
if (drools4) {
switch (type) {
case LogEvent.INSERTED: return DroolsPluginImages.getImage(DroolsPluginImages.INSERT);
case LogEvent.UPDATED: return DroolsPluginImages.getImage(DroolsPluginImages.UPDATE);
case LogEvent.RETRACTED: return DroolsPluginImages.getImage(DroolsPluginImages.RETRACT);
case LogEvent.ACTIVATION_CREATED: return DroolsPluginImages.getImage(DroolsPluginImages.CREATE_ACTIVATION);
case LogEvent.ACTIVATION_CANCELLED: return DroolsPluginImages.getImage(DroolsPluginImages.CANCEL_ACTIVATION);
case LogEvent.BEFORE_ACTIVATION_FIRE: return DroolsPluginImages.getImage(DroolsPluginImages.EXECUTE_ACTIVATION);
case 8: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW);
case 9: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW);
case LogEvent.BEFORE_RULEFLOW_NODE_TRIGGERED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_NODE_TRIGGERED);
case 10: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_GROUP);
case 11: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_GROUP);
case 12: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case 14: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case 17: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case 19: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
}
}
switch (type) {
case LogEvent.INSERTED: return DroolsPluginImages.getImage(DroolsPluginImages.INSERT);
case LogEvent.UPDATED: return DroolsPluginImages.getImage(DroolsPluginImages.UPDATE);
case LogEvent.RETRACTED: return DroolsPluginImages.getImage(DroolsPluginImages.RETRACT);
case LogEvent.ACTIVATION_CREATED: return DroolsPluginImages.getImage(DroolsPluginImages.CREATE_ACTIVATION);
case LogEvent.ACTIVATION_CANCELLED: return DroolsPluginImages.getImage(DroolsPluginImages.CANCEL_ACTIVATION);
case LogEvent.BEFORE_ACTIVATION_FIRE: return DroolsPluginImages.getImage(DroolsPluginImages.EXECUTE_ACTIVATION);
case LogEvent.BEFORE_RULEFLOW_CREATED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW);
case LogEvent.BEFORE_RULEFLOW_COMPLETED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW);
case LogEvent.BEFORE_RULEFLOW_NODE_TRIGGERED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_NODE_TRIGGERED);
case LogEvent.BEFORE_RULEFLOW_GROUP_ACTIVATED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_GROUP);
case LogEvent.BEFORE_RULEFLOW_GROUP_DEACTIVATED: return DroolsPluginImages.getImage(DroolsPluginImages.RULEFLOW_GROUP);
case LogEvent.BEFORE_PACKAGE_ADDED: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case LogEvent.BEFORE_PACKAGE_REMOVED: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case LogEvent.BEFORE_RULE_ADDED: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
case LogEvent.BEFORE_RULE_REMOVED: return DroolsPluginImages.getImage(DroolsPluginImages.DROOLS);
}
return null;
}
return null;
}
}
}