%% -*- mode: LaTeX -*-
%%
%% Copyright (c) 2002 University of Utah and the Flux Group.
%% All rights reserved.
%% This file is part of the JanosVM documentation.
%% 
%% Permission to use, copy, modify, distribute, and sell this
%% documentation for any purpose is hereby granted without fee,
%% provided that the above copyright notice(s) appear in all copies.
%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Using jsihey}
\label{cha:Using jsihey}

The \jsihey{} command line tool is designed to be the lowest common denominator
for sending any type of \JSI{} message, over any type of communication medium,
and dealing with the reply.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Argument Format}
\label{sec:Argument Format}

The arguments to \jsihey{} are given in a near English syntax similar to
AppleScript's \jsiheyid{tell} and BeOS's \jsiheyid{hey} forms.  The style tries
to simulate a natural conversation between the user and the target object.  For
example, ``hey photoshop create window with file picture.jpg'' is a little
easier to understand than ``hey photoshop window.create('picture.jpg')''.  In
addition, the style doesn't require \jsihey{} to fully understand the structure
of the destination object, thus allowing it to be used for any \JSI{} enabled
application.

The overall argument format is:
\begin{itemize}
  \item The target program's address.

  \item A ``verb'' that describes what action to take.

  \item A ``specifier stack'' that routes the message to the target object.

  \item An optional argument list given as identifier/value pairs.

  \item And, an optional reply action.
\end{itemize}

In addition, \jsihey{} will print out a pseudo-\BNF{} usage statement if no
arguments are given, if you'd like a more structured description of the
syntax.
% XXX put the bnf in an appendix?


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Target Program}
\label{subsec:Target Program}

The target program's address is a formatted string starting with the protocol
type, followed by a colon and the protocol specific address.  For example, to
communicate with a program running on the same machine and listening on \TCP{}
port 10000, you would use ``tcp:localhost/10000''.  There are only a few
communication implementations at the moment:

\begin{optionlist}
  \item[tcp]
  %
  Uses \TCPIP{} to communicate with the target program.  Format:
  \jsiheyid{tcp:<hostname>/<port>}.

  \item[file]
  %
  Uses a pair of files, \file{<prefix>.to} and \file{<prefix>.from}, to
  communicate with the target program.  Format: \jsiheyid{file:<prefix>}.
  Note: Unlike \TCP{}, this protocol cannot support more than one concurrent
  client, so you'll need to create extra files if you wish to do this.

  \item[plex:udp]
  %
  The \jsiheyid{plex} protocol is used to multiplex \JSI{} streams over a
  single unreliable data link.  In this case, \UDP{}, however, any unreliable
  communication link would suffice.  Format:
  \jsiheyid{plex:udp:<hostname>/<port>}.  Note: This is still somewhat
  experimental and is only used when communicating with a \JanosVM{} running on
  a bare machine.
\end{optionlist}

Since the above address specification can be a little wordy, you can use a
``registered'' name in its place.  The ``registered'' name is simply a
directory in 
\file{$JSI_ROOT/registry}
% $ font-lock silliness
that contains a \file{jsi.id} file, where
\file{$JSI_ROOT}
% $
defaults to 
\file{$HOME/.janosvm}.
% $
In the case of \JanosVM{}, you can automatically register a name using the
\option{-name} option or you can use the \jsiregister{} script:

\begin{transcript}
[stewie@home ~] janosvm -jsiprovider tcp:localhost/9000 -name jvminstance
[stewie@home ~] jsiregister jvminstance jsi.id tcp:localhost/9000
\end{transcript}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Message Verb}
\label{subsec:Message Verb}

After the target program value, the rest of the arguments are used to build the
request message.  The first value is a ``verb'' that determines the action to
be taken.  Currenty, \jsihey{} understands the following verbs:

\begin{optionlist}
  \item[getsuites]
  %
  Get the set of \jsiheyid{suites} for a given object.  Each \jsiheyid{suite}
  contains information about an object in the program, including what verbs it
  can be used with and their arguments.  So, if you need help interacting with
  a program, this is the first place to look.

  \item[list]
  %
  List any objects contained within another object.

  \item[get]
  %
  Get the value of an object.

  \item[set]
  %
  Set the value of an object.

  \item[create]
  %
  Create a new object with the given arguments.

  \item[delete]
  %
  Delete an object.

  \item[execute]
  %
  Execute a method on an object with the given arguments.

  \item[shutdown]
  %
  Shutdown the target program.
\end{optionlist}

Several of the verbs, \jsiheyid{getsuites}, \jsiheyid{list}, and
\jsiheyid{shutdown}, can be used without additional arguments since they
operate directly on the root of the program's object tree.  However, most
require a real object to process them properly, which brings us to the next
part of the argument list and message, the ``specifier stack''.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Specifier Stack}
\label{subsec:Specifier Stack}

The verb determines what action to take, but doesn't indicate which object
should take that action, this is the job of the ``specifier stack''.  The stack
contains a list of specifiers that describe the path through the program's
object tree to the desired destination.  Each specifier in the stack is made up
of an object type or name and an optional identifier, for example, ``window
1''.  Finally, you aggregate the specifiers into a stack using the
\jsiheyid{of} keyword.  For example, ``button ok of window 1'' would build a
stack that addressed the ``ok'' button inside of window number one.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Identifier Pairs}
\label{subsec:Identifier Pairs}

In the case of the \jsiheyid{create} and \jsiheyid{execute} verbs they can take
an optional list of identifier/value pairs to be used as arguments.  To add a
list to the message simply add \jsiheyid{with} to the end of the specifier
stack and then write the identifier name and value separated by a space or
equals sign.  You can add the same identifier more than once to create array.
For example:

\begin{transcript}
[stewie@home ~] jsihey jvm create team with name lois
[stewie@home ~] jsihey jvm create team with name=peter
\end{transcript}

The \jsiheyid{set} verb also requires an argument, however, the identifier is
implicit so only the value needs to be given after a \jsiheyid{to} keyword.
For example:

\begin{transcript}
[stewie@home ~] jsihey raygun set level to stun
\end{transcript}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Reply Actions}
\label{subsec:Reply Actions}

Once the request message has been constructed and sent off to the target
program and object, \jsihey{} can react in a number of different ways to the
reply message.  The default response is simply to wait for a response and print
out the contents of the reply message.  However, you can change this by using
the \jsiheyid{then} keyword followed by one of these actions:

\begin{optionlist}
  \item[print]
  %
  Print out a formatted string that can use values from the reply message.  The
  format string can contain plain text, formatting escapes, and directives
  which print out values contained in the reply message.  An escape starts with
  a backslash and is followed by a t, for tab, or n, for a line feed.  Each
  directive starts with a \jsiheyid{%(} and is followed by the name of a value
  in the message, an optional range if the value occurs more than once, then a
  colon followed by a regular printf format conversion, and finally, the
  closing parentheses.  For example, the format, \jsiheyid{%(result[1]:d)}
  would print out an integer with the value of the second instance of
  \jsiheyid{result} in the reply message.  In addition, it is possible to print
  out a range of indeces separated by a string.  This is done by using a pair
  of periods to separate the starting index, a separator string, and the final
  index.  For example, \jsiheyid{%(result[1.} \jsiheyid{.5])}, would print out
  the second through sixth values of \jsiheyid{result} separated by spaces.
  Also, the range values can be left out to imply the first and last indeces.

  % XXX Is the above too much?

  \item[forinstance]
  %
  Walks over all of the instances of an identifier in the message and
  repeatedly executes the rest of the actions on the command line.  The
  arguments to \jsiheyid{forinstance} are a temporary variable name used to
  store the current index, the \jsiheyid{in} keyword, the message identifier to
  loop over, and finally, the action to perform on each iteration.

  \item[nothing]
  %
  Wait for the reply, but don't print anything, even if the reply is an error.

  \item[ignore]
  %
  Dont wait for the reply, return immediately.  Note: This is the default
  action for the shutdown message since it isn't expecting a reply.
\end{optionlist}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Interim I/O Messages}
\label{subsec:Interim I/O Messages}

The \JSI{} protocol supports what is known as ``interim messages'' that can be
transmitted while an object is trying to satisfy a request.  For example, a
request to the stdout object can send an interim message to an object on the
requesting side requesting the data to print.  The option to allow objects to
coordinate themselves without user input can be quite handy, however,
\jsihey{}'s primitive nature leads it to only support a minor amount of
interaction.  Therefore, \jsihey{} implements three objects named ``in'',
``out'', and ``err'' which represent the standard I/O files.  With these
objects you should be able to do something like the above example using
\janosvm{}:

\begin{transcript}
[lsimpson@utah ~] jsihey jvm create file with name test
Normal reply:
  result = `ok'
[lsimpson@utah ~] jsihey jvm execute write of file test
Hello World!
^D
Normal reply:
  result = `ok'
[lsimpson@utah ~] jsihey jvm execute read of file test
Hello World!
Normal reply:
  result = `ok'
\end{transcript}

As you can see, we created a file and executed it's write method.  Since no
data was given to write, the \JVM{} sent an interim message to \jsihey{}'s
``in'' object asking for the data to write.  And, a similar process occurred
when we read the file, except the message was sent to the ``out'' object.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Return Values}
\label{subsec:Return Values}

When \jsihey{} is finished processing messages it will exit with one of these
values:

\begin{optionlist}
  \item[0]
  %
  Everything worked fine.

  \item[10]
  %
  The reply message was an error.

  \item[20]
  %
  There was a communication error.

  \item[30]
  %
  There was a usage error.

  \item[100]
  %
  There was an internal error.
\end{optionlist}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Example jsihey usage}
\label{sec:Example jsihey usage}

List the root properties of the \JanosVM{} listening on \TCP{} port 14000 of
the local machine:

\begin{transcript}
[bubbles janosvm] jsihey tcp:localhost/14000 list
Normal reply:
  result = `err'
  result = `out'
  ...
\end{transcript}

Getting the suites of the teams object:

\begin{transcript}
[bubbles janosvm] jsihey tcp:localhost/14000 getsuites of teams
Property:  name
  Supported verbs:  get
Usage (arguments, if any, followed by a description):
  The name of the team

Property:  description
  Supported verbs:  get, set
Usage (arguments, if any, followed by a description):
  A description of the contents of the team

...
\end{transcript}

Create a new team with the name ``THX'' in the \JanosVM{} listening on \UDP{}
port 1138 and then print the resulting team identifier.

\begin{transcript}
[bubbles janosvm] jsihey plex:udp:townsville/1138 create team with name "THX" \
  then print "%(result:d)"
5
\end{transcript}

Delete the newly created team and don't do anything with the reply:

\begin{transcript}
[bubbles janosvm] jsihey plex:udp:townsville/1138 delete team 5 then nothing
\end{transcript}

Turn on the xprofiler:

\begin{transcript}
[bubbles janosvm] jsihey janosvm set xprofiler to on
\end{transcript}

Get the current value of the xprofiler:

\begin{transcript}
[bubbles janosvm] jsihey janosvm get xprofiler
Normal reply:
  result = `on'
\end{transcript}

Shutdown the \JVM{}:

\begin{transcript}
[bubbles janosvm] jsihey janosvm shutdown
\end{transcript}

List all of the agents of a covert spy organization:

\begin{transcript}
[sloane@sd6 ~] jsihey db list agents
Normal reply:
  result = `Arvin Sloane'
  result = `Sydney Bristow'
  result = `Jack Bristow'
  ...
\end{transcript}

Format the above list:

\begin{transcript}
[sloane@sd6 ~] jsihey db list agents then \
  forinstance lpc in result print ``Agent #%(lpc:d): %(name[lpc]:s)\n''
Agent #1: Arvin Sloane
Agent #2: Sydney Bristow
Agent #3: Jack Bristow
...
\end{transcript}

Another formatting of the above list:

\begin{transcript}
[sloane@sd6 ~] jsihey db list agents then print ``%(name[.\n.]:s)\n''
Arvin Sloane
Sydney Bristow
Jack Bristow
...
\end{transcript}

Executing the domination property of the world object:

\begin{transcript}
brain@acmelabs ~> jsihey janosvm execute domination of world
Error:
  why = `Pinky'
\end{transcript}

Executing the domination property of the world object using plan B:

\begin{transcript}
brain@acmelabs ~> jsihey janosvm execute domination of world with plan B
Error:
  why = `Pinky'
\end{transcript}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% End of file.

