/* * Salamander Transport Layer * * Michael J. Willis (violator@umich.edu) * * $Workfile: SalProperties.java $ * $Author: rmalan $ * $Date: 1997/07/16 02:22:31 $ * $Revision: 1.5 $ */ package Salamander; import java.util.*; import java.io.*; /** * SalProperties is used for two purposes: to identify the properties * for a given SalPacket, and to specify criteria for a search or * dataflow request from the SalConnection object. * * Data suppliers that build SalPackets are responsible for setting * up at least the name field of a SalPacket using the setName() * method. Suppliers are free to define their own custom key/value * pairs, with the only stipulation being that key names must not * have a leading underscore; these keys are reserved for internal * key values. * * Well-known properties should be accessed with the respective access * method, i.e., getName(), getTimeStamp(). */ public class SalProperties extends Properties { public static final String NAME_PROPERTY = "NAME"; public static final String TIMESTAMP_PROPERTY = "TIMESTAMP"; public static final String COOKIE_PROPERTY = "COOKIE"; /*********************************************************************** * System properties: ***********************************************************************/ public static final String OBJ_SIZE_PROPERTY = "OBJ_SIZE"; public static final String COMMAND_PROPERTY = "COMMAND"; /*********************************************************************** * Supplier and Client commands (COMMAND_PROPERTY value's): ***********************************************************************/ /* * Client to server messages: */ public static final String PUBLISH_COMMAND = "PUBLISH"; public static final String QUERY_COMMAND = "QUERY"; public static final String REMOVE_QUERY = "REMOVE QUERY"; public static final String SUPPLY_COMMAND = "SUPPLY"; public static final String REMOVE_SUPPLY = "REMOVE SUPPLY"; public static final String MATCH_SUPPLIES = "MATCH SUPPLIES"; public static final String SETUP_CONDOLENCE = "SETUP CONDOLENCE"; public static final String UNICAST_MESSAGE = "UNICAST MESSAGE"; public static final String SOURCE = "SOURCE"; public static final String DESTINATION = "DESTINATION"; /* * Server to client messages: */ public static final String QUERY_RESPONSE = "QUERY RESPONSE"; public static final String SUPPLY_RESPONSE = "SUPPLY RESPONSE"; public static final String QUERY_EXPIRED = "QUERY EXPIRED"; public static final String SUPPLIERS = "SUPPLIERS"; public static final String NOTIFICATION = "NOTIFICATION"; /*********************************************************************** * Query/Supply Properties and values: ***********************************************************************/ public static final String QUERY_ID = "QUERY ID"; public static final String QUERY_FAILED = "QUERY FAILED"; public static final String SUPPLY_ID = "SUPPLY ID"; public static final String SUPPLY_FAILED = "SUPPLY FAILED"; public static final String ALL_SALAMANDER_DATA = "ALL SALAMANDER DATA"; /** * Convenience */ public void setProperty(String s1, String s2) { put(s1, s2); } public DataOutputStream serialize(DataOutputStream out) { save(out); return out; } public DataInputStream serialize(DataInputStream in) throws IOException { load(in); return in; } /** * Loads a Props object from an InputStream. If the object was * written to the stream with save(), this function will return * with the InputStream pointing to the first byte after the Props * object in the stream. * @param in the input stream * @exception IOException Error when reading from input stream. */ public synchronized void load(InputStream in) throws IOException { BufferedReader bufIn = new BufferedReader(new InputStreamReader(in)); System.out.println("LOAD: 1"); int ch = in.read(); while (true) { switch (ch) { case -1: System.err.println("Failure in SalProperties.load!!!"); throw new IOException("End of server input stream "); // System.exit(1); // return; } if (ch == '\0') return; // Read the key StringBuffer key = new StringBuffer(); while ((ch > 0)){ key.append((char)ch); ch = in.read(); } ch = in.read(); // Read the value StringBuffer val = new StringBuffer(); while ((ch > 0)) { val.append((char)ch); ch = in.read(); } ch = in.read(); // System.out.println("READ: "+key + " = '" + val + "'"); put(key.toString(), val.toString()); } } /** * Calculate the plist size for TLV length. */ public synchronized int getLength() { int totalLength = 0; for (Enumeration e = keys(); e.hasMoreElements() ;) { String key = (String) e.nextElement(); totalLength += key.length() + 1; String val = (String ) get(key); totalLength += val.length() + 1; } return (++totalLength); } /** * Save properties to an OutputStream. */ public synchronized void save(OutputStream out) { DataOutputStream output = new DataOutputStream (out); try { for (Enumeration e = keys() ; e.hasMoreElements() ;) { String key = (String)e.nextElement(); output.writeBytes(key); output.writeByte(0); String val = (String)get(key); output.writeBytes(val); output.writeByte(0); } output.writeByte(0); } catch (IOException e) { System.err.println ("IOException: " + e); e.printStackTrace (); } } public static void main(String[] arg) { try { SalProperties p1 = new SalProperties(); SalProperties p2 = new SalProperties(); PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(in); p1.setProperty("HELLO", "BEAVER"); p1.setProperty("I'm a different property", "i'm a different value"); p1.serialize(new DataOutputStream(out)); p2.serialize(new DataInputStream(in)); p2.serialize(new DataOutputStream(System.out)); } catch (IOException e) { System.err.println("Exceptio caught"); } } }