// Module : $RCSfile: EventGenerationRule.java,v $ // Version : $Revision: 0.0 $ $Author: patrick $ $Date: 22.08.2012 $ // Project : quest-plugin-mfc // Creation : 2012 by patrick // Copyright : Patrick Harms, 2012 package de.ugoe.cs.quest.plugin.mfc; import java.util.ArrayList; import java.util.List; import org.jdom.Element; import org.jdom.Namespace; import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessageType; /** *

* TODO comment *

* * @version $Revision: $ $Date: 22.08.2012$ * @author 2012, last modified by $Author: patrick$ */ class EventGenerationRule { /** *

* the namespace used for parsing the rule *

*/ private Namespace namespace; /** *

* the name of the rule *

*/ private String name; /** *

* the list of conditions for the rule to be matched *

*/ private List messageConditions; /** *

* the list of parameters to be provided to the generated event *

*/ private List eventParameters; /** *

* the list of replay message generation rules *

*/ private List replayMessageSpecifications; /** *

* TODO: comment *

* * @param ruleElement * @param rulesNamespace */ @SuppressWarnings("unchecked") EventGenerationRule(Element ruleElement, Namespace rulesNamespace) { this.namespace = rulesNamespace; this.name = ruleElement.getAttributeValue("name"); this.messageConditions = new ArrayList(); this.eventParameters = new ArrayList(); this.replayMessageSpecifications = new ArrayList(); for (Element child : (List) ruleElement.getChildren()) { if ("msg".equals(child.getName()) && namespace.equals(child.getNamespace())) { messageConditions.add(new MessageCondition(child)); } else if ("idinfo".equals(child.getName()) && namespace.equals(child.getNamespace())) { for (Element parameterElements : (List) child.getChildren()) { eventParameters.add(new Term(parameterElements)); } } else if ("genMsg".equals(child.getName()) && namespace.equals(child.getNamespace())) { replayMessageSpecifications.add(new ReplayMessageSpec(child)); } else if ("genMsgSeq".equals(child.getName()) && namespace.equals(child.getNamespace())) { replayMessageSpecifications.add(new ReplayMessageSpec(child)); } else { throw new IllegalArgumentException ("the provided rules can not be parsed: unknown element " + child.getName()); } } } /** * @return the name */ String getName() { return name; } /** *

* TODO: comment *

* * @return */ List getMessageConditions() { return messageConditions; } /** *

* TODO: comment *

* * @return */ List getEventParameters() { return eventParameters; } /** *

* TODO: comment *

* * @return */ List getReplayMessageSpecifications() { return replayMessageSpecifications; } /** *

* TODO comment *

* * @version $Revision: $ $Date: 22.08.2012$ * @author 2012, last modified by $Author: patrick$ */ class MessageCondition { /** *

* true, if the condition defines to match several conditions *

*/ private boolean matchMultiple; /** *

* the type of the message matched by the condition *

*/ private WindowsMessageType messageType; /** *

* the term conditions associate with the rule condition *

*/ private List attributeConditions; /** *

* the list of messages to be stored, if the message matches, for continuing the * rule application *

*/ private ArrayList messagesToStore; /** *

* TODO: comment *

* * @param msgChild */ @SuppressWarnings("unchecked") private MessageCondition(Element msgChild) { this.matchMultiple = "true".equals(msgChild.getAttributeValue("multiple")); this.messageType = WindowsMessageType.parseMessageType(msgChild.getAttributeValue("type")); this.attributeConditions = new ArrayList(); for (Element childElement : (List) msgChild.getChildren("equals", namespace)) { attributeConditions.add(new AttributeCondition(childElement)); } this.messagesToStore = new ArrayList(); for (Element childElement : (List) msgChild.getChildren("store", namespace)) { messagesToStore.add(new Term(childElement)); } for (Element childElement : (List) msgChild.getChildren("storeSeq", namespace)) { messagesToStore.add(new Term(childElement)); } } /** * @return the matchMultiple */ boolean matchMultiple() { return matchMultiple; } /** *

* TODO: comment *

* * @return */ WindowsMessageType getMessageType() { return messageType; } /** *

* TODO: comment *

* * @return */ List getAttributeConditions() { return attributeConditions; } /** * @return the valuesToStore */ ArrayList getMessagesToStore() { return messagesToStore; } } /** *

* TODO comment *

* * @version $Revision: $ $Date: 22.08.2012$ * @author 2012, last modified by $Author: patrick$ */ class AttributeCondition { /** *

* the left hand side of the condition *

*/ private Term leftHandSide; /** *

* the left hand side of the condition *

*/ private Term rightHandSide; /** *

* TODO: comment *

* * @param childElement */ private AttributeCondition(Element conditionElement) { this.leftHandSide = new Term((Element) conditionElement.getChildren().get(0)); this.rightHandSide = new Term((Element) conditionElement.getChildren().get(1)); } /** * @return the leftHandSide */ Term getLeftHandSide() { return leftHandSide; } /** * @return the rightHandSide */ Term getRightHandSide() { return rightHandSide; } } /** *

* TODO comment *

* * @version $Revision: $ $Date: 22.08.2012$ * @author 2012, last modified by $Author: patrick$ */ class Term { /** *

* the name of the term *

*/ private String name; /** *

* the value of the term, if it is a constValue, null instead *

*/ private String value; /** *

* the variable name of the object, i.e. a message, of which a parameter is identified if * the term is a winInfoValue or a msgInfoValue; null instead *

*/ private String messageId; /** *

* the name of the parameter of the object, e.g. a message, of which a parameter is * identified if the term is a paramValue, null instead *

*/ private String messageParameterName; /** *

* the variable name of the message sequence denoted by the term in case of a seqValue; * null instead *

*/ private String sequenceId; /** *

* the name of the parameter of the sequence of which a parameter is * identified if the term is a seqValue, null instead *

*/ private String sequenceParameterName; /** *

* the name of the parameter of the window of the object, e.g. a message, of which a * parameter is identified if the term is a winInfoValue, null instead *

*/ private String windowParameterName; /** *

* the name of the info of the message of which a parameter is identified if the * term is a msgInfoValue, null instead *

*/ private String messageInfoName; /** *

* the name of the parameter of the message into which a value shall be stored if the * term is a resolveHwnd, null instead *

*/ private String storeParameterName; /** *

* the list of handles to be resolved in case the term is a store or storeSeq, null instead *

*/ private List resolveHandles; /** *

* TODO: comment *

* * @param object */ @SuppressWarnings("unchecked") private Term(Element termElement) { this.name = termElement.getName(); if ("constValue".equals(name)) { this.value = termElement.getAttributeValue("value"); } else if ("paramValue".equals(name)) { this.messageId = termElement.getAttributeValue("obj"); this.messageParameterName = termElement.getAttributeValue("param"); } else if ("winInfoValue".equals(name)) { this.messageId = termElement.getAttributeValue("obj"); this.windowParameterName = termElement.getAttributeValue("winParam"); } else if ("msgInfoValue".equals(name)) { this.messageId = termElement.getAttributeValue("obj"); this.messageInfoName = termElement.getAttributeValue("msgParam"); } else if ("seqValue".equals(name)) { this.sequenceId = termElement.getAttributeValue("seqObj"); this.sequenceParameterName = termElement.getAttributeValue("param"); } else if ("store".equals(name)) { this.messageId = termElement.getAttributeValue("var"); if ((termElement.getChildren() != null) && (termElement.getChildren().size() > 0)) { this.resolveHandles = new ArrayList(); for (Element child : (List) termElement.getChildren()) { this.resolveHandles.add(new Term(child)); } } } else if ("storeSeq".equals(name)) { this.sequenceId = termElement.getAttributeValue("varSeq"); if ((termElement.getChildren() != null) && (termElement.getChildren().size() > 0)) { this.resolveHandles = new ArrayList(); for (Element child : (List) termElement.getChildren()) { this.resolveHandles.add(new Term(child)); } } } else if ("resolveHwnd".equals(name)) { this.messageParameterName = termElement.getAttributeValue("param"); this.storeParameterName = termElement.getAttributeValue("storeParam"); } } /** * @return the name */ String getName() { return name; } /** * @return the value */ String getValue() { return value; } /** * @return the object */ String getMessageId() { return messageId; } /** * @return the objectParameter */ String getMessageParameterName() { return messageParameterName; } /** * @return the sequenceId */ String getSequenceId() { return sequenceId; } /** * @return the sequenceParameter */ String getSequenceParameterName() { return sequenceParameterName; } /** * @return the windowParameter */ String getWindowParameterName() { return windowParameterName; } /** * @return the messageParameter */ String getMessageInfoName() { return messageInfoName; } /** * @return the storeParameter */ String getStoreParameterName() { return storeParameterName; } /** * @return the resolveHandles */ List getResolveHandles() { return resolveHandles; } } /** *

* TODO comment *

* * @version $Revision: $ $Date: 22.08.2012$ * @author 2012, last modified by $Author: patrick$ */ class ReplayMessageSpec { /** *

* determines, if this specification defines one, or a sequence of messages *

*/ private boolean generateSingleMessage; /** *

* the id of a concrete message of message sequence to be replayed as is *

*/ private String replayObjectId; private Term type; private Term target; private Term lparamLoWord; private Term lparamHiWord; private Term lparam; private Term wparamLoWord; private Term wparamHiWord; private Term wparam; private int delay; /** *

* TODO: comment *

* * @param child */ @SuppressWarnings("unchecked") private ReplayMessageSpec(Element replayMessageSpecElement) { List children = replayMessageSpecElement.getChildren(); if ("genMsg".equals(replayMessageSpecElement.getName())) { generateSingleMessage = true; if (children.size() == 1) { replayObjectId = children.get(0).getAttributeValue("obj"); } } else { generateSingleMessage = false; if (children.size() == 1) { replayObjectId = children.get(0).getAttributeValue("seqObj"); } } this.delay = Integer.parseInt(replayMessageSpecElement.getAttributeValue("delay")); if (children.size() > 1) { for (Element child : children) { Element termElement = (Element) child.getChildren().get(0); if (child.getName().equals("type")) { this.type = new Term(termElement); } else if (child.getName().equals("target")) { this.target = new Term(termElement); if (!generateSingleMessage) { // in this case, the target is always a sequence value term, i.e. // the targets of the originally recorded sequence. So the // replay object id is set to this sequence replayObjectId = target.getSequenceId(); } } else if (child.getName().equals("LPARAM")) { Element loWordElement = child.getChild("LOWORD", namespace); if (loWordElement != null) { this.lparamLoWord = new Term((Element) loWordElement.getChildren().get(0)); } Element hiWordElement = child.getChild("HIWORD", namespace); if (hiWordElement != null) { this.lparamHiWord = new Term((Element) hiWordElement.getChildren().get(0)); } if ((lparamLoWord == null) && (lparamHiWord == null)) { this.lparam = new Term(termElement); } } else if (child.getName().equals("WPARAM")) { Element loWordElement = child.getChild("LOWORD", namespace); if (loWordElement != null) { this.wparamLoWord = new Term((Element) loWordElement.getChildren().get(0)); } Element hiWordElement = child.getChild("HIWORD", namespace); if (hiWordElement != null) { this.wparamHiWord = new Term((Element) hiWordElement.getChildren().get(0)); } if ((wparamLoWord == null) && (wparamHiWord == null)) { this.wparam = new Term(termElement); } } } } } /** *

* TODO: comment *

* * @return */ boolean generateSingleMessage() { return generateSingleMessage; } /** *

* TODO: comment *

* * @return */ String getReplayObjectId() { return replayObjectId; } /** * @return the type */ Term getType() { return type; } /** * @return the target */ Term getTarget() { return target; } /** * @return the lparamLoWord */ Term getLparamLoWord() { return lparamLoWord; } /** * @return the lparamHiWord */ Term getLparamHiWord() { return lparamHiWord; } /** * @return the lparam */ Term getLparam() { return lparam; } /** * @return the wparamLoWord */ Term getWparamLoWord() { return wparamLoWord; } /** * @return the wparamHiWord */ Term getWparamHiWord() { return wparamHiWord; } /** * @return the wparam */ Term getWparam() { return wparam; } /** * @return the delay */ int getDelay() { return delay; } } }