Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /*
  2.  * MbPacket.java
  3.  *
  4.  * Created on den 24 augusti 2003, 12:55
  5.  */
  6. package Macbeth.System;
  7.  
  8. import Macbeth.XML.XMLDataHandler;
  9. import Macbeth.XML.XMLParser;
  10. import Macbeth.Utilities.MySystem;
  11. import java.util.Iterator;
  12. import java.util.HashMap;
  13. import java.io.IOException;
  14.  
  15. import org.xml.sax.SAXException;
  16.  
  17. /**
  18.  * This class represents a Macbeth packet, containing both its destination,
  19.  * its source, and its contents.
  20.  * @author Jimmy
  21.  */
  22. public class MbPacket {
  23.  
  24.     /**
  25.      * The Macbeth location to which this packet is addressed.
  26.      * If the kernel-field is set to "self", it means that
  27.      * the packet will be delivered locally only (that is,
  28.      * within the same kernel it was sent from). If the field
  29.      * is set to something else, however, this name will be
  30.      * looked up in the list of known kernels, which, in case
  31.      * the kernel was found, also provides the internet address
  32.      * of the specified kernel.
  33.      */
  34.     private MbLocation destination;
  35.  
  36.     /**
  37.      * The Macbeth location from which this packet was sent.
  38.      * This can be used by receiver module (or kernel)
  39.      * to identify the sender.
  40.      */
  41.     private MbLocation source;
  42.  
  43.     /**
  44.      * The packet contents (an XML-document).
  45.      */
  46.     private String contents;
  47.  
  48.     /**
  49.      * The remote address of the client that sent us this packet.
  50.      * If the packet has never been transported via any networks,
  51.      * this value is "self" (that is, source kernel and dest kernel
  52.      * are equal).
  53.      */
  54.     private String originAddress;
  55.  
  56.     /**
  57.      * Gets the destination of this packet.
  58.      * @return The packet destination.
  59.      */
  60.     public MbLocation getDestination() {
  61.         return destination;
  62.     }
  63.     /**
  64.      * Sets the destination of this packet.
  65.      * @param destination The new destination.
  66.      */
  67.     public void setDestination(MbLocation destination) {
  68.         this.destination = destination;
  69.     }
  70.     /**
  71.      * Sets the kernel field in the destination of this packet.
  72.      * @param kernel The new destination kernel.
  73.      */
  74.     public void setDestinationKernel(String kernel) {
  75.         destination.setKernel(kernel);
  76.     }
  77.     /**
  78.      * Sets the module field in the destination of this packet.
  79.      * @param module The new destination module.
  80.      */
  81.     public void setDestinationModule(String module) {
  82.         destination.setModule(module);
  83.     }
  84.  
  85.     /**
  86.      * Gets the source of this packet.
  87.      * @return The packet source.
  88.      */
  89.     public MbLocation getSource() {
  90.         return source;
  91.     }
  92.     /**
  93.      * Sets the source of this packet.
  94.      * @param source The new packet source.
  95.      */
  96.     public void setSource(MbLocation source) {
  97.         this.source = source;
  98.     }
  99.  
  100.     /**
  101.      * Gets the packet contents. This is an XML-string.
  102.      * @return The packet contents.
  103.      */
  104.     public synchronized String getContents() {
  105.         return contents;
  106.     }
  107.     /**
  108.      * Sets the packet contents. This must be valid XML-data.
  109.      * @param contents The new packet contents.
  110.      */
  111.     public synchronized void setContents(String contents) {
  112.         this.contents = contents;
  113.     }
  114.     /**
  115.      * Appends a string to the packet contents. This must be
  116.      * valid XML-data.
  117.      * @param s The string to append.
  118.      */
  119.     public synchronized void appendContents(String s) {
  120.         this.contents += s;
  121.     }
  122.  
  123.     /**
  124.      * Gets the source remote address of this packet.
  125.      * @return The remote address of the packet source.
  126.      */
  127.     public synchronized String getOriginAddress() {
  128.         return originAddress;
  129.     }
  130.  
  131.     /**
  132.      * Creates a new instance of MbPacket.
  133.      */
  134.     public MbPacket() {
  135.         destination = new MbLocation();
  136.         source = new MbLocation();
  137.         originAddress = "self";
  138.         contents = "";
  139.     }
  140.  
  141.     /**
  142.      * Serializes this packet into a string object (XML-formatted)
  143.      * @return the packet as an XML-string.
  144.      */
  145.     public String serializeToString() {
  146.         String s = "<mbpacket ";
  147.         s += "sourcekernel=\"" + source.getKernel() + "\" ";
  148.         s += "sourcemodule=\"" + source.getModule() + "\" ";
  149.         //s += "destkernel=\"" + destination.kernel + "\" ";
  150.         s += "destmodule=\"" + destination.getModule() + "\" ";
  151.         s += ">" + MySystem.lineBreak;
  152.         s += contents;
  153.         s += MySystem.lineBreak + "</mbpacket>";
  154.         return s;
  155.     }
  156.  
  157.     /**
  158.      * Tries to deserialize an XML-string into a packet.
  159.      * The format of the string must be:
  160.      * <mbpacket destmodule="modulename">
  161.      *     Only valid XML-data in here!
  162.      * </mbpacket>
  163.      * or else this function will not succeed.
  164.      * @param s The XML-string
  165.      * @return true if successful, false otherwise.
  166.      * @throws SAXException if the string contains an invalid XML document (syntax errors).
  167.      */
  168.     synchronized public boolean createFromString(String s) throws SAXException {
  169.         //destination kernel is always set to "self"
  170.         destination = new MbLocation("self",null);
  171.         source = new MbLocation("external","external");
  172.         contents = "";
  173.         XMLParser xmlParser = new XMLParser(new DataHandler());
  174.         try {
  175.             xmlParser.parseString(s);
  176.         } catch (IOException e) {
  177.             System.err.println(e);
  178.             e.printStackTrace();
  179.             return false;
  180.         }
  181.         //TODO: why check this? can it happen?
  182.         if (destination==null) {
  183.             return false;
  184.         }
  185.         return true;
  186.     }
  187.  
  188.     /**
  189.      * A data handler for XML parser.
  190.      */
  191.     private class DataHandler implements XMLDataHandler {
  192.         //current element name
  193.         private String currentElement = null;
  194.         //current data for the element
  195.         private String currentElementData = null;
  196.  
  197.         public void XMLstartElement(String element, HashMap attributes) {
  198.             currentElementData = null;
  199.             if (element.equals("mbpacket")) {
  200.                 if (attributes.containsKey("sourcekernel")) {
  201.                     source.setKernel((String)attributes.get("sourcekernel"));
  202.                 }
  203.                 if (attributes.containsKey("sourcemodule")) {
  204.                     source.setModule((String)attributes.get("sourcemodule"));
  205.                 }
  206.                 if (attributes.containsKey("destmodule")) {
  207.                     destination.setModule((String)attributes.get("destmodule"));
  208.                 }
  209.                 // NOTE: destination kernel is IGNORED in all incoming packets!
  210.                 // (for security reasons, since no relaying is allowed. destkernel is always set to "self")
  211.             } else if (element.equals("remoteaddress") && originAddress.equals("self")) {
  212.                 //(it must equal self, or else it can be set more than once, and can thus be faked)
  213.                 //remember remote address
  214.                 if (attributes.containsKey("value")) {
  215.                     originAddress = (String)attributes.get("value");
  216.                 }
  217.             } else {
  218.                 //this is user data, so put it into the contents field
  219.                 currentElement = element;
  220.                 contents += "<" + element;
  221.                 Iterator it = attributes.keySet().iterator();
  222.                 while (it.hasNext()) {
  223.                     String key = (String)it.next();
  224.                     contents += " " + key + "=\"" + attributes.get(key) + "\"";
  225.                 }
  226.                 //NEW CODE:
  227.                 contents += ">";
  228.             }
  229.         }
  230.         public void XMLelementData(String data) {
  231.             //NEW CODE
  232.             if (currentElement!=null) {
  233.                 contents += MySystem.lineBreak + data;
  234.                 currentElementData = data;
  235.             }
  236.         }
  237.         public void XMLendElement(String element) {
  238.             if (!element.equals("remoteaddress") && !element.equals("mbpacket")) {
  239.                 //NEW CODE:
  240.                 //always add full end tag
  241.                 //TODO: maybe fix this again. OLD CODE caused some ">" to be missing though!
  242.                 contents += "</" + element + ">";
  243.             }
  244.             currentElement = null;
  245.         }
  246.         public void XMLdocumentStart() {}
  247.         public void XMLdocumentEnd() {}
  248.     }
  249. }
  250.