Package jade.content.frame

Source Code of jade.content.frame.LEAPFrameCodec

/**
* ***************************************************************
* JADE - Java Agent DEvelopment Framework is a framework to develop
* multi-agent systems in compliance with the FIPA specifications.
* Copyright (C) 2000 CSELT S.p.A.
*
* GNU Lesser General Public License
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation,
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA  02111-1307, USA.
* **************************************************************
*/
package jade.content.frame;

import java.util.Vector;
import java.util.Enumeration;
import java.util.Date;
import java.io.*;

import jade.core.AID;
import jade.content.lang.sl.SL0Vocabulary;
import jade.util.leap.Iterator;

/**
   @author Giovanni Caire - TILAB
*/
public class LEAPFrameCodec implements jade.util.leap.Serializable {
  public static final String NAME = "LEAP";

  private transient ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
  private transient DataOutputStream      outStream = new DataOutputStream(outBuffer);
  private transient Vector             stringReferences = new Vector();
  //#MIDP_EXCLUDE_BEGIN
  private void readObject(java.io.ObjectInputStream oin) throws java.io.IOException, ClassNotFoundException {
    oin.defaultReadObject();
    outBuffer = new ByteArrayOutputStream();
    outStream = new DataOutputStream(outBuffer);
    stringReferences = new Vector();
  }
  //#MIDP_EXCLUDE_END

  // Primitive types
  private static final byte  STRING = 6;
  private static final byte  BOOLEAN = 7;
  private static final byte  INTEGER = 8;
  private static final byte  FLOAT = 9;
  private static final byte  DATE = 10;
  private static final byte  BYTE_SEQUENCE = 11;

  // Structured types
  private static final byte  AGGREGATE = 1;
  private static final byte  CONTENT_ELEMENT_LIST = 2;
  private static final byte  OBJECT = 3;

  // Markers for structured types
  private static final byte  ELEMENT = 4;
  private static final byte  END = 5;

  // Modifiers for string encoding
  private static final byte  MODIFIER = (byte) 0x10; // Only bit five set to 1
  private static final byte  UNMODIFIER = (byte) 0xEF; // Only bit five cleared to 1

  /**
     Transform a Frame into a sequence of bytes encoded according to the
     LEAP language
     @param content The Frame to be transformed
     @throws FrameException
   */
  public synchronized byte[] encode(Frame content) throws FrameException {
    if (content == null) {
      return null;
    }
    try {
      write(outStream, content);
      return outBuffer.toByteArray();
    }
    catch (FrameException fe) {
      throw fe;
    }
    catch (Throwable t) {
      throw new FrameException("Error encoding content", t);
    }
    finally {
      outBuffer.reset();
      stringReferences.removeAllElements();
    }
  }

  /**
     Transform a sequence of bytes encoded according to the LEAP
     language into a Frame
     @param content The sequence of bytes to be transformed.
     @throws FrameException
   */
  public synchronized Frame decode(byte[] content) throws FrameException {
    if (content == null || content.length == 0) {
      return null;
    }
    ByteArrayInputStream inpBuffer = null;
    DataInputStream      inpStream = null;
    try {
      inpBuffer = new ByteArrayInputStream(content);
      inpStream = new DataInputStream(inpBuffer);

      return (Frame) read(inpStream);
    }
    catch (FrameException fe) {
      //fe.printStackTrace();
      throw fe;
    }
    catch (Throwable t) {
      //t.printStackTrace();
      throw new FrameException("Error decoding content", t);
    }
    finally {
      try {
        inpStream.close();
        inpBuffer.close();
      }
      catch (IOException ioe) {
        ioe.printStackTrace();
      }
      stringReferences.removeAllElements();
    }
  }

  /**
   */
  private void write(DataOutputStream stream, Object obj) throws Throwable {
    // PRIMITIVES
    if (obj instanceof String) {
      writeString(stream, STRING, (String) obj);
    }
    else if (obj instanceof Boolean) {
      stream.writeByte(BOOLEAN);
      stream.writeBoolean(((Boolean) obj).booleanValue());
    }
    else if (obj instanceof Long) {
      stream.writeByte(INTEGER);
      stream.writeLong(((Long) obj).longValue());
    }
    //#MIDP_EXCLUDE_BEGIN
    else if (obj instanceof Double) {
      stream.writeByte(FLOAT);
      stream.writeDouble(((Double) obj).doubleValue());
    }
    //#MIDP_EXCLUDE_END
    else if (obj instanceof Date) {
      stream.writeByte(DATE);
      stream.writeLong(((Date) obj).getTime());
    }
    else if (obj instanceof byte[]) {
      stream.writeByte(BYTE_SEQUENCE);
      byte[] b = (byte[]) obj;
      stream.writeInt(b.length);
      stream.write(b, 0, b.length);
    }

    // ORDERED FRAME
    else if (obj instanceof OrderedFrame) {
      OrderedFrame f = (OrderedFrame) obj;
      int size = f.size();
      String typeName = f.getTypeName();
      if (typeName != null) {
        // AGGREGATE
        writeString(stream, AGGREGATE, typeName);
      }
      else {
        // CONTENT_ELEMENT_LIST
        stream.writeByte(CONTENT_ELEMENT_LIST);
      }
      for (int i = 0; i < size; i++) {
        stream.writeByte(ELEMENT);
        write(stream, f.elementAt(i));
      }
      stream.writeByte(END);
    }

    // QUALIFIED_FRAME
    else if (obj instanceof QualifiedFrame) {
      QualifiedFrame f = (QualifiedFrame) obj;
      writeString(stream, OBJECT, f.getTypeName());

      Enumeration e = f.keys();
      while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        writeString(stream, ELEMENT, key);
        write(stream, f.get(key));
      }
      stream.writeByte(END);
    }

    // AID
    else if (obj instanceof AID) {
      // Convert the AID into a qualified frame and call write() again
      write(stream, aidToFrame((AID) obj));
    }

    else {
      throw new FrameException("Object "+obj+" cannot be encoded");
    }
  }

  /**
   */
  private Object read(DataInputStream stream) throws Throwable {
    Object obj = null
    byte type = stream.readByte();

    // PRIMITIVES
    if ((type&UNMODIFIER) == STRING) {
      obj = readString(stream, type);
    }
    else if (type == BOOLEAN) {
      obj = new Boolean(stream.readBoolean());
    }
    else if (type == INTEGER) {
      obj = new Long(stream.readLong());
    }
    //#MIDP_EXCLUDE_BEGIN
    else if (type == FLOAT) {
      obj = new Double(stream.readDouble());
    }
    //#MIDP_EXCLUDE_END
    else if (type == DATE) {
      obj = new Date(stream.readLong());
    }
    else if (type == BYTE_SEQUENCE) {
      int length = stream.readInt();
      obj = new byte[length];
      stream.read((byte[]) obj, 0, length);
    }

    // AGGREGATE
    else if ((type&UNMODIFIER) == AGGREGATE) {
      String typeName = readString(stream, type);
      OrderedFrame f = new OrderedFrame(typeName);
      fillOrderedFrame(stream, f);
      obj = f;
    }

    // CONTENT_ELEMENT_LIST
    else if (type == CONTENT_ELEMENT_LIST) {
      OrderedFrame f = new OrderedFrame(null);
      fillOrderedFrame(stream, f);
      obj = f;
    }

    // QUALIFIED_FRAME
    else if ((type&UNMODIFIER) == OBJECT) {
      String typeName = readString(stream, type);
      QualifiedFrame f = new QualifiedFrame(typeName);

      byte marker = stream.readByte();
      do {
        if ((marker&UNMODIFIER) == ELEMENT) {
          String elementName = readString(stream, marker);
          Object elementVal = read(stream);
          f.put(elementName, elementVal);
          marker = stream.readByte();
        }
      }
      while (marker != END);

      // If this QualifiedFrame represents an AID, convert it
      if (f.getTypeName().equals(SL0Vocabulary.AID)) {
        obj = frameToAid(f);
      }
      else {
        obj = f;
      }
    }
    else {
      throw new FrameException("Unexpected tag "+type);
    }

    return obj;
  }

  private void fillOrderedFrame(DataInputStream stream, OrderedFrame f) throws Throwable {
    byte marker = stream.readByte();
    do {
      if (marker == ELEMENT) {
        Object elementVal = read(stream);
        f.addElement(elementVal);
        marker = stream.readByte();
      }
    }
    while (marker != END);
  }

  private final void writeString(DataOutputStream stream, byte tag, String s) throws Throwable {
    int index = stringReferences.indexOf(s);
    if (index >= 0) {
      // Write the tag modified and just put the index
      stream.writeByte(tag|MODIFIER);
      stream.writeByte(index);

    }
    else {
      stream.writeByte(tag);
      stream.writeUTF(s);
      if ((s.length() > 1) && (stringReferences.size() < 256)) {
        stringReferences.addElement(s);
        //System.out.println("writeString: added:"+s);
      }
    }
  }

  private final String readString(DataInputStream stream, byte tag) throws Throwable {
    if ((tag&MODIFIER) != 0) {
      int index = stream.readUnsignedByte();
      String s = (String) stringReferences.elementAt(index);
      return s;
    }
    else {
      String s = stream.readUTF();
      if ((s.length() > 1) && (stringReferences.size() < 256)) {
        stringReferences.addElement(s);
      }
      return s;
    }
  }

  private final QualifiedFrame aidToFrame(AID id) {
    QualifiedFrame f = new QualifiedFrame(SL0Vocabulary.AID);
    // Name
    f.put(SL0Vocabulary.AID_NAME, id.getName());

    // Addresses
    Iterator i = id.getAllAddresses();
    if (i.hasNext()) {
      OrderedFrame addresses = new OrderedFrame(SL0Vocabulary.SEQUENCE);
      while (i.hasNext()) {
        addresses.addElement(i.next());
      }
      f.put(SL0Vocabulary.AID_ADDRESSES, addresses);
    }
    // Resolvers
    i = id.getAllResolvers();
    if (i.hasNext()) {
      OrderedFrame resolvers = new OrderedFrame(SL0Vocabulary.SEQUENCE);
      while (i.hasNext()) {
        AID res = (AID) i.next();
        resolvers.addElement(aidToFrame(res));
      }
      f.put(SL0Vocabulary.AID_RESOLVERS, resolvers);
    }
    return f;
  }

  private final AID frameToAid(QualifiedFrame f) {
    // Name
    AID id = new AID((String) f.get(SL0Vocabulary.AID_NAME), AID.ISGUID);

    // Addresses
    OrderedFrame addresses = (OrderedFrame) f.get(SL0Vocabulary.AID_ADDRESSES);
    if (addresses != null) {
      for (int i = 0; i < addresses.size(); ++i) {
        id.addAddresses((String) addresses.elementAt(i));
      }
    }
    // Resolvers
    OrderedFrame resolvers = (OrderedFrame) f.get(SL0Vocabulary.AID_RESOLVERS);
    if (resolvers != null) {
      for (int i = 0; i < resolvers.size(); ++i) {
        AID res = frameToAid((QualifiedFrame) resolvers.elementAt(i));
        id.addResolvers(res);
      }
    }
    return id;
  }
}

TOP

Related Classes of jade.content.frame.LEAPFrameCodec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.