/*
* Copyright 2011 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.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.drools.mas.util;
import com.google.gson.Gson;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import org.drools.mas.Act;
import org.drools.mas.Encodings;
import org.drools.mas.body.acts.AbstractMessageBody;
import org.drools.mas.body.acts.Agree;
import org.drools.mas.body.acts.Inform;
import org.drools.mas.body.acts.InformIf;
import org.drools.mas.body.acts.InformRef;
import org.drools.mas.body.acts.QueryIf;
import org.drools.mas.body.acts.QueryRef;
import org.drools.mas.body.acts.Request;
import org.drools.mas.body.acts.RequestWhen;
import org.drools.mas.body.content.Action;
import org.drools.mas.body.content.Query;
import org.drools.mas.body.content.Ref;
import org.drools.mas.body.content.Rule;
import org.drools.runtime.rule.Variable;
/**
*
* @author salaboy
*/
public class MessageContentEncoder {
//TODO: Use provider interfaces to decouple
private static XStream xmlConverter;
private static XStream jsonConverter;
private static Gson gsonConverter;
public static void decodeBody(AbstractMessageBody body, Encodings encoding) {
Act act = body.getPerformative();
Object decoded = null;
switch (act) {
case INFORM:
decoded = MessageContentEncoder.decode(((Inform) body).getProposition().getEncodedContent(), encoding);
((Inform) body).getProposition().setData(decoded);
((Inform) body).getProposition().setEncoded(false);
break;
case INFORM_IF:
decoded = MessageContentEncoder.decode(((InformIf) body).getProposition().getEncodedContent(), encoding);
((InformIf) body).getProposition().setData(decoded);
((InformIf) body).getProposition().setEncoded(false);
break;
case INFORM_REF:
decoded = MessageContentEncoder.decode(((InformRef) body).getReferences().getEncodedContent(), encoding);
((InformRef) body).setReferences((Ref)decoded);
((InformRef) body).getReferences().setEncoded(false);
break;
case QUERY_IF:
decoded = MessageContentEncoder.decode(((QueryIf) body).getProposition().getEncodedContent(), encoding);
((QueryIf) body).getProposition().setData(decoded);
((QueryIf) body).getProposition().setEncoded(false);
break;
case AGREE:
Object decodedAction = MessageContentEncoder.decode(((Agree) body).getAction().getEncodedContent(), encoding);
Object decodedCondition = MessageContentEncoder.decode(((Agree) body).getCondition().getEncodedContent(), encoding);
((Agree) body).setAction((Action) decodedAction);
((Agree) body).setCondition((Rule) decodedCondition);
((Agree) body).getCondition().setEncoded(false);
((Agree) body).getAction().setEncoded(false);
break;
case QUERY_REF:
String oldEncoded = ((QueryRef) body).getQuery().getEncodedContent();
decoded = MessageContentEncoder.decode(((QueryRef) body).getQuery().getEncodedContent(), encoding);
((QueryRef) body).setQuery((Query) decoded);
((QueryRef) body).getQuery().setEncodedContent(oldEncoded);
((QueryRef) body).getQuery().setEncoded(false);
((QueryRef) body).getQuery().setEncoding(encoding);
String queryName = ((Query) decoded).getQueryName();
List<Object> args = ((Query) decoded).getArgs();
if (args != null) {
for (int i = 0; i < args.size(); i++) {
Object argument = args.get(i);
if (argument != null && argument instanceof Variable) {
Variable tmpVariable = Variable.v;
args.set(i, tmpVariable);
}
}
}
break;
case REQUEST:
String oldEncodedAction = ((Request) body).getAction().getEncodedContent();
decoded = MessageContentEncoder.decode(((Request) body).getAction().getEncodedContent(), encoding);
((Request) body).setAction((Action) decoded);
System.err.println( decoded );
((Request) body).getAction().setEncodedContent(oldEncodedAction);
((Request) body).getAction().setEncoded(false);
break;
case REQUEST_WHEN:
String oldEncodedActionWhen = ((RequestWhen) body).getAction().getEncodedContent();
String oldEncodedConditionWhen = ((RequestWhen) body).getCondition().getEncodedContent();
Object decodedActionRequestWhen = MessageContentEncoder.decode(((RequestWhen) body).getAction().getEncodedContent(), encoding);
Object decodedConditionRequestWhen = MessageContentEncoder.decode(((RequestWhen) body).getCondition().getEncodedContent(), encoding);
((RequestWhen) body).setAction((Action) decodedActionRequestWhen);
((RequestWhen) body).getAction().setEncodedContent(oldEncodedActionWhen);
((RequestWhen) body).getAction().setEncoded(false);
((RequestWhen) body).setCondition((Rule) decodedConditionRequestWhen);
((RequestWhen) body).getCondition().setEncodedContent(oldEncodedConditionWhen);
((RequestWhen) body).getCondition().setEncoded(false);
break;
}
}
public static void encodeBody(AbstractMessageBody body, Encodings encoding) {
Act act = body.getPerformative();
String encoded = "";
switch (act) {
case INFORM:
encoded = MessageContentEncoder.encode(((Inform) body).getProposition().getData(), encoding);
((Inform) body).getProposition().setEncodedContent(encoded);
((Inform) body).getProposition().setEncoded(true);
((Inform) body).getProposition().setEncoding(encoding);
((Inform) body).getProposition().setData(null);
break;
case INFORM_IF:
encoded = MessageContentEncoder.encode(((InformIf) body).getProposition().getData(), encoding);
((InformIf) body).getProposition().setEncodedContent(encoded);
((InformIf) body).getProposition().setEncoded(true);
((InformIf) body).getProposition().setEncoding(encoding);
((InformIf) body).getProposition().setData(null);
break;
case INFORM_REF:
encoded = MessageContentEncoder.encode(((InformRef) body).getReferences(), encoding);
((InformRef) body).getReferences().setEncodedContent(encoded);
((InformRef) body).getReferences().setEncoded(true);
((InformRef) body).getReferences().setEncoding(encoding);
((InformRef) body).getReferences().setReferences(null);
break;
case QUERY_IF:
encoded = MessageContentEncoder.encode(((QueryIf) body).getProposition().getData(), encoding);
((QueryIf) body).getProposition().setEncodedContent(encoded);
((QueryIf) body).getProposition().setEncoded(true);
((QueryIf) body).getProposition().setEncoding(encoding);
((QueryIf) body).getProposition().setData(null);
break;
case QUERY_REF:
encoded = MessageContentEncoder.encode(((QueryRef) body).getQuery(), encoding);
((QueryRef) body).getQuery().setEncodedContent(encoded);
((QueryRef) body).getQuery().setEncoded(true);
((QueryRef) body).getQuery().setEncoding(encoding);
((QueryRef) body).getQuery().getArgs().clear();
((QueryRef) body).getQuery().getReferences().clear();
((QueryRef) body).getQuery().setQueryName("");
break;
case AGREE:
String encodedAction = MessageContentEncoder.encode(((Agree) body).getAction(), encoding);
String encodedCondition = MessageContentEncoder.encode(((Agree) body).getCondition(), encoding);
((Agree) body).getAction().setEncoded(true);
((Agree) body).getAction().setEncodedContent(encodedAction);
((Agree) body).getAction().setEncoding(encoding);
((Agree) body).getAction().getArgs().clear();
((Agree) body).getAction().getReferences().clear();
((Agree) body).getCondition().setEncoded(true);
((Agree) body).getCondition().setEncoding(encoding);
((Agree) body).getCondition().setEncodedContent(encodedCondition);
break;
case REQUEST:
encoded = MessageContentEncoder.encode(((Request) body).getAction(), encoding);
((Request) body).getAction().setEncoded(true);
((Request) body).getAction().setEncodedContent(encoded);
((Request) body).getAction().setEncoding(encoding);
((Request) body).getAction().getArgs().clear();
((Request) body).getAction().getReferences().clear();
break;
case REQUEST_WHEN:
String encodedConditionRequestWhen = MessageContentEncoder.encode(((RequestWhen) body).getCondition(), encoding);
String encodedActionRequestWhen = MessageContentEncoder.encode(((RequestWhen) body).getAction(), encoding);
((RequestWhen) body).getAction().setEncoded(true);
((RequestWhen) body).getAction().setEncodedContent(encodedActionRequestWhen);
((RequestWhen) body).getAction().setEncoding(encoding);
((RequestWhen) body).getAction().getArgs().clear();
((RequestWhen) body).getAction().getArgs().clear();
((RequestWhen) body).getCondition().setEncoded(true);
((RequestWhen) body).getCondition().setEncodedContent(encodedConditionRequestWhen);
break;
}
}
public static String encode(Object obj, Encodings encoding) {
switch (encoding) {
case BYTE:
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
bos.close();
return new String(bos.toByteArray());
} catch (IOException ioe) {
return null;
}
case JSON:
String bodyString = getJsonConverter().toXML(obj);
//TODO : Check - bug in XStream ?? Class name has one \" too much
bodyString = bodyString.replaceAll("\"\"", "\"");
return bodyString;
case GSON:
return getGsonConverter().toJson(obj);
case XML:
return getXmlConverter().toXML(obj);
default:
return null;
}
}
private static XStream getJsonConverter() {
if (jsonConverter == null) {
jsonConverter = new XStream(new JettisonMappedXmlDriver());
}
return jsonConverter;
}
private static Gson getGsonConverter() {
if (gsonConverter == null) {
gsonConverter = new Gson();
}
return gsonConverter;
}
protected static XStream getXmlConverter() {
if (xmlConverter == null) {
xmlConverter = new XStream();
}
return xmlConverter;
}
protected static Object decode(String encodedContent, Encodings encoding) {
switch (encoding) {
case BYTE:
try {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(encodedContent.getBytes()));
return ois.readObject();
} catch (Exception e) {
return null;
}
case JSON:
return getJsonConverter().fromXML(encodedContent);
case XML:
default:
return getXmlConverter().fromXML(encodedContent);
}
}
}