The Artima Developer Community
Sponsored Link

Version 1.1a
The ServiceUI API Specification
by Bill Venners

<<  Page 5 of 12  >>

Advertisement

3. UI Roles

The UIDescriptor's role field gives the fully qualified name of the interface that represents the role of the UI the marshalled UI factory generates. If the client program unmarshals the UI factory and invokes a factory method, the UI the factory method returns must implement the role interface that role specifies.

For a client program to use a UI, the client must have prior knowledge of the UI semantics, a portion of which the UI's role type defines. Thus, for a client to use a UI, the client must understand the semantics of the type whose fully qualified name appears in the role field of that UI's UIDescriptor.

For example, three role types defined in the net.jini.lookup.ui package by the Jini Service UI Specification are MainUI, for a main UI to a Jini service; AdminUI, for an administration UI; and AboutUI for an about UI. Future incarnations of the Jini Service UI Specification, individual Jini service API specifications, or any other party may define other role types. The UI role types' fully qualified names should, as with any other type, follow the recommended naming convention for unique packages outlined in the Java Language Specification:

You form a unique package name by first having (or belonging to an organization that has) an Internet domain name, such as sun.com. You then reverse this name, component by component, to obtain, in this example, com.sun, and use this as a prefix for your package names, using a convention developed within your organization to further administer package names.

For example, printers in general don't have a main UI, but they may have a UI for printer setup, a UI for print job setup, and a UI for administering the printer. The Printer working group, therefore, could define two role types as part of its Printer API definition, one for printer setup and one for print job setup. (The printer's administration UI could likely use the existing net.jini.lookup.ui.AdminUI role.) The Printer working group would start its role type names with a package prefix it has either received or obtained control over. For example, if the Jini Community grants the Printer working group the right to place its APIs in the net.jini.print package, the group could name its role types: net.jini.print.ui.PrinterSetup and net.jini.print.ui.PrintJobSetup. Each working group or other entity that defines Jini Service APIs can include, as part of its specification, any new UI role types useful in the context of its service.

3.1. Display Roles to Users

As the strings referenced from the role field are Java type names, they should only be manipulated by client programs. Users should not view them. A client may, nevertheless, display localized strings representing roles about which the client has prior knowledge.

For example, imagine a Jini browser client shows a service list using icons and names provided by net.jini.lookup.entry.ServiceType (ServiceType) entries. Such a Jini browser could, when the user double-clicks on a service icon or name, attempt to display a MainUI for the service. In addition, such a Jini browser could, when the user right-clicks on a service icon or name, pop up a list of verb strings, one for each UI role the service offers in a form the client believes it can use. For example, imagine that the user right-clicked, among the UIs offered by the service, three java.swing.JFrame (JFrame) UIs (produced by net.jini.lookup.ui.factory.JFrameFactorys); one for each of net.jini.lookup.ui package's three defined roles: MainUI, AdminUI, and AboutUI. If the client can use JFrames, the client could display three verbs on the pop-up list when the user right-clicks. In the US-English locale, the verb strings could be: "Open...", "Administer...", and "About...". If the user selects About..., the client could display the AboutUI JFrame.

Note that the service did not provide the strings shown to the user -- "Open...", "Administer...", and "About...". The developers of the Jini browser client decided upon these strings. Given that these developers had prior knowledge of the MainUI role, they were able to decide that, in their client, "Open" would be a sensible verb string for MainUIs in the US-English locale. Of course, those developers may have selected other verb strings for other locales. German users of the same browser, for example, could potentially encounter the verb string "Jetzt Geht's Los..." for MainUIs, "Was Ist Das Ding..." for AboutUIs, and "Spielen Sie Mit Die Viele Kleine Nummern..." for AdminUIs.

Because the client program, not the Jini service, provides the verb strings, the client will be unable to show a verb in its list for any role about which it did not have prior knowledge. Thus, if the user right-clicks a service that also offers a JFrame UI with the role net.jini.blender.ui.FrappeUI, the client will be able to display a localized string for that UI in its verb list only if the client's developers had had prior knowledge of that role. If the client's programmers did not endow the program with prior knowledge of FrappeUIs, the client will not be able to list a verb for that UI in its pop-up, and therefore the user will not be able to select it. This prior-knowledge requirement is intentional, because as mentioned previously, the role defines a portion of the UI's semantics. Before the client program can properly use a UI, it must have prior knowledge of the role interface. If a client doesn't know how to use a UI, then letting the user select that UI makes no sense.

3.2. The net.jini.lookup.ui.MainUI Role

net.jini.lookup.ui.MainUI (MainUI) is a UI role interface implemented by main UIs, which enable client programs to grant users general access to a service. If a UI descriptor's UI factory produces a UI that implements this interface (i.e., produces a main UI), the UI descriptor's role field must reference a String with the value net.jini.lookup.ui.MainUI.

The first parameter of any factory method declared in a UI factory type is a role object. Any factory method that produces a main UI must accept as the role object the service item (the net.jini.core.lookup.ServiceItem) of the service associated with the main UI.

Main UIs should let clients configure them before they begin. For example, main UIs produced by FrameFactory, JFrameFactory, WindowFactory and JWindowFactory (all members of the net.jini.lookup.ui.factory package) should not be visible when they return from the factory method. This allows clients to set the UI's position and size, for example, before making the UI visible by invoking setVisible(true) on the UI.

A client should be able to invoke a main UI factory method multiple times sequentially. In other words, if a user uses a service via a main UI, then exits, and then double-clicks once again on the service icon, the client can simply invoke a UI factory method again, and acquire another main UI for the same service. Therefore, you should write main UIs so that they work regardless of the service proxy's state when the main UI is created.

It is recommended that clients use multiple main UIs for the same service only sequentially, and avoid creating for the same service proxy multiple main UIs that operate concurrently with one another. But because some clients may create and use multiple main UIs simultaneously for the same service proxy, service and main UI providers should program defensively to ensure that multiple main UIs for the same service proxy will all work together concurrently.

Here's the net.jini.lookup.ui.MainUI tag interface:

package net.jini.lookup.ui;

public interface MainUI {

    String ROLE = "net.jini.lookup.ui.MainUI";
}

3.3. The net.jini.lookup.ui.AdminUI Role

net.jini.lookup.ui.AdminUI (AdminUI) is a UI role interface implemented by admin UIs, which enable users to administer a service. If a UI descriptor's UI factory produces a UI that implements this interface (i.e., produces an admin UI), the UI descriptor's role field must reference a String with the value "net.jini.lookup.ui.AdminUI".

The first parameter of any factory method declared in a UI factory type is a role object. Any factory method that produces an admin UI must accept as the role object the service item (the net.jini.core.lookup.ServiceItem) of the service associated with the main UI.

Admin UIs have precisely the same semantics as main UIs. The only difference is their purpose. Here's the net.jini.lookup.ui.AdminUI interface:

package net.jini.lookup.ui;

public interface AdminUI {

    String ROLE = "net.jini.lookup.ui.AdminUI";
}

3.4. The net.jini.lookup.ui.AboutUI Role

net.jini.lookup.ui.AboutUI (AboutUI) is a UI role interface implemented by about UIs, which enable users to view (or in some way experience) information about a service. If a UI descriptor's UI factory produces a UI that implements this interface (i.e., produces an about UI), the UI descriptor's role field must reference a String with the value "net.jini.lookup.ui.AboutUI".

The first parameter of any factory method declared in a UI factory type is a role object. Any factory method that produces an about UI must accept as the role object the service item (the net.jini.core.lookup.ServiceItem) of the service associated with the main UI.

About UIs have precisely the same semantics as main UIs. The only difference is their purpose. Here's the net.jini.lookup.ui.AboutUI interface:

package net.jini.lookup.ui;

public interface AboutUI {

    String ROLE = "net.jini.lookup.ui.AboutUI";
}

3.5. Defining New Role Types

As mentioned previously, any party may define new role interfaces. New UI role interfaces will likely be defined in conjunction with new Jini Service API definitions, and many of those roles will likely represent service-specific dialogs with users. As used here, a dialog is a short conversation with the user, usually to obtain some information from the user. Although for graphical toolkits, a dialog is often implemented with a dialog box, such as AWT's Dialog or Swing's JDialog, the term dialog is used here in the generic sense, not strictly in the graphical sense. Service-specific dialog UIs will enable clients to enlist a user's help at various points throughout an otherwise direct use of a service.

As an example, consider a user asking a word processor that has prior knowledge of a well-known Jini Printer API to print a document. (Note that the types appearing in this example were invented for illustration purposes. At the time of this writing, the Jini Printer Service API had not been finalized.) To print via the Jini Print Service API, the word processor first obtains a net.jini.print.service.PrintService (PrintService) object and invokes createPrintJob() on that object to obtain a net.jini.print.job.PrintJob (PrintJob) object. A purely direct-use client must do two things with the PrintJob object -- configure the print job and supply the print data -- before invoking close() on the print job, thereby queuing the printing job. Although the word processor could potentially do both jobs directly, it may not have prior knowledge of the portion of the PrintJob object's interface that lets the client configure the print job, and besides, users are accustomed to configuring print jobs. Given an available user, the word processor would likely want to provide a dialog UI that lets the user configure the print job. Once the user completes his or her configuration and dismisses the dialog UI (with "OK," not "Cancel"), the word processor could supply the print data and invoke close() on the PrintJob.

Given that Jini Print Service API clients would prefer a dialog UI that allows for user configuration, the Printer working group could define a new UI role type for that purpose. The Printer working group would likely place the role interface in some subpackage of its API's main package. For example, it could define an interface named: net.jini.print.ui.PrintJobSetup (PrintJobSetup).

A PrintJobSetup UI would represent a dialog that enables user configuration of a print job, such as page orientation, and so on. Once the user selects configuration parameters, he or she dismisses the dialog UI, which in some way communicates back to the client those parameters (likely by invoking methods on the PrintJob object itself, which is likely the role object for the PrintJobSetup role) and indicates to the client that the dialog is finished. The PrintJobSetup interface's semantics would define how the client interacts with the UI, such as how the client knows the UI has been dismissed, and whether or not the user dismissed the UI with "OK" or "Cancel." If the client receives "OK," the client could then write print data to the PrintJob object and invoke close() on the PrintJob, thereby sending it to the printer.

The semantics of the PrintJobSetup role interface defines the way in which the PrintJobSetup UI interacts with the client (i.e., communicates the configuration data and indicates the dialog's dismissal). As the dialog may require sophisticated UI and client interaction, the role interface may be more than just a tag interface; it may include methods that define how the UI and client interact. The word processor client would know how to display this PrintJobSetup dialog because the PrintJobSetup role interface, and its semantics, would be defined in the Jini Print Service API, of which that client has prior knowledge.

3.6. Working with Existing Role Types

Besides creating new role types for service-specific dialogs, a working group for a Jini service API or a provider of a Jini service API implementation could also provide multiple incarnations of an already-defined role. For example, what if the manufacturer of a combined printer/scanner/faxer/copier product (a "four-in-one box") wanted to deliver four AdminUIs, each dedicated to administering one of four product functions? Such a manufacture could take several approaches.

First, assuming the Jini Community has adopted a standard API for each product function (i.e., a Jini Print Service API, a Jini Scanner Service API, a Jini Faxer Service API, and a Jini Copier Service API), the four-in-one-box manufacturer could, rather than registering one Jini service whose service proxy implements four interfaces (such as Printer, Scanner, Faxer, and Copier), simply offer four separate Jini services, each of which implements only one interface. In this approach, each service could offer an AdminUI dedicated to that one function.

Alternatively (or in addition), the manufacturer could register one Jini service whose service proxy implements all four interfaces. The AdminUI for that service could present a user interface device (such as a tabbed pane for a graphical UI) that lets users select between the four main functions. In this way, one AdminUI exists, which grants users access to the four conceptual administration UIs.

Lastly, the manufacturer could propose to the Jini Community a Jini Four-in-One Service API that includes four new role types, each dedicated to administering a product subset. The Four-in-One working group, which defines the Jini Four-in-One Service API, could control a package that holds the role types, PrinterAdminUI, ScannerAdminUI, FaxerAdminUI, and CopierAdminUI. Clients with prior knowledge of the Jini Four-in-One Service API would also have prior knowledge of the four role types, and therefore could offer verb strings for them. Four-in-One service providers could offer those four admin UI types, but should also offer a basic net.jini.lookup.ui.AdminUI, which as described previously, grants a user access to all four admin UIs. Including an AdminUI lets clients that don't have prior knowledge of the Four-in-One service to offer a UI that will let users administer that service.

3.7. Choosing Superinterfaces for New Role Types

In general, role interfaces should not extend other role interfaces, because only one role interface is described in the UI descriptor's role field. For example, the FaxerAdminUI from the previous section appears to be able to extend AdminUI, because you could consider a FaxerAdminUI to be an AdminUI type. However, only one role interface can appear in the UI descriptor's role field. If a UI is both a FaxerAdminUI and an AdminUI, then which role goes into the role field? If the same UI registers twice, once with AdminUI and once with FaxerAdminUI, then what is the point of FaxerAdminUI? In other words, if a FaxerAdminUI is the default admin UI of the four, then the Four-in-One working group wouldn't need to define a FaxerAdminUI in the first place. They would only need to mention that an AdminUI should behave as an admin UI for the fax machine.

Role interfaces can extend other interfaces; in general, they simply shouldn't extend other role interfaces. If a dialog UI role's semantics are already defined in an interface, then the role interface could extend that interface and thereby inherit those methods and semantics.

Nevertheless, if a party decides to create a role interface that extends another role interface, any factory method that generates the subinterface UI role type must accept the same role object categories accepted by factory methods that generate the superinterface UI role type. For example, if FaxerAdminUI were declared as an AdminUI subinterface, any factory method that produces a FaxerAdminUI would have to accept as the role object the FaxerAdminUI-associated service item, because factory methods that produce AdminUIs accept that role object category.

It is recommended that all role interfaces include a compile time String constant named ROLE, which gives the UI role interface's fully qualified string type name, as it should appear in UI descriptor's role fields. Such convenience constants not only help reduce typing and increase code readability, they also leverage compile-time type checking to help minimize the chance of typographical errors in role strings.

<<  Page 5 of 12  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2017 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us