Many of the classes you've been using to create channels and plug-ins throughout this book have been part of the standard Marimba APIs. Both Castanet and Bongo come with a suite of new Java classes that not only help implement the Castanet and Bongo tools themselves, but can help you create channels, plug-ins, and other tools.
This chapter provides a general overview of many of the classes contained in the Marimba classes and tells you in which library they are located. I'm not going to cover every possible Marimba class here–many of the classes in the marimba.gui package, for example, are covered in detail in the Official Marimba Guide To Bongo. And I'm going to go into more detail about the classes specific to Castanet and channel development than I am for other classes. After reading this chapter, however, you should have a good idea of all the possible classes and how they can be used.
For more information on any of these classes, API documentation is available online from the Marimba site at http://www.marimba.com, as a set of channels from trans.marimba.com, and on the CD for this book. Official Marimba Guide To Bongo also contains documentation for many of these classes.
The packages you've used most often throughout this book, and the classes you will use time and time again as you develop your own channels are the classes contained in the marimba.channel package. These classes include the interfaces for creating applications and for managing the application context; they also include classes for treating applets as channels and for incorporating Bongo presentations into channels.
The marimba.channel classes are split amongst multiple .zip files, which you'll need to add to your CLASSPATH or to the search path for your development environment before you can use them. The Application and ApplicationContext interfaces are contained in the marimba.zip file for either Bongo or the Castanet Transmitter. For the other four channel classes, you'll need Bongo's bongo.zip library, or the Transmitter's transmitter.zip class.
The Application Interface
The Application interface defines the standard channel methods and events; implement this interface in your own classes to convert them into channels. The Application interface defines four event types for handling updates:
The Application interface also defines the following methods:
public abstract void handleEvent(Event) process events.
public abstract void setContext(ApplicationContext) is called at startup with an instance of the current application context, this method should save that context and perform any very basic initialization tasks.
public abstract void start() is called when the channel is first started.
public abstract void stop() is called when the channel is stopped.
The ApplicationContext Interface
The ApplicationContext interface defines the environment in which the channel runs and provides a mechanism for accessing Castanet Tuner and channel features. An object that responds to the ApplicationContext methods is passed to the channel through the setContext() method; usually you'll store that object in an instance variable and call its methods later on as the channel executes.
The ApplicationContext defines the following methods:
public abstract boolean appendLog(byte[]) stores an array of bytes as a channel log entry, to be sent to the transmitter as feedback data during the next update. Returns false only if there was an error writing the log entry.
public abstract boolean appendLog(String) is the same as the previous method, except the argument is String.
public abstract boolean channelFileExists(String) returns true if the given relative path exists in the channel.
public abstract URL getBase() returns the base URL for this channel.
public abstract String getChannelDirectory() is an older version of getDataDirectory; this method is obsolete and will be removed from a later release.
public abstract String getChannelName() returns the full name of the channel.
public abstract String getChannelStatus(String) returns the current channel status (one of "unsubscribed", "subscribed", "running").
public abstract URL getCodeBase() returns the URL of the directory for the channel's code (might be the same as getBase(), used most often with applets).
public abstract URL getDataBase() returns the URL for the data directory for this channel, which be used to store persistent local files.
public abstract String getDataDirectory() returns the path name to the data directory for this channel.
public abstract String getParameter(String) returns the value of an application parameter, as stored in the properties.txt file for the channel (and set in the Castanet Publish).
public abstract Updates getPendingUpdates() returns an Updates object representing the changes that will be made to the channel in the course of the update. Returns null if there are no updates to be made.
public abstract byte[] getProfile() returns an array of bytes representing the profile data for this channel. Will return empty of there is no profile data for this channel.
public abstract String getServerName() returns the name of the server (transmitter) for this channel. The transmitter name is of the form hostname:port.
public abstract void installData(String) requests the tuner to install all or part of newly arrived data. The argument is the relative path name of the file or directory to install.
public abstract String[] listChannelDirectory(String) returns an array of strings representing the names of files in the given directory. To list the entire channel, use "." as the argument. Returns null if the path does not exist.
public abstract String[] listChannels() returns an array of strings representing all the subscribed channels.
public abstract long publishTime() returns the time that has passed since this channel was last published.
public abstract void removeChannel(String) removes this channel.
public abstract void restart() restarts the channel.
public abstract boolean setProfile(byte[]) stores the array of bytes as profile data for this channel, to be sent to the transmitter as feedback data during the next update. Returns false only if there was an error writing the profile.
public abstract void startChannel(String, String) starts some other channel. The first argument is the same of the transmitter; the second is the name of the channel.
public abstract void stop() stops the channel.
public abstract void subscribeChannel(String, String) subscribes to a channel (don't start it). The arguments are the name of a transmitter and the name of the channel.
public abstract void unsubscribeChannel(String) unsubscribes from the named channel.
public abstract void update() updates the channel.
public abstract long updateTime() returns the time that has passed since this channel was last updated.
Updates
The Updates class represents the changes that will be made to the channel as part of an update. You can get an instance of this class using the getPendingUpdates() method from the application context. Using these methods in the Updates class, you can get a collection of strings representing path names to files that will be created, deleted, or changed as part of the update.
public Enumeration getDeletes() returns an Enumeration object, consisting of Strings which represent paths to any files which will be deleted as part of this update.
public Enumeration getCreates() returns an Enumeration object, consisting of Strings which represent paths to any files that will be created as part of this update (new channel files).
public Enumeration getUpdates() returns an Enumeration object, consisting of Strings that represent paths to any files which will change as part of the update.
ApplicationFrame is a subclass of the standard java.awt.Frame class that implements a basic form of the Application interface. You can use this class to implement your own channels.
In addition to the methods defined by both the java.awt.Frame class and the Application interface, ApplicationFrame provides the instance variable context, which holds the application context for this channel, and the following methods:
public void notifyAvailable(String) is called in response to the DATA_AVAILABLE_EVENT event. The argument is the path name to the top-level directory that needs installing. By default, this method calls context.restart() if the Data Available property is set to restart, and context.install is the property is set to install.
public void notifyInstall(String) is called in response to the DATA_INSTALL_EVENT event. No default implementation.
ApplicationPlayerFrame
ApplicationPlayerFrame is a subclass of the marimba.gui.PlayerFrame class that implements the Application interface. Use it to create channels that use Bongo presentations for their user interface.
ApplicationPlayerFrame supports all the PlayerFrame methods, all the Application methods, and also has the same base implementation as ApplicationFrame.
AppletContext and AppletViewer
The AppletContext interface extends the java.applet.AppletContext interface and is used to gain access to the application interface when applets are run as channels. Use the getApplicationContext() method to get that context object from inside an applet.
AppletViewer is a of ApplicationFrame that implements AppletContext and java.applet.AppletStub. It's used by the Castanet Tuner to play applets as channels and to support most of the common applet context methods (showDocument(), showStatus(), and so on).
The classes in the marimba.plugin package are used to create transmitter plug-ins, including the standard Plugin class and the RequestContext interface, which provides information about the update reqeust the plug-in is processing.
The marimba.plugin classes are available only in the transmitter.zip class that comes with the Castanet Transmitter. You'll need to add that file to your CLASSPATH or to the search path for your development environment before you can use them.
Plugin
The Plugin class provides the basic behavior for a transmitter plug-in; subclass this class to create your own transmitter plug-ins. Your class will be instantiated when an update request is made to your channel; with an object that supports the RequestContext interface that gets passed along in the processRequest() method you can get information and data from that update reqeust and process it.
When you subclass the Plugin class, you'll generally override three methods: init(), destroy(), and processRequest().
The Plugin class provides four static variables for setting the disposition of files that you add to the channel's index using addFile (you learned about all these dispositions in Chapter 12, "Creating Transmitter Plug-Ins"):
The Plugin class also provides these methods:
NoteThis is not a complete list of methods in the Plugin class. Many standard Plugin methods are intended to be called by the transmitter to start or to interact with the plug-in and are not useful to you for your subclasses. See the API documentation for the full set of methods.
public Checksum calculateChecksum(byte[]) returns a checksum for the array of bytes.
public Checksum calculateChecksum(String) returns a checksum for the file referred to by the argument (a relative path to a channel file).
public void destroy() is called when the plug-in object is unloaded. Override this method to clean up after your plug-in.
public File getChannelFile(String) returns a File object representing the path to a channel file.
public String getChannelName() returns the name of the channel this plug-in operates on.
public File getDataFile(String) returns a file object pointing to the path name for the plug-in's local data directory. You can safely read and write files to this directory.
public Vector getLogEntries(RequestContext) returns all the log entries sent to the transmitter as part of the request.
public void init() is called by the transmitter when the plug-in is first started. Override to provide your own initialization behavior.
public void processRequest(RequestContext) processes a subscribe or update reqeust for this channel. Override this method to process logging or profile data or to customize a channel.
public void processUnsubscribe(RequestContext) processes an unsubscribe reqeust for this channel. There will be no profile data, nor will any data be sent back to the tuner.
RequestContext
The RequestContext interface defines methods that allow a plug-in to get information about the channel making and update or subscribe request. Usually those methods are used in the Plugin class, which is passed an instance of RequestContext object by the transmitter.
The RequestContext interface provides the following methods:
public abstract void addFile(String, byte[], int) throws IOException adds the file data in the byte array to the channel file list with the name given by the string argument, and with the given integer file disposition.
public abstract void addFile(String, byte[], Checksum, int) throws IOException is the same as the previous method but also allows you to specify the checksum of the data.
public abstract void addFile(String, File) throws IOException adds the file referred to by the File to the file list with the path name given in the string argument.
public abstract void addFile(String, File, Checksum) throws IOException is the same as the previous method but also allows you to specify the checksum of the file.
public abstract void deleteFile(String) deletes the specified file from the channel file list.
public abstract byte[] getLoggingData() returns the data logged by the channel as an array of bytes. Returns null if there is no logging data.
public abstract String getLogPrefix() returns a string representing the IP number and date and time of the reqeust.
public abstract int getMinutesGMT() returns the number of minutes off the GMT for the system that made the reqeust.
public abstract getOSarch() returns the OS architecture of the system that made the request.
public abstract getOSname() returns the OS name of the system that made the request.
public abstract getOSversion() returns the OS version of the system that made the request.
public abstract byte[] getProfileData() returns the profile data for the channel as an array of bytes. Returns null if there is no profile data.
public abstract int getProtocolVersion() returns the transmitter protocol version number.
public abstract String getRequestComment() returns the reqeust comment (sent as part of the reqeust) and null if there is no comment.
public abstract long getTunerID() returns a long integer representing the ID of the requesting tuner
public abstract String getTunerIDString() returns a string object representing the ID of the requesting tuner.
public abstract void redirect(String, int) redirects this reqeust to another transmitter. The string argument is the name of the transmitter, and the int is the port number.
public abstract void renameFile(String, String) renames the file from the channel list specified in the first string argument to the name or path of the second string argument.
public abstract void setRequestDelay(int) sets the delay in minutes before the tuner should make a second update reqeust.
LogEntry
The LogEntry class is a simple class for dealing with channel log entries. The Vector object created by the getLogEntries method (from the Plugin class) contains a LogEntry object for each of the log entries.
The LogEntry class has two instance variables:
The marimba.io Package
The marimba.io package provides classes for input and output to supplement the standard java.io classes. The most significant of those classes are the FastInputStream and FastOutputStream classes, which provide optimized unsynchronized buffered input and output streams.
The marimba.io package is part of the marimba.zip library (in either the Castanet Transmitter or Bongo releases).
FastInputStream and FastOutputStream
The FastInputStream and FastOutputStream classes, as I mentioned, provide input and output streams that are fast versions of a combination of the buffered, byte array, and data and print streams from the standard java.io package. Use FastInputStream and FastOutputStream for reading to and writing from files or arrays of bytes.
FastInputStream
FastInputStream extends the java.io.FilterInputStream class and implements the DataInput interface. You can create FastInputStream in a multitude of different ways:
FastInputStream(byte[]) creates a stream that reads from a byte array.
FastInputStream(byte[], int, int) creates a stream that reads from a byte array (the two integers are the offset and length of the array).
FastInputStream(String) opens a file.
FastInputStream(File) opens the given file.
FastInputStream(InputStream) combines two streams.
FastInputStream(InputStream, int) combines two streams given a buffer size.
FastInputStream(RandomAccessFile) accesses a RandomAccessFile stream
In addition to the standard methods available from its superclasses and the DataInput interface, FastInputStream includes the following additional methods:
public boolean backup(int) backs up by a given amount (usually just one character or a small amount near the beginning of a stream).
public boolean getError() sees if there has been an I/O error. (I/O errors are only reported when the stream is closed.)
public PropertyObject readObject() reads a persistent object into a PropertyObject instance. (See the section on marimba.persist in this chapter for more information about persistent objects.)
FastOutputStream
FastOutputStreams are analogous to FastInputStreams; the FastOutputStream class inherits from java.io.FilterOutputStream and implements the DataInput interface. FastOutputStreams combine the best features of DataOutputStream, PrintStream, and BufferedOutputStream.
You can create a new FastOutputStream using one of these constructors:
FastOutputStream() creates a memory-output stream.
FastOutputStream(int) creates a memory output stream with a given size.
FastOutputStream(byte[]) creates a memory-output to the given byte array.
FastOutputStream(File) opens the given file for writing.
FastOutputStream(String) opens a file for writing.
FastOutputStream(OutputStream) combines two output streams.
FastOutputStream(OutputStream, int) combines two streams given a buffer size.
FastOutputStream(RandomAccessFile) opens using a random access file.
In addition to the standard methods available from its superclasses and the DataInput interface, FastOutputStreams also implement all the printing methods from PrintStream, and the following methods:
public boolean getError() returns true if there has been a write error. (Write errors are not reported until the stream is closed or flushed.)
public void justClose() is a version of the close() method that doesn't throw an exception.
public void writeObject(PropertyObject) writes a PropertyObject object to the stream. See the section on the marimba.persist package for more information.
Other Classes
The marimba.io package also contains the following classes, which you may find useful:
The marimba.gui Package
The marimba.gui package contains the classes that constitute Java support for Bongo and its widgets. Although this is a very large package, I'm not going to cover all of it in this chapter; here I'll focus on the parts we've covered throughout this book and that are useful to channel developers. See the API documentation or Official Marimba Guide to Bongo for more information.
The marimba.gui package is part of the bongo.zip library. Because this library will not be part of the standard tuner distribution (it was in previous beta releases of the tuner), you should include it with every channel that uses any of its classes.
(d)PlayerUtil
The PlayerUtil class allows you to manipulate the widgets in a presentation from the class that uses that presentation. For channels built from the ApplicationPlayerFrame class, you can get to the PlayerUtil object for the current presentation via the util instance variable.
The PlayerUtil class provides the following methods:
NoteMany of these methods only apply to specific widget classes in the presentation, and others are only meaningful on specific widgets. You should be familiar with the widgets you use so that the values you get and set from those widgets to not surprise you.
public void addList(String, ListItemWidget) adds the ListItemWidget in the second argument to the ListWidget named in the first argument.
public void addSortedList(String, ListItemWidget) adds a ListItemWidget to a named ListWidget, sorted by the key.
public void appendText(String, String) appends the string in the second argument to the TextWidget or TextAreaWidget named in the first string argument.
public void clearList(String) clears the ListWidget named in the argument.
public void clearText(String, long) clears the TextWidget or TextAreaWidget named in the first argument, after the number of milliseconds in the second argument.
public String currentPage(String) returns the current page of the FolderWidget named in the argument.
public boolean getBoolean(String) gets the value of the CheckBoxWidget or OptionWidget named in the argument.
public String getChoice(String) gets the value of the ChoiceWidget named in the argument.
public PlayerPanel getPlayerPanel() returns the PlayerPanel object for this presentation. (The PlayerPanel is a subclass of java.awt.Panel that displays a presentation.)
public Presentation getPresentation() gets the current presentation.
public String getText(String) gets the text of the widget named in the string argument.
public Object getValue(String) gets the value of the widget named in the argument.
public synchronized Widget getWidget(String) returns the widget object referenced by name in the argument.
public void gotoPage(String) goes to the page named by the argument.
public void setBoolean(String, boolean) sets the value of the CheckBoxWidget or OptionWidget named in the first argument to the value of the second argument.
public void setChoice(String, String) sets the value of the ChoiceWidget named in the first argument to the value of the second argument.
public void setFPS(String, int) sets the frames per second for the AnimatedWidget listed in the argument to the speed in the second argument.
public synchronized void setPresentation(String) sets the current presentation, located at this path and filename.
public synchronized void setPresentation(URL) sets the current presentation, located at the given URL.
public void setText(String, String) sets the text of the widget named in the first string argument to have the value of the second string argument.
public void setValue(String, Object) sets the value of the widget named in the string argument to the value of the object argument.
public void show(String) shows the widget named by the first argument.
public void show(String, boolean) shows or hides the widget named by the first argument. If the second argument is true, this shows the widget; if false, hides the widget.
Widget and its Subclasses
The Widget class is the generic class for all Bongo widgets, and includes a set of standard properties and behaviors for all widgets. All the widget classes in the marimba.gui class inherit from this class.
Widget is a large class and contains many of the same methods available from PlayerUtil to get an set various values of a widget. For more information on the variables and methods in Widget and its subclasses, see the API documentation or Official Marimba Guide to Bongo.
PlayerFrame
The PlayerFrame class is a subclass of java.awt.Frame that displays a Bongo presentation in a window. Usually with a channel, you'll subclass ApplicationPlayerFrame so that your Java program can respond to channel events; however, if your channel uses subwindows with separate bongo presentations you'll want to subclass PlayerFrame instead.
The marimba.persist package contains classes that helps freeze the state of objects–which usually means saving them to files. These classes are used as part of Bongo to help widgets store themselves and their properties. If you're interested in learning more about widget persistence, Official Marimba Guide to Bongo has details.
The marimba.persist classes are stored in the marimba.zip class, available from either the Castanet Transmitter or Bongo releases.
The marimba.desktop Package
The marimba.desktop package contains classes that allow Bongo widgets and classes that use Bongo to interact with the native desktop. These classes are, for the most part, used internally by Bongo, with a few notable exceptions: four classes for adding a menubar and menus to presentations being displayed in PlayerFrame or ApplicationPlayerFrame. These classes behave nearly identically to the java.awt classes for menus (in fact, they inherit from those classes and are effectively Bongo-based wrappers for that AWT functionality), and include
The marimba.text Package
The marimba.text package contains classes for implementing a rich text editor–used by Bongo for its script editor. These are utility classes that you generally won't use in your own classes. marimba.text is part of the bongo.zip library and includes
The marimba.util package provides assorted utility classes for the other Marimba classes. Although these classes are generally only useful to the Marimba software, they are worth a mention here.
The marimba.util package is contained in the marimba.zip library, in either the Castanet Transmitter or Bongo distributions, and includes the following classes and interfaces:
Do any work developing Castanet channels, and you'll end up touching the classes in the various Marimba packages. (Often you'll end up putting your hands all over them, actually.) In this chapter you got a general overview of the classes available to you in the marimba packages, in which zip libraries they can be found and, in the case of the more important classes, the sorts of things you can do with them.
Congratulations! You've reached the end of Official Marimba Guide to Castanet. After slogging through all 14 chapters in this book, you've now learned nearly everything you'll need to know about using the Castanet software and creating channels. Stay tuned to the Marimba home page and to the mailing lists for new information and details on further releases, and good luck!