[Isolate-interest] Strawman 7 notes

Pete Soper Pete@Soper.US
Tue, 22 Jun 2004 22:59:38 -0400


I neglected to include these notes (mostlly written by Richard 
Holdsworth) to go along with the "still mostly empty" javadoc. Here they 
are:
-----------------------------
//
// JSR-121 "Strawman 7" proposed APIs for J2ME/CLDC J2ME/CDC and J2SE
//
// September 11, 2003
//

/**
CORE API:
---------
*/

package  javax.isolate;

interface  Message  { }

public final class  Isolate  implements Message {
     public  Isolate(String mainClass, String[] mainArgs)  {}
     public  Isolate(IsolateParameters params)  {}
     public static Isolate  currentIsolate()  {}
     public static Link[]  currentIsolateStartLinks()  {}
     public static IsolateParameters  currentIsolateParameters()  {}
     public Link  newStatusLink()  {}
     public void  start(Link[] links) throws IsolateStartException  {}
     public void  exit(int status)  {}
     public void  halt(int status)  {}
     public StatusMessage.Type getStatus() {}
     public boolean  equals(Object o)  {}
     public int  hashCode()  {}
}

public class  CompositeMessage  implements Message {
      CompositeMessage()  {}
     public Message[]  getComposite(Message[] msgs)  {}
     public static CompositeMessage  newCompositeMessage(Message[] msgs)  {}
}

public class  DataMessage  implements Message {
      DataMessage()  {}
     public long  size()  {}
     public byte[]  getData(byte[] b)  {}
     public void  getData(int src_position, byte[] dst, int 
dst_position, int length)  {}
     public static DataMessage  newDataMessage(byte[] b)  {} // convenience
     public static DataMessage  newDataMessage(byte[] b, int off, int 
len)  {}
}

public class  StatusMessage  implements Message {
      StatusMessage()  {}
     public final class ExitReason {
       private ExitReason() {}
       public final ExitReason IMPLICIT_EXIT = new ExitReason();
       public final ExitReason OTHER_EXIT = new ExitReason();
       public final ExitReason OTHER_HALT = new ExitReason();
       public final ExitReason SELF_EXIT = new ExitReason();
       public final ExitReason SELF_HALT = new ExitReason();
       public final ExitReason UNCAUGHT_EXCEPTION = new ExitReason();
     }
     public final class Type {
       private Type() {}
       public final Type  STARTING = new Type();
       public final Type  EXITING = new Type();
       public final Type  TERMINATED = new Type();
     }
     public ExitReason  getExitReason()  {}
     public Type  getType()  {}
     public int  getExitStatus()  {}
     public Isolate  getIsolate()  {}
     public boolean  equals(Object o)  {}
     public int  hashCode()  {}
}

public abstract class  Link  implements Message {
      Link()  {}
     public static Link  newLink(Isolate sender, Isolate receiver)  {}
     public abstract Message  receive() throws IOException;
     public abstract void  send(Message msg) throws IOException;
     public abstract void  close() throws IOException;
     public abstract boolean  isOpen();
     public abstract boolean  isSender(Isolate i);
     public abstract boolean  isReceiver(Isolate i);
     public boolean  equals(Object o)  {}
     public int  hashCode()  {}
}

public class  IsolateParameters  implements Message {
     public  IsolateParameters(String classname, String[] mainArgs)  {}
     public  void setContext(String name, String value)  {}
     public  String getContext(String name)  {}
}

public class  IsolateStartException  extends Exception {
   public  IsolateStartException()  {}
   public  IsolateStartException(String detail)  {}
}

/**
CDC ADDITIONAL API:
-------------------
*/

package  javax.isolate.tbd;

import  java.security.BasicPermission;

public class  IsolatePermission  extends BasicPermission {
     public  IsolatePermission(String name)  {}
     public  IsolatePermission(String name, String actions)  {}
}

public class  ObjectMessage  implements Message {
      ObjectMessage()  {}
     public Object  getObject()  {}
     public static ObjectMessage  newObjectMessage(Object o)  {}
}

/**
SE ADDITIONAL API:
------------------
*/

package  javax.isolate.io

import  java.io.InputStream;
import  java.io.OutputStream;
import  java.io.IOException;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.RandomAccessFile;
import  java.net.Socket;
import  java.net.ServerSocket;
import  java.net.DatagramSocket;
import  javax.isolate.Link;
import  javax.isolate.Message;
import  javax.isolate.DataMessage;

public interface  IOMessage  extends Message { }

public class  FileMessage  implements IOMessage {
      FileMessage()  {}
     public FileInputStream  getFileInputStream()  {}
     public FileOutputStream  getFileOutputStream()  {}
     public RandomAccessFile  getRandomAccessFile()  {}
     public static FileMessage 
newFileInputStreamMessage(FileInputStream f)  {}
     public static FileMessage 
newFileOutputStreamMessage(FileOutputStream f)  {}
     public static FileMessage 
newRandomAccessFileMessage(RandomAccessFile f)  {}
}

public class  SocketMessage  implements IOMessage {
      SocketMessage()  {}
     public Socket  getSocket()  {}
     public DatagramSocket  getDatagramSocket()  {}
     public ServerSocket  getServerSocket()  {}
     public static SocketMessage  newSocketMessage(Socket s)  {}
     public static SocketMessage 
newDatagramSocketMessage(DatagramSocket s)  {}
     public static SocketMessage  newServerSocketMessage(ServerSocket s)  {}
}

public class  DataMessageOutputStream  extends OutputStream {
     public  DataMessageOutputStream()  {}
     public  DataMessageOutputStream(int size)  {}
     public  DataMessageOutputStream(Link l) throws IOException  {}
     // OutputStream
     public void  close() throws IOException  {}
     public void  flush() throws IOException  {}
     public void  write(byte[] b) throws IOException  {}
     public void  write(byte[] b, int off, int len) throws IOException  {}
     public void  write(int b) throws IOException  {}
     // conversion
     public DataMessage  readDataMessage() throws IOException  {}
}

public class  DataMessageInputStream  extends InputStream {
     public  DataMessageInputStream()  {}
     public  DataMessageInputStream(DataMessage m)  {}
     public  DataMessageInputStream(Link l) throws IOException  {}
     // InputStream
     public int  available() throws IOException  {}
     public void  close() throws IOException  {}
     public void  mark(int readlimit)  {}
     public boolean  markSupported()  {}
     public int  read() throws IOException  {}
     public int  read(byte[] b) throws IOException  {}
     public int  read (byte[] b, int off, int len) throws IOException  {}
     public void  reset() throws IOException  {}
     public long  skip(long n) throws IOException  {}
     // conversion
     public void  writeDataMessage(DataMessage m) throws IOException  {}
}

public class  IOIsolateParameters  extends IsolateParameters {
     public  IOIsolateParameters(String mainClass, String[] mainArgs) 
{super(null,null);}
     public void  setIn(IOMessage in)  {}
     public void  setOut(IOMessage out)  {}
     public void  setErr(IOMessage err)  {}
     public void  setName(String name)  {}
     public IOMessage  getIn()  {}
     public IOMessage  getOut()  {}
     public IOMessage  getErr()  {}
     public String  getName()  {}
}

public class  LinkClosedException  extends IOException {
   public  LinkClosedException()  {}
   public  LinkClosedException(String detail)  {}
}

/**
SE additional API: java.
------------------
*/

package  javax.isolate.nio;

import  java.nio.ByteBuffer;
import  java.nio.channels.SocketChannel;
import  java.nio.channels.ServerSocketChannel;
import  java.nio.channels.DatagramChannel;
import  java.nio.channels.FileChannel;
import  java.nio.channels.Pipe.SinkChannel;
import  java.nio.channels.Pipe.SourceChannel;

public class  ByteBufferMessage  implements Message {
      ByteBufferMessage()  {}
     public ByteBuffer  getByteBuffer()  {}
     public ByteBufferMessage  newByteBufferMessage(ByteBuffer b)  {}
}

public class  ChannelMessage  implements IOMessage {
      ChannelMessage()  {}
     public SocketChannel  getSocketChannel()  {}
     public DatagramChannel  getDatagramChannel()  {}
     public ServerSocketChannel  getServerSocketChannel()  {}
     public FileChannel  getFileChannel()  {}
     public Pipe.SinkChannel  getPipeSinkChannel()  {}
     public Pipe.SourceChannel  getPipeSourceChannel()  {}
     public static ChannelMessage  newSocketChannelMessage(SocketChannel 
c)  {}
     public static ChannelMessage 
newDatagramChannelMessage(DatagramChannel c)  {}
     public static ChannelMessage 
newServerSocketChannelMessage(ServerSocketChannel c)  {}
     public static ChannelMessage  newFileChannelMessage(FileChannel c)  {}
     public static ChannelMessage 
newPipeSinkChannelMessage(Pipe.SinkChannel c)  {}
     public static ChannelMessage 
newPipeSourceChannelMessage(Pipe.SourceChannel c)  {}
}

/**
SE additional API: javax.isolate.util
------------------
*/

package  javax.isolate.util;


import  javax.isolate.Link;
import  javax.isolate.Message;
import  javax.isolate.CompositeMessage;
import  javax.isolate.DataMessage;
import  javax.isolate.Isolate;
import  javax.isolate.StatusMessage;
import  javax.isolate.io.FileMessage;
import  javax.isolate.io.ObjectMessage;
import  javax.isolate.io.SocketMessage;
import  javax.isolate.nio.ByteBufferMessage;
import  javax.isolate.nio.ChannelMessage;
import  java.io.IOException;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.RandomAccessFile;
import  java.net.Socket;
import  java.net.ServerSocket;
import  java.net.DatagramSocket;
import  java.nio.ByteBuffer;
import  java.nio.channels.SocketChannel;
import  java.nio.channels.ServerSocketChannel;
import  java.nio.channels.DatagramChannel;
import  java.nio.channels.FileChannel;
import  java.nio.channels.Pipe.SinkChannel;
import  java.nio.channels.Pipe.SourceChannel;


public interface  MessageHandler  {
     public void  messageReceived(MessageDispatcher d, Link l, Message m);
     public void  receiveFailed(MessageDispatcher d, Link l, Throwable t);
}

public class  MessageDispatcher  implements Runnable {
     public  MessageDispatcher()  {}
     public void  add(Link l, MessageHandler h)  {}
     public void  remove(Link l)  {}
     public void  run()  {}
     public void  shutdown()  {}
}

public abstract class  MessageVisitor  {
     public  MessageVisitor()  {}
     public void  acceptMessage(Message m) throws IOException  {}
     // core message types
     public void  visitIsolate(Isolate i)  {}
     public void  visitLink(Link l)  {}
     public void  visitComposite(CompositeMessage m)  {}
     public void  visitData(DataMessage m)  {}
     public void  visitStatus(StatusMessage m)  {}
     // serial message types
     public void  visitObject(ObjectMessage m)  {}
     // nio bytebuffers
     public void  visitByteBuffer(ByteBufferMessage m)  {}
     // desc message types
     public void  visitSocketChannel(ChannelMessage m)  {}
     public void  visitDatagramChannel(ChannelMessage m)  {}
     public void  visitServerSocketChannel(ChannelMessage m)  {}
     public void  visitFileChannel(ChannelMessage m)  {}
     public void  visitPipeSinkChannel(ChannelMessage m)  {}
     public void  visitPipeSourceChannel(ChannelMessage m)  {}
     public void  visitSocket(SocketMessage m)  {}
     public void  visitDatagramSocket(SocketMessage m)  {}
     public void  visitServerSocket(SocketMessage m)  {}
     public void  visitFileInputStream(FileMessage m)  {}
     public void  visitFileOutputStream(FileMessage m)  {}
     public void  visitRandomAccessFile(FileMessage m)  {}
}

/**********

Notes
-----
- The marker interface for link-sendables is called Message. Other possible
   names for the interface: LinkTransmittable, Sendable, 
IsolateTransferrable,
   LinkSendable, LinkMessage.
- Few classes are final. Package constructors are used to prevent user
   extension. This is less limiting on future expansion, and allows for a
   hierarchy of Message types (e.g. IOMessage).
- Renamed IsolateEvent to StatusMessage to fit with the Message 
terminology and
   to avoid the 'Event types should extend EventObject' complaint.
- The DataMessage includes size(), getData(byte[]...) a 
create-from-subarray
   method. These allow copying to and from user-provided buffers so new 
arrays
   do not have to be created by the API or the user.
- ClosedLinkException is moved to 'io' and only IOException is thrown by 
the
   Link methods. For CLDC just the basic IOException class is thrown, 
for the
   other platforms the subclass is actually thrown.
- IsolateResourceError is removed. OutOfMemoryError can be thrown 
instead. If
   reinstated, it should probably extend VirtualMachineError and live in 
the
   util package.
- SerializableMessage renamed to ObjectMessage and placed in the io 
package.
   This class is used for potentially optimised object transfer.
- MessageConverters changed to extend InputStream and OutputStream (and 
renamed
   as such) and have new constructors that take Link. This fully links
   DataMessages in with the IO API by hiding Link.send() and 
Link.receive().
   Manual driving from DataMessages is still supported, but only with
   no-parameter constructors.  Need to consider how stream is segmented 
into
   DataMessages, just on flush() or should there be a maximum transfer size?
- {Data|Object}{In|Out}put interfaces removed from Converter/Stream 
classes, so
   there is no exposure of standard to-serialized-form operations in 
this API.
- Have put ByteBuffer into a separate class.
- IOMessage is an extension interface of IOMessage that marks a DBD type 
("Descriptor Bearing Doober", a link message "wrapping" a filesystem or 
network class instance that typically contains an underlying OS 
descriptor of some sort).
- Reasonable type-safety is imposed on the IOBindings by using the 
IOMessage
   interface - it now only implements the DBD types (is ByteBuffer 
FD-backed?).
- The basic IOMessage type is moved into the io package, along with 
FileMessage
   and SocketMessage, which means CDC system need to support DBD-passing 
for
   file and socket FDs.
- LinkSerializationException is removed - java.io.NotSerializableException
   (which is an IOException) can be thrown instead.
- IsolatePermission is in security subpackage as it doesn't fit in 'io'. 
Move
   back if 'serial' is reinstated.
- Renamed Visitor, Dispatcher and Dispatcher.Listener based on 'Message' 
rather
   than 'IsolateMessage'.
- MessageListener is renamed MessageHandler as it does not follow the
   EventListener pattern, so a different name is suitable.  Not an inner
   interface as previously as there seems no advantage to that, and it 
is an
   unfamiliar pattern.
- The acceptVisitor() method is moved to the Visitor class itself, as any
   Message type could be visited.  This means the Visitor implementation 
must
   have some internal magic to identify Message type. It throws 
IOException to
   cover serialization exceptions.
- The visitXXX() methods do type conversions to the correct Message type.
- Removed TransientPreferences and String[][] context types in favour of an
   extendable IsolateParameters object. Alternative considered was a simple
   Hashtable.
- IsolateParameters has Message interface so it can be transferred between
   Isolates on CLDC.
- IOBoundIsolate removed and an extended IOIsolateParameters object used.
- The IOBoundIsolateParameters class is now in isolate.io, so only NIO 
APIs are
   left in isolate.nio.
- Isolate made final - this should prevent a lot of API abuses.
- Changed DataMessage.getData and CopositeMessage getComposite to take an
   optional array parameter to be filled if possible. See
   Vector.toArray(Object[]);
- Looked at DataMessage again - using System.arraycopy()-lookalike for 
reading.
   Reduces method count slightly.
- Flagged a small number of methods in core API as 'convenience' which 
can be
   removed without loss of functionality.
- Sep 10 EG meeting resulted in 1) sticking with Message interface, 2)
   collapsing Isolate state query methods into one "getStatus" method and 3)
   grouping ObjectMessage with IsolatePermission in javax.isolate.tbd 
(formerly
   called javax.isolate.security).
- The Isolate.getStatus method CANNOT take advantage of enumeration 
support in
   J2SE 1.5 as this package is intended to serve J2ME users too.
*********/