/* * 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.*; 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; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author salaboy */ public class MessageContentEncoder { private static Logger logger = LoggerFactory.getLogger(MessageContentEncoder.class); //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: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING INFORM: " + body); } decoded = MessageContentEncoder.decode(((Inform) body).getProposition().getEncodedContent(), encoding); ((Inform) body).getProposition().setData(decoded); ((Inform) body).getProposition().setEncoded(false); break; case CONFIRM: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING DISCONFIRM: " + body); } decoded = MessageContentEncoder.decode(((Confirm) body).getProposition().getEncodedContent(), encoding); ((Confirm) body).getProposition().setData(decoded); ((Confirm) body).getProposition().setEncoded(false); break; case DISCONFIRM: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING DISCONFIRM: " + body); } decoded = MessageContentEncoder.decode(((Disconfirm) body).getProposition().getEncodedContent(), encoding); ((Disconfirm) body).getProposition().setData(decoded); ((Disconfirm) body).getProposition().setEncoded(false); break; case INFORM_IF: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING INFORM_IF: " + body); } decoded = MessageContentEncoder.decode(((InformIf) body).getProposition().getEncodedContent(), encoding); ((InformIf) body).getProposition().setData(decoded); ((InformIf) body).getProposition().setEncoded(false); break; case INFORM_REF: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING INFORM_REF: " + body); } decoded = MessageContentEncoder.decode(((InformRef) body).getReferences().getEncodedContent(), encoding); ((InformRef) body).setReferences((Ref) decoded); ((InformRef) body).getReferences().setEncoded(false); break; case QUERY_IF: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING QUERY_IF: " + body); } decoded = MessageContentEncoder.decode(((QueryIf) body).getProposition().getEncodedContent(), encoding); ((QueryIf) body).getProposition().setData(decoded); ((QueryIf) body).getProposition().setEncoded(false); break; case AGREE: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING AGREE: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING QUERY_REF: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING REQUEST: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING REQUEST_WHEN: " + body); } 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; case FAILURE: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING REQUEST_WHEN: " + body); } String oldEncodedActionFailure = ((Failure) body).getAction().getEncodedContent(); Object decodedActionFailure = MessageContentEncoder.decode(((Failure) body).getAction().getEncodedContent(), encoding); ((Failure) body).setAction((Action) decodedActionFailure); ((Failure) body).getAction().setEncodedContent(oldEncodedActionFailure); ((Failure) body).getAction().setEncoded(false); break; case NOT_UNDERSTOOD: if (logger.isTraceEnabled()) { logger.trace(" xxx DECODING NOT_UNDERSTOOD: " + body); } if (((NotUnderstood) body).getAction() != null) { String oldEncodedActionNotUnderstood = ((NotUnderstood) body).getAction().getEncodedContent(); Object decodedActionNotUnderstood = MessageContentEncoder.decode(((NotUnderstood) body).getAction().getEncodedContent(), encoding); ((NotUnderstood) body).setAction((Action) decodedActionNotUnderstood); ((NotUnderstood) body).getAction().setEncodedContent(oldEncodedActionNotUnderstood); ((NotUnderstood) body).getAction().setEncoded(false); } break; } } public static void encodeBody(AbstractMessageBody body, Encodings encoding) { Act act = body.getPerformative(); String encoded = ""; switch (act) { case INFORM: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING INFORM: " + body); } 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 CONFIRM: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING INFORM: " + body); } encoded = MessageContentEncoder.encode(((Confirm) body).getProposition().getData(), encoding); ((Confirm) body).getProposition().setEncodedContent(encoded); ((Confirm) body).getProposition().setEncoded(true); ((Confirm) body).getProposition().setEncoding(encoding); ((Confirm) body).getProposition().setData(null); break; case DISCONFIRM: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING INFORM: " + body); } encoded = MessageContentEncoder.encode(((Disconfirm) body).getProposition().getData(), encoding); ((Disconfirm) body).getProposition().setEncodedContent(encoded); ((Disconfirm) body).getProposition().setEncoded(true); ((Disconfirm) body).getProposition().setEncoding(encoding); ((Disconfirm) body).getProposition().setData(null); break; case INFORM_IF: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING INFORM_IF: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING INFORM_REF: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING QUERY_IF: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING QUERY_REF: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING AGREE: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING REQUEST: " + body); } 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: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING REQUEST_WHEN: " + body); } 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; case FAILURE: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING FAILURE: " + body); } String encodedActionFailure = MessageContentEncoder.encode(((Failure) body).getAction(), encoding); ((Failure) body).getAction().setEncoded(true); ((Failure) body).getAction().setEncodedContent(encodedActionFailure); ((Failure) body).getAction().setEncoding(encoding); ((Failure) body).getAction().getArgs().clear(); ((Failure) body).getAction().getArgs().clear(); break; case NOT_UNDERSTOOD: if (logger.isTraceEnabled()) { logger.trace(" xxx ENCODING NOT_UNDERSTOOD: " + body); } if (((NotUnderstood) body).getAction() != null) { String encodedActionNotUnderstood = MessageContentEncoder.encode(((NotUnderstood) body).getAction(), encoding); ((NotUnderstood) body).getAction().setEncoded(true); ((NotUnderstood) body).getAction().setEncodedContent(encodedActionNotUnderstood); ((NotUnderstood) body).getAction().setEncoding(encoding); ((NotUnderstood) body).getAction().getArgs().clear(); ((NotUnderstood) body).getAction().getArgs().clear(); } 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(); xmlConverter.setClassLoader(MessageContentEncoder.class.getClassLoader()); } 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); } } }