CHAPTER 6: PLUGINS

 

What

 

Why

                vs external program

                vs source code

 

Mechanics of plugin client

                Code to interface

                Move class files to plugin directory

                Watch it work

 

Mechanics of server

                Define interface

                Define directory

                Load classes

                Instantiate & call

 

Plugins in Java

 

Consequences

                Security

                Security Manager

                CPU

 

Applications in the Site Manager

 

 


Plugins

Sometimes, we’d like to treat a whole application as a black-box framework. We might like a sophisticated end user to be able to extend the application.

 

A plugin is code, typically developed by a framework user, that provides extra capabilities to an application. It is useful when the application provides a framework (in the broadest sense), but different users might need their own handling of the details.

 

Adobe Photoshop™, a top-end graphics tool, is probably the biggest popularizer of the plugin approach. Adobe didn’t want to be responsible for creating and marketing every cool image filter imaginable. Instead, they provide a mechanism where you can buy a plugin from a third party, and install it into Photoshop. The plugin becomes a new tool available to the user, as if it had been built in originally.

 

A “traditional” way to provide such a feature is to provide a pipeline to a separate process. For example, web servers have traditionally used CGI scripts in this way. When a web page is requested that uses a CGI script, the web server creates a process for the script, builds a pipeline to it, sends the script the data from the request, and sends the output of the pipline as the result of the request.

 

Separate process

Advantages

Disadvantages

·         Well-defined interface.

·         Separate address space prevents a bad script from crashing the whole process.

·         Separate address space requires explicit transfer of information.

·         Creating processes adds overhead (mitigated by pooling).

·         May require multiple copies of data.

 

An alternative is to use threads, running the script in a separate thread within the server.

 

 

Separate thread in one process

Advantages

Disadvantages

·         Well-defined interface.

·         Easier to pass information to the script.

·         Less overhead to create thread (rather than process).

·         Trouble in one thread can hurt the whole process.

·         The thread has access to the internals of the whole application.

 

In Java, servlets take this approach. (Because Java is a relatively safe language, we run less risk of the script crashing the server than we would for, say, C programs.) Some web servers, such as Apache, have been modified to take this approach for languages other than Java.

 

Another alternative would be to provide the whole framework of the application.

 

Make whole framework/application available

Advantages

Disadvantages

·         Allows developer to control all aspects.

 

·         Requires developer to control all aspects.

·         Gives away too much intellectual property.

 

 

A plugin provides an intermediate point in this design space.

 

·         Only part of the application framework is exposed. The preserves much of the developer’s intellectual property, but still exposes a well-defined piece. (This exposure is the price of letting others extend the application.)

·         The plugin code typically runs in the main thread, or a separate thread in the application. It is quick enough to start up that it can be used to extend a menu or palette.

·         “Integration” of the plugin with the application is done at run-time. (The developer has to integrate and test with the application, but to the end user it’s “plug-n-play”.)

 

We'll look at plugins from the perspective of the end user, the plugin developer, and the framework developer. We'll explore how  plugins can be implemented in Java. Finally, we'll add plugin support to the web site manager we developed in a previous chapter.

 


Plugins as Seen by the End-User

 

Plugins are simple from the end-user's point of view. The user has the main application, and decides to add a plugin. Once the plugin is installed, the user has a new feature in the application.

 

How does the user install the plugin? Several possibilities are common:

·         The main application detects the need for the plugin, and asks permission to  install it. (Netscape Communicator (TM) does this.)

·         The user can instruct the main application to install a new plugin. The main application typically  uses a file dialog to help the user locate the plugin.

·         The plugin may control the process, by having an installation program the user must run. (Then the user is often prompted to locate the main application.)

·         Installation is “by convention.” The user may be instructed to drag a file (or files) to a particular directory of the main application.

 

Any of these mechanisms are workable. The key is to make it easy for the user.

 

 

Plugins as Seen by the Plugin Developer

The plugin developer typically works with a software development kit (SDK) for the plugin, provided by the developer of the main application.

 

The SDK will contain documentation, source code, object code, miscellaneous scripts and tools, and most importantly, examples. (Some SDKs will include tools such as compilers.)

 

The plugin developer will need to know the interface to which the plugin code must conform. (In Java, this will often be a Java “interface”, rather than inheriting from a particular class.) There may be important support classes as well. There may be information passed to the plugin that the plugin must understand.

 

The first example is the most critical. It's the equivalent of "Hello, World" in C. It needn't do much, but when the developer completes the steps, they will have created and installed a plugin from scratch.

 

Once completed, the plugin developer will test the plugin, and develop an installation mechanism (if one isn’t provided by the application directly).

 

 

 

Plugins as Seen by the Framework/Application Developer

The framework developer must define the interface for the plugin developer. In many ways, this is similar to defining any other framework interface. You want to keep it "narrow" - dependent on as few types as possible. This way, you only expose a limited amount of information to the plugin developer.

 

An easy way to allow for plugins is to designate a directory as the target location. This should be in the tree of class files: the plugin mechanism must be able to locate them.

 

The framework needs a mechanism for loading the plugin files. (We'll see the details in the next section.)

 

                                Locate the plugins

                                Load their classes

                                Instantiate and hook up instances

 

Once instantiated, the plugins look like any other class. Usually, they’re added to a special menu or palette, to make them available to the end user at runtime.

 

Next, the framework developer must develop documentation and examples, as described in the previous section.

 

[TBD: The SDK]

 


 

Plugins in Java

Set directory

Class.forName("file") -> Class

Class.newInstance()

 

Use reflection:

Class c = Class.forName("Package.classname");

Object o = c.newInstance();

MyClass c = (MyClass) obj;

 

 

 


The Site Manager as a Plugin

 

 

Site manager plugins:

·         Look up plugins

·         Create main form

·         For each plugin, make listener & insert panel

·         Select top node

 

 

Make graph:

  getCanReverseLinks()

to tell if in-links accessible.

 

If false, enum always empty (not null).

 

 

PageSelectionListener

 

PageHandler implements PageSelectionListener

  void pageSelected (PageSelectionEvent e) { ...}

 

 

Page view Plugin extends PageSelectionListener

                No-arg constructor () required

                void pageSelected (PageSelectionEvent e) { ...}

                String getShortName() { ...}

                String getLongName() { ...}

                JPanel getPanel() { ...}

 

Or an ObjectSelectionListener?

 

PageScorePlugin

  columns

  values

  min?  max?

  Range limits? (red/yellow/green?)

  int valueFor (page)

 

 


Plugin

 

Root directory

Directory to search

Class to match

Return array of all classes in the list that match the class

 

 

DefaultMutableTreeNode

 

public class FileTree extends DefaultTreeModel {

   public FileTree(File base) {

                super(new FileTreeNode(base));

  }

}

 

public class FileTreeNode extends DefaultMutableTreeNode {

                public FileTreeNode(File base) { super(base); base.isDirectory();}

                protected boolean loaded;

                public int getChildCount() {

                                if (!loaded) {

                                                File thisFile = (File)userObject;

                                                String files[] = thisFile.list();

                                                for (int i = 0; i < files.length; i++) {

                                                                add(new FileTreeNode(new File(thisFile, files[i])));

                                                }

                                                loaded = true;

                                }

                                return super.getChildCount();

                }

 

Note:

·         File.toString() is full path

·         Not alphabetical

·         Method to select row given file

 


public class GraphBrowser extends JPanel  implements GraphListener {

                GraphBrowser(Graph)

                GraphBrowser(Graph, Node)

                GraphBrowser()                   --??

                addObjectSelectionListener (ObjectSelectionListener osl) { ...}

                removeObjectSelectionListener(ObjectSelectionListener osl) { ...}

                setGraph(Graph)

                setNode(Node)                    // may be null

}

 

 

UI:

                List                Label=current   List

 

 


Graph Browser

 

Graph graph = null

Node current = null

 

JList inList = new JList();    // single-sel

JList outList = new JList();                // single-sel

JLabel currentNode = new JLabel();

 

GraphBrowser() {

                setLayout(new GridLayout(1,3));

                add(new JScrollPane(inList));

                add(currentNode);

                add(new JScrollPane(outList));

}

 

GraphBrowser(Graph) { ...}

GraphBrowser(Graph, Node) { ...}

 

void setGraph (Graph g) { graph = g; setNode(null);}

 

void setNode (Node n) {

                if (current != n) {

                                inList.setModel(new listModel w/in-nodes for enum);

                                Object o = n.getUserObject();

                                currentNode.setText(n==null?"":n.toString());

                                outList.setModel(new model w/out-nodes);

                                fireSelectionChanged();

                }

}

 

Listeners must make the selection be the new node.

addObjectSelectionListener (osl o) { ...}

removeObjectSelectionListener(osl O) { ...}

 


NodeToFileTreeAdapter extends objectSelectionListener {

                public void objectSelected (ObjectSelectionEvent e) {

                                Node n = (Node)e.getSelection();

                                Page p = (Page)n.getUserObject();

                                File f = p.getFile();

                                find f in tree

                                Set selector to that

                }

}

 


PLUGINS - NETSCAPE

 

http://developer.netscape.com/docs/manuals/communicator/plugin/index.html

 

Checks directory

Registers

Queries to see if they can handle it

 

Check type

Load plugin

Initialize

Create instance

 

Plug-in methods: Functions you implement

Netscape methods: In Communicator, plugin calls them

Data structures

 

 

When does it apply?

Beans as programs

 

 

Copyright 1994-2006, William C. Wake - William.Wake@acm.org