/**
* Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* 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.wso2.carbon.mediator.command;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAttribute;
import org.apache.synapse.config.xml.SynapseXPathSerializer;
import org.apache.synapse.config.xml.SynapseXPathFactory;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.wso2.carbon.mediator.service.MediatorException;
import org.wso2.carbon.mediator.service.ui.AbstractMediator;
import org.jaxen.JaxenException;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
public class CommandMediator extends AbstractMediator {
protected static final QName ATT_ACTION = new QName("action");
protected static final QName ATT_CTXNAME = new QName("context-name");
protected static final String RM_ACTION = "ReadMessage";
protected static final String UM_ACTION = "UpdateMessage";
protected static final String RC_ACTION = "ReadContext";
protected static final String UC_ACTION = "UpdateContext";
protected static final String RAUM_ACTION = "ReadAndUpdateMessage";
protected static final String RAUC_ACTION = "ReadAndUpdateContext";
private String command = null;
private final Map<String, Object> staticSetterProperties = new HashMap<String, Object>();
private final Map<String, SynapseXPath> messageSetterProperties = new HashMap<String, SynapseXPath>();
private final Map<String, String> contextSetterProperties = new HashMap<String, String>();
private final Map<String, String> contextGetterProperties = new HashMap<String, String>();
private final Map<String, SynapseXPath> messageGetterProperties = new HashMap<String, SynapseXPath>();
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public void addStaticSetterProperty(String name, Object value) {
this.staticSetterProperties.put(name, value);
}
public void addMessageSetterProperty(String name, SynapseXPath xpath) {
this.messageSetterProperties.put(name, xpath);
}
public void addContextSetterProperty(String name, String ctxName) {
this.contextSetterProperties.put(name, ctxName);
}
public void addContextGetterProperty(String name, String value) {
this.contextGetterProperties.put(name, value);
}
public void addMessageGetterProperty(String name, SynapseXPath xpath) {
this.messageGetterProperties.put(name, xpath);
}
public Map<String, Object> getStaticSetterProperties() {
return this.staticSetterProperties;
}
public Map<String, SynapseXPath> getMessageSetterProperties() {
return this.messageSetterProperties;
}
public Map<String, String> getContextSetterProperties() {
return this.contextSetterProperties;
}
public Map<String, String> getContextGetterProperties() {
return this.contextGetterProperties;
}
public Map<String, SynapseXPath> getMessageGetterProperties() {
return this.messageGetterProperties;
}
public OMElement serialize(OMElement parent) {
OMElement pojoCommand = fac.createOMElement("pojoCommand", synNS);
saveTracingState(pojoCommand, this);
if (command != null) {
pojoCommand.addAttribute(fac.createOMAttribute(
"name", nullNS, command));
} else {
throw new MediatorException("Invalid POJO Command mediator. The command class name is required");
}
for (String propName : getStaticSetterProperties().keySet()) {
Object value = getStaticSetterProperties().get(propName);
OMElement prop = fac.createOMElement(PROP_Q.getLocalPart(), synNS);
prop.addAttribute(fac.createOMAttribute("name", nullNS, propName));
if (value instanceof String) {
prop.addAttribute(fac.createOMAttribute("value", nullNS, (String) value));
} else if (value instanceof OMElement) {
prop.addChild((OMElement) value);
} else {
throw new MediatorException("Unable to serialize the command " +
"mediator property with the naem " + propName + " : Unknown type");
}
if (getContextGetterProperties().containsKey(propName)) {
prop.addAttribute(fac.createOMAttribute("context-name", nullNS,
getContextGetterProperties().get(propName)));
} else if (getMessageGetterProperties().containsKey(propName)) {
SynapseXPathSerializer.serializeXPath(
getMessageGetterProperties().get(propName), prop, "expression");
}
pojoCommand.addChild(prop);
}
for (String propName : getMessageSetterProperties().keySet()) {
OMElement prop = fac.createOMElement(PROP_Q.getLocalPart(), synNS);
prop.addAttribute(fac.createOMAttribute("name", nullNS, propName));
SynapseXPathSerializer.serializeXPath(
getMessageSetterProperties().get(propName), prop, "expression");
if (getMessageGetterProperties().containsKey(propName)) {
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadAndUpdateMessage"));
} else if (getContextGetterProperties().containsKey(propName)) {
prop.addAttribute(fac.createOMAttribute("context-name", nullNS,
getContextGetterProperties().get(propName)));
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadMessage"));
} else {
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadMessage"));
}
pojoCommand.addChild(prop);
}
for (String propName : getContextSetterProperties().keySet()) {
OMElement prop = fac.createOMElement(PROP_Q.getLocalPart(), synNS);
prop.addAttribute(fac.createOMAttribute("name", nullNS, propName));
prop.addAttribute(fac.createOMAttribute("context-name", nullNS,
getContextSetterProperties().get(propName)));
if (getContextGetterProperties().containsKey(propName)) {
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadAndUpdateContext"));
} else if (getMessageGetterProperties().containsKey(propName)) {
SynapseXPathSerializer.serializeXPath(
getMessageGetterProperties().get(propName), prop, "expression");
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadContext"));
} else {
prop.addAttribute(fac.createOMAttribute("action", nullNS, "ReadContext"));
}
pojoCommand.addChild(prop);
}
for (String propName : getContextGetterProperties().keySet()) {
if (!isSerialized(propName)) {
String value = getContextGetterProperties().get(propName);
OMElement prop = fac.createOMElement(PROP_Q.getLocalPart(), synNS);
prop.addAttribute(fac.createOMAttribute("name", nullNS, propName));
prop.addAttribute(fac.createOMAttribute("context-name", nullNS, value));
prop.addAttribute(fac.createOMAttribute("action", nullNS, "UpdateContext"));
pojoCommand.addChild(prop);
}
}
for (String propName : getMessageGetterProperties().keySet()) {
if (!isSerialized(propName)) {
OMElement prop = fac.createOMElement(PROP_Q.getLocalPart(), synNS);
prop.addAttribute(fac.createOMAttribute("name", nullNS, propName));
SynapseXPathSerializer.serializeXPath(
getMessageGetterProperties().get(propName), prop, "expression");
prop.addAttribute(fac.createOMAttribute("action", nullNS, "UpdateMessage"));
pojoCommand.addChild(prop);
}
}
if (parent != null) {
parent.addChild(pojoCommand);
}
return pojoCommand;
}
private boolean isSerialized(String propName) {
return getContextSetterProperties().containsKey(propName) ||
getStaticSetterProperties().containsKey(propName) ||
getMessageSetterProperties().containsKey(propName);
}
public void build(OMElement elem) {
OMAttribute name = elem.getAttribute(ATT_NAME);
if (name == null) {
String msg = "The name of the actual POJO command implementation class" +
" is a required attribute";
throw new MediatorException(msg);
}
this.command = name.getAttributeValue();
// setting the properties to the command. these properties will be instantiated
// at the mediation time
for (Iterator it = elem.getChildElements(); it.hasNext();) {
OMElement child = (OMElement) it.next();
if("property".equals(child.getLocalName())) {
OMAttribute nameAttr = child.getAttribute(ATT_NAME);
if (nameAttr != null && nameAttr.getAttributeValue() != null
&& !"".equals(nameAttr.getAttributeValue())) {
handlePropertyAction(nameAttr.getAttributeValue(), child);
} else {
throw new MediatorException("A POJO command mediator " +
"property must specify the name attribute");
}
}
}
}
private void handlePropertyAction(String name, OMElement propElem) {
OMAttribute valueAttr = propElem.getAttribute(ATT_VALUE);
OMAttribute exprAttr = propElem.getAttribute(ATT_EXPRN);
OMAttribute ctxNameAttr = propElem.getAttribute(ATT_CTXNAME);
OMAttribute actionAttr = propElem.getAttribute(ATT_ACTION);
SynapseXPath xpath = null;
try {
if (exprAttr != null) {
xpath = SynapseXPathFactory.getSynapseXPath(propElem, ATT_EXPRN);
}
} catch (JaxenException e) {
throw new MediatorException("Error in building the expression as an SynapseXPath" + e);
}
// if there is a value attribute there is no action (action is implied as read value)
if (valueAttr != null) {
String value = valueAttr.getAttributeValue();
// all other three attributes can not co-exists
if (exprAttr != null && ctxNameAttr != null) {
throw new MediatorException("Command properties can not contain all three 'value', " +
"'expression' and 'context-name' attributes. Only one or " +
"combination of two can be there.");
} else {
addStaticSetterProperty(name, value);
if (exprAttr != null) {
// action ==> ReadValueAndUpdateMesssage
addMessageGetterProperty(name, xpath);
} else if (ctxNameAttr != null) {
// action ==> ReadValueAndUpdateContext
addContextGetterProperty(name, ctxNameAttr.getAttributeValue());
} // else the action ==> ReadValue
}
} else if (propElem.getFirstElement() != null) {
// all other two attributes can not co-exists
if (exprAttr != null && ctxNameAttr != null) {
throw new MediatorException("Command properties can not contain all the " +
"'expression' and 'context-name' attributes with a child. Only one " +
"attribute of those can co-exists with a child");
} else {
addStaticSetterProperty(name, propElem.getFirstElement());
if (exprAttr != null) {
// action ==> ReadValueAndUpdateMesssage
addMessageGetterProperty(name, xpath);
} else if (ctxNameAttr != null) {
// action ==> ReadValueAndUpdateContext
addContextGetterProperty(name, ctxNameAttr.getAttributeValue());
} // else the action ==> ReadValue
}
} else {
// if both context-name and expression is there
if (exprAttr != null && ctxNameAttr != null) {
if (actionAttr != null && actionAttr.getAttributeValue() != null) {
String action = actionAttr.getAttributeValue();
if (RM_ACTION.equals(action) || UC_ACTION.equals(action)) {
// action ==> ReadMessageAndUpdateContext
addMessageSetterProperty(name, xpath);
addContextGetterProperty(name, ctxNameAttr.getAttributeValue());
} else if (RC_ACTION.equals(action) || UM_ACTION.equals(action)) {
// action ==> ReadContextAndUpdateMessage
addContextSetterProperty(name, ctxNameAttr.getAttributeValue());
addMessageGetterProperty(name, xpath);
} else {
throw new MediatorException("Invalid action for " +
"the command property with the name " + name);
}
} else {
throw new MediatorException("Action attribute " +
"is required for the command property with name " + name);
}
} else {
// only one of expression or context-name is present
if (actionAttr != null && actionAttr.getAttributeValue() != null) {
String action = actionAttr.getAttributeValue();
if (exprAttr != null) {
if (RM_ACTION.equals(action)) {
// action ==> ReadMessage
addMessageSetterProperty(name, xpath);
} else if (UM_ACTION.equals(action)) {
// action ==> UpdateMessage
addMessageGetterProperty(name, xpath);
} else if (RAUM_ACTION.equals(action)) {
// action ==> ReadAndUpdateMessage
addMessageSetterProperty(name, xpath);
addMessageGetterProperty(name, xpath);
} else {
throw new MediatorException("Invalid action for " +
"the command property with the name " + name);
}
} else if (ctxNameAttr != null) {
String ctxName = ctxNameAttr.getAttributeValue();
if (RC_ACTION.equals(action)) {
// action ==> ReadContext
addContextSetterProperty(name, ctxName);
} else if (UC_ACTION.equals(action)) {
// action ==> UpdateContext
addContextGetterProperty(name, ctxName);
} else if (RAUC_ACTION.equals(action)) {
// action ==> ReadAndUpdateContext
addContextSetterProperty(name, ctxName);
addContextGetterProperty(name, ctxName);
} else {
throw new MediatorException("Invalid action for " +
"the command property with the name " + name);
}
} else {
throw new MediatorException("Unrecognized command property with the name " + name);
}
} else {
// action ==> ReadAndUpdateMessage/Context
if (exprAttr != null) {
addMessageSetterProperty(name, xpath);
addMessageGetterProperty(name, xpath);
} else if (ctxNameAttr != null) {
String ctxName = ctxNameAttr.getAttributeValue();
addContextSetterProperty(name, ctxName);
addContextGetterProperty(name, ctxName);
} else {
throw new MediatorException("Unrecognized command property with the name " + name);
}
}
}
}
}
public String getTagLocalName() {
return "pojoCommand";
}
}