SDSU CS 596: Client-Server Programming
Spring Semester, 1997
Doc 27 Distributed Objects: A First Step

To Lecture Notes Index
San Diego State University -- This page last updated Apr 24, 1997

Contents of Doc 27 Distributed Objects: A First Step


Distributed Objects slide # 1
...Why not Read/Write LabeledData Objects? slide # 4
......The Writer! slide # 4
......The Reader slide # 5
......An Example of Reading and Writing slide # 6
...What about Writing/Sending Other Objects? slide # 9
......Interface and Writer slide # 9
......Reader slide # 10
......Sample Class slide # 12
......Sample Test Program slide # 13


Doc 27 Distributed Objects: A First Step Slide # 1

Distributed Objects


Recall the server architecture

class DateServer implements ServerEngine 
     {
     DataInputStream     input;
     PrintStream     output;
     
     public ServerEngine newInstance( InputStream in, 
                                        OutputStream out )
          {return new DateServer( in, out );}
          
     public DateServer() {}


Doc 27 Distributed Objects: A First Step Slide # 2
Our ServerEngines act is if
they read strings from a Stream!


public DateServer( InputStream in, OutputStream out )
          {
          input = new DataInputStream(in);
          output = new PrintStream(out);
          }
     
     public void run(){
          try
               {
               String inputLine = input.readLine().toLowerCase();
               if ( inputLine.startsWith("date") )
                    {
                    Date now = new Date();
                    output.println(now.toString());
                    }
               input.close();
               output.close();
               }
          catch ( IOException howToHandleThis )
               {// A topic to be covered later     }
          }     
     }


Doc 27 Distributed Objects: A First Step Slide # 3
Recall The LabeledData Class

It saves/restores itself to/from a string

LabeledData original = new LabeledData();
original.put( "The", "semester");
original.put( "is", "almost");
original.put( "at", "end");

String flattened = original.toString();

LabeledData recovered = new LabeledData();

recovered.fromString( flattened );



Doc 27 Distributed Objects: A First Step Slide # 4

Why not Read/Write LabeledData Objects?

The Writer!


class LabeledDataPrintStream extends PrintStream
     {
     public static final char OBJECT_TERMINATOR = '\003';
     
     public LabeledDataPrintStream( OutputStream output)
          {
          super( output );
          }
          
     public void print( LabeledData printMe )
          {
          String toPrint = printMe.toString() + OBJECT_TERMINATOR;
          super.print( toPrint );
          }
     }


Doc 27 Distributed Objects: A First Step Slide # 5

The Reader


class LabeledDataInputStream extends FilterInputStream
     {
     private static final int EOF = -1;
     private static final char OBJECT_TERMINATOR =
                LabeledDataPrintStream.OBJECT_TERMINATOR;

     public LabeledDataInputStream( InputStream in )
          {
          super( in);
          }
          
     public LabeledData readLabeledData() throws IOException
          {
          StringBuffer theData = new StringBuffer();
          
          int nextChar = super.read();
          while (( nextChar != EOF ) && 
                         ( nextChar != OBJECT_TERMINATOR ))
               {
               theData.append( (char) nextChar);
               nextChar = super.read();
               }
          
          LabeledData recovered = new LabeledData();
          recovered.fromString( theData.toString() );
          return recovered;
          }
     }

Doc 27 Distributed Objects: A First Step Slide # 6

An Example of Reading and Writing


class Test
     {
     public static LabeledDataInputStream getFileInput(String fileName)
                                                        throws IOException
          {
          FileInputStream inputFile;
          BufferedInputStream bufferedFile;
          
          inputFile = new FileInputStream( fileName );
          bufferedFile = new BufferedInputStream( inputFile );
          return  new LabeledDataInputStream( bufferedFile );
          }
          


     public static LabeledDataPrintStream getFileOutput( 
                                        String fileName )      throws IOException
          {
          FileOutputStream outputFile;
          BufferedOutputStream bufferedFile;
          
          outputFile = new FileOutputStream( fileName );
          bufferedFile = new BufferedOutputStream( outputFile );
          return new LabeledDataPrintStream( bufferedFile );
          }


Doc 27 Distributed Objects: A First Step Slide # 7
     public  static  void  main( String  args[] ) throws Exception
          {
          LabeledData  mom = new LabeledData();
          mom.put( "hi", "mom");
          mom.put( "dinner", "when?");
          LabeledData  dad = new LabeledData();
          dad.put( "hi", "dad");
          
          LabeledDataPrintStream   cout;
          cout = getFileOutput( "LetterHome");

          cout.print( mom );
          cout.print( dad );
          cout.close();
          
          LabeledDataInputStream  cin;
          cin = getFileInput( "LetterHome" );
     
          LabeledData recoveredMom = cin.readLabeledData();
          LabeledData recoveredDad = cin.readLabeledData();
          System.out.println( recoveredDad.get( "hi"));
          }

Output
dad

Doc 27 Distributed Objects: A First Step Slide # 8
Now we can send LabeledData Objects
between Clients and Servers!

public DateServer( InputStream in, OutputStream out )
          {
          input = new LabeledDataInputStream(in);
          output = new LabeledDataPrintStream(out);
          }
     
     public void run(){
          try
               {
               LabeledData clientObject = input.readLabeledData();
               if ( inputLine.getData("command").equals( "date" ) )
                    {
                    Date now = new Date();
                    clientObject.put( "date" , now.toString() );
                    output.print( clientObject );
                    }
               input.close();
               output.close();
               }
          catch ( IOException howToHandleThis )
               {// A topic to be covered later     }
          }     
     }


Doc 27 Distributed Objects: A First Step Slide # 9

What about Writing/Sending Other Objects?

Interface and Writer


interface FromString
     {
     /**
      * Recreate the state of an obejct from a string
      */
     public void fromString( String obejctState) throws IOException;

     public String toString();
     }

class ObjectPrintStream extends PrintStream
     {
     public static final char OBJECT_TERMINATOR = '\003';
     
     public ObjectPrintStream( OutputStream output)
          {super( output );}
          
     public void print( FromString printMe )
          {
          LabeledData classType = new LabeledData();

          String className = printMe.getClass().getName();
          classType.put( "class", className);

          String toPrint = classType.toString() +  OBJECT_TERMINATOR
                     + printMe.toString() + OBJECT_TERMINATOR;

          super.print( toPrint );
          }
     }

Doc 27 Distributed Objects: A First Step Slide # 10

Reader

class ObjectInputStream extends FilterInputStream
     {
     private static final int EOF = -1;
     private static final char OBJECT_TERMINATOR = 
                    ObjectPrintStream.OBJECT_TERMINATOR;
     public ObjectInputStream( InputStream in )
          {
          super( in);
          }
          
     public FromString readLabeledData() throws IOException, 
          ClassNotFoundException, IllegalAccessException,
           InstantiationException
          {
          FromString recovered =  getObjectInstance();
          StringBuffer theData = new StringBuffer();
          
          int nextChar = super.read();
          while (( nextChar != EOF ) && 
                    ( nextChar != OBJECT_TERMINATOR ))
               {
               theData.append( (char) nextChar);
               nextChar = super.read();
               }
          
          recovered.fromString( theData.toString() );
          return recovered;
          
}


Doc 27 Distributed Objects: A First Step Slide # 11
Reader Continued

private FromString getObjectInstance()  throws IOException,
ClassNotFoundException,
                                                                      
IllegalAccessException, InstantiationException
          {
          StringBuffer classInfo = new StringBuffer();
          
          int nextChar = super.read();
          while ( nextChar != OBJECT_TERMINATOR )
               {
               classInfo.append( (char) nextChar);
               nextChar = super.read();
               }
          LabeledData classHash = new LabeledData();
          classHash.fromString( classInfo.toString() );
          
          Class objectClass = Class.forName( classHash.getData( "class"));
          return (FromString) objectClass.newInstance();
          
          }
     }


Doc 27 Distributed Objects: A First Step Slide # 12

Sample Class


class Sample implements FromString
     {
     private int myData;
     public void setMyData( int value )
          {
          myData = value;
          }
     
     public String toString()
          {
          LabeledData myState = new LabeledData();
          myState.put( "myData", String.valueOf( myData ) );
          return myState.toString();
          }
     
     public void fromString( String aState)  throws IOException
          {
          LabeledData myState = new LabeledData();
          myState.fromString( aState );
          String dataValue = myState.getData( "myData" );
          myData = (new Integer(dataValue)).intValue();
          }
     }


Doc 27 Distributed Objects: A First Step Slide # 13

Sample Test Program


class Test
     {
     public  static  void  main( String  args[] ) throws Exception
          {
          Sample someData = new Sample();
          someData.setMyData( 5);
          ObjectPrintStream   cout;
          cout = getFileOutput( "DataFile");

          cout.print( someData );
          cout.close();
          
          ObjectInputStream  cin;
          cin = getFileInput( "DataFile" );
     
          FromString recoveredData = cin.readLabeledData();
          System.out.println( recoveredData);
          }
     public static ObjectInputStream getFileInput( String fileName )
throws IOException
          {
          // nearly the same as first example
          }
          
     public static ObjectPrintStream getFileOutput( String fileName )
throws IOException
          {
          // nearly the same as first example
          }
     }