Revision History

1.1a - Sat., June 4, 2005: Released 1.1a with no changes to the code or this specification other
than changing the license from the Sun Community Source License (SCSL) to Apache License, Version 2.0.

1.1 - Thu., October 14, 2002: Released 1.1beta4 as 1.1 with no changes to the code or this specification.

1.1beta4 - Thu., July 11, 2002: Made a
1.1beta4 release in which the doPrivileged statements are removed from
the UIDescriptor.getUIFactory method.
Removed the sentence, "Because setting
and getting the context class loader is a privileged operation, the getUIFactory()
method wraps those operations in AccessController.doPrivileged() calls," from the
description of getUIFactory in section 2 of this specification.

Added Section 9, Consistent Serialized Forms, which
describes a slight narrowing of the contracts of the constructors of UIDescriptor,
Locales, UIFactoryTypes, and RequiredPackages. These
constructors are now required to copy the contents of the passed Set or
Map to an unmodifiable version that has a consistent serialized form
across all VMs.

Changed the implementation and contract of AccessibleUI.hashcode
so that it returns the hashcode of its fully qualified String name, rather than
the hashcode of its Class instance.

Added UIDescriptorBean to net.jini.lookup.entry, as suggested
by the Jini Lookup Attributes Schema specification.

Theresa Gonzales edited the entire spec for English, and I went over it again after that. Lots
of minor changes to clarify sentences, but no change in semantics.

Changed "service object" to "service proxy," to tow the line with
commonly used Jini jargon.

Modified the Javadoc of MainUI, AdminUI,
and AboutUI to match the semantics given in the
specification. Originally (prior to the 1.0 release), these role
interfaces defined their role object to be exactly the service item.
Ken Arnold requested we say that the service item must be accepted
as the role object, which yields more flexibility. Although a
service item is required to always work when passed as the role
object to factory methods for main, admin, and about UIs, other
objects may also work. I made this change back then to the
specification, but forgot to change the Javadoc comments. The
specification and the Javadoc comments are now in sync.

1.1 - Wed., Aug. 22, 2001:
Fixed two method names in JDialogFactory that were both incorrectly
named getDialog()
in ServiceUI 1.0. The methods are now correctly named getJDialog().
Added serialVersionIDs
to all classes in the API in order to accelerate deserialization. Improved
javadoc comments: added missing serial, author, param, throws, and return
tags, as well as added clarifying javadoc text where it seemed helpful.
Added flat javadoc documentation to the end of Service UI API Specification
to make sure the API's semantics are specified in detail in the
specification itself.

1.0 - Mon., Apr. 24, 2000:
Only changed the specification's version number from 0.9.2 to 1.0 in order
to match the version number of the code now released under the Sun
Community Source License (SCSL).

0.9.1 - Mon., Mar. 6, 2000:
Only changed the specification's version number from 0.9.0 to 0.9.1 to
match the code's revised version number. Fixed some bugs in version 0.9.1
code, which are described on the Code Access
page: http://www.artima.com/jini/serviceui/CodeAccess.html.

0.9.0 - Tue., Feb. 22, 2000:
Fixed four grammar typos, without changing specification meaning. In
section 3.2, paragraph 2, the main UI's associated service item must be
accepted as the role object, rather than required as the role
object. In section 3.3, paragraph 2, the admin UI's associated service
item must be accepted as the role object, rather than required
as the role object. In section 3.4, paragraph 2, the about UI's associated
service item must be accepted as the role object, rather than required
as the role object. In section 3.7, paragraph 2, changed "simply
shouldn't extend" to "simply shouldn't in general
extend." In section 3.7, added paragraph 3, which starts,
"Nevertheless, if some party...."

0.8.1 - Wed., Feb. 9, 2000:
In MainUI,
AdminUI,
and AboutUI,
changed constant role
to ROLE.
In all factories, changed toolkit to TOOLKIT and typeName
to TYPE_NAME.

0.8.0 - Tue., Feb. 8, 2000:
One last pass. Mostly minor tweaks except for the last few sections, which
had some major surgery.

0.7 - Mon., Feb. 7, 2000:
Reviewed and cleaned up a lot of text. A few sections near the end are
still a bit rough. Will post version 0.8 tonight, which will serve as the
starting point for the two-week ServiceUI review phase.

0.6 - Sat., Feb. 5, 2000:
Fleshed out remaining sections, though some of it is rough.

0.5 - Thu., Feb. 3, 2000:
Fleshed out material in most sections. Added a new section on third-party
UIs.

0.4 - Wed., Feb. 2, 2000:
Incorporated changes decided upon with Jini architects at the 2nd meeting.
Document now offers a good general overview.

1. Introduction

Traditionally, desktop applications are designed with a built-in user
interface (UI). The code for the application's UI is often highly coupled to
the code that implements the application's functionality. Over time, tentacles
of UI code may burrow deep into functionality code, and tentacles of
functionality code may burrow back into UI code. In the traditional desktop
application, therefore, the UI code and functionality code are usually
inseparable, married for all eternity.

Jini's service proxy architecture encourages you to think differently about
UI and functionality:

UI and functionality should
be separate

Both UI and functionality are
encapsulated in objects

The coupling point between UI
code and functionality code should be the service proxy interface

A Jini service proxy should represent the service's pure functionality, expressed
via the methods of its object interface. For example, the service proxy
interface for a toaster service should express or model the conceptual toaster
service's functionality -- the interface should say "what it means to be a
toaster." The service proxy should not supply human access to the toaster
service; a separate UI object should provide such access.

1.1. Direct-Use Clients

One reason for excluding the UI from the service proxy is to enable client
programs (clients) to access the service without human intervention or
supervision. Clients written by programmers who knew about a particular service
proxy's (potentially well-known or standard) interface can interact with a
service directly. As Figure 1 shows, client code can interact directly with a
service by invoking the methods in the service proxy interface. Such a client
is called a direct-use client, because its programmers, based on their
knowledge of the service proxy interface, can write code that uses the service
directly via that interface.

Figure 1. A "direct-use" client talks to a service through its object
interface.

Direct-use clients need not be completely devoid of a user. For example, a
user could operate a device that acts as a direct-use client in certain cases.
If the user requested that the device save some data in a file, the device
could acquire a storage service proxy and directly invoke methods on that
object to save data in a file, without further user intervention. In this case,
the user-operated device acts as a direct-use client of storage services,
because the device's programmers had prior knowledge of the storage service proxy
interface and used that knowledge to program the device to use those services
directly.

On the other hand, direct-use clients can also function independently of
human supervision or intervention. Such clients act as autonomous agents,
which decide for themselves when to enlist a service's help. When an autonomous
agent uses a service, it invokes the methods offered by the service proxy
interface directly. Thus, an autonomous agent's programmers must have prior
knowledge of the service proxy interfaces their agent uses. (Although the
human programmer actually has the prior knowledge when he or she writes the
client code, in this document the code itself will often be said to have prior
knowledge.)

1.2. User Adapters

When you design a Jini service, you should attempt to capture the service's
entire functionality in the service proxy interface. To access any aspect of
your service, a direct-use client should only need a reference to the service
proxy. The service proxy should not include any code that defines a user
interface to the service, just code that provides the service functionality at
the method invocation level.

To provide a user interface for the service, you should encapsulate the user
interface code in a separate UI object. As Figure 2 shows, a UI object grants a
user access to some aspect of a Jini service. Think of a service UI object as a
user adapter -- an object that adapts a service proxy
interface that a human user cannot interact with directly into one a human user
can interact with directly. Sitting between the service proxy interface and a
human user, a UI object can grant the user access to a service.

Figure 2. A user interacts with a service via a UI object.

A UI object can represent a graphical UI component, such as an AWT Frame or Swing
JPanel,
but doesn't necessarily need to be graphical. A UI object could also represent
a speech interface, a text interface, a speech and graphic combination, or a
3D-immersive world. (The UI object is called UI object, rather than GUI
object or view object, because the object represents UI components
in general, not just graphical UI components.) Any kind of Jini Service UI,
including a 3D-immersible world with speech and virtual text display, should be
represented by a UI object, which is distinct from the service proxy.

One advantage of this architecture, in which UI and functionality are
separated, is that you can associate multiple UIs with the same service.
Associating multiple UIs with one service lets you tailor different UIs for
clients that have particular UI capabilities, such as Swing or speech. Clients
can then choose the UI that best fits their user interface capabilities. In
addition, you may want to associate different UIs that serve different
purposes, such as a main UI or an administration UI, with a service. Often, you
may need to associate multiple UIs with one Jini service, where each UI has a
particular purpose and targets a particular set of client capabilities.

1.3. Jini Service UIs

This specification standardizes how UI providers associate a UI (user
adapter) object with a Jini service, and shows how client programs can find the
best-fit UI among multiple UIs associated with the same service. To associate a
UI with a Jini service, UI providers (primarily service providers, but also
possibly third parties) must supply three items:

The UI itself

A UI factory that produces
the UI

A UI descriptor that
describes the UI

A UI factory is an object that has one or more
factory methods that produce and return a UI object. A UI descriptor, an
instance of net.jini.lookup.entry.UIDescriptor
(UIDescriptor),
serves as a container for the UI factory and other objects that describe the UI produced by the factory.
Because UIDescriptor
implements net.jini.core.entry.Entry
(Entry),
you can include a UIDescriptor
in a Jini service item's attribute sets array, thereby associating the UI with
the service. A UI descriptor contains four public fields:

factory: A reference to a java.rmi.MarshalledObject
that contains the UI factory object in marshalled form

attributes: A java.util.Set
of attribute objects that describe the factory-produced UI

toolkit: A String
that names the main package of the UI toolkit the UI requires

role: A String
that gives the fully qualified name of a Java interface type that
represents the UI's role

The attributes,
toolkit,
and role
fields' purpose is to describe the UI produced by the marshalled UI factory.
Using these fields, clients can choose from multiple UIs associated with a
service. Once they select a UI object, clients can use the other field, factory, to
create the object.

To associate a UI with a Jini service, the UI provider must first fill a UI
descriptor with a role String,
a toolkit String,
an attribute set, and a marshalled UI factory. The UI provider must then place
the UI descriptor in the attribute sets of the Jini service's service item.

A UI's role indicates both its purpose and its role-related semantics. Each
UI role is defined as a Java interface type, which UI objects playing that role
implement. The role
field references a String
whose value is the role interface type's fully qualified name. For example, a net.jini.lookup.ui.MainUI
role UI provides general access to a service. A net.jini.lookup.ui.AdminUI role
UI enables a user to administer a service. Although most UI object semantics of
interest to the client program are defined by the UI factory's return type,
some semantics may be tied to the role. For example, for a role that represents
a user dialog, the role interface might include methods that let the client
determine the dialog's result.

The UI descriptor's attributes
field holds a reference to a java.util.Set of serializable objects that contain
information about the UI the descriptor represents. These objects can be of any
class, so long as they are serializable. Clients can search through the
attributes set for attribute types about which they have prior knowledge. The
objects can then help the client decide whether or not to use the
descriptor-represented UI. Several attribute classes, defined in the net.jini.lookup.ui.attribute
package, are described later in this document.

The toolkit
field facilitates matching when querying the Jini lookup service. For example,
if a client seeks all services that have main UIs working with the Swing
toolkit, it could form a net.jini.core.lookup.ServiceItem
(ServiceItem)
whose attributeSetTemplates
array includes a UI descriptor template. If the UI descriptor template's factory and attributes
fields are set to null,
the role
field is set to net.jini.lookup.ui.MainUI,
and toolkit
field is set to javax.swing,
the lookup would only return services that have at least one main UI for Swing.

The factory
field contains the UI factory object inside a MarshalledObject so that you
can place the class files for the factory and the UI it produces in a different
codebase than the service item containing the UI descriptor. By placing the
class files for UI factories and UI objects in separate codebases than that of
the service item, clients can download a service item without downloading all
the JAR files containing those class files, most or all of which the client may
never use. Only if the client attempts to use a UI will it need to unmarshal
the UI factory; this would trigger the downloading of the JAR file containing
the factory class files, and possibly the class files for the factory-generated
UI.

To use a UI, a client program must have prior knowledge of both the UI
factory type (including, of course, the UI object type returned by its factory
methods) and the UI role type. These types define the UI object semantics,
which client programmers must understand before they can write code to interact
properly with the UI. A client doesn't need prior knowledge of all the
attributes types that appear in the attributes set. To the extent the client
has prior knowledge of the attribute types, it can use that knowledge to select
an appropriate UI from multiple UIs associated with a service.

2. UI Descriptors

A net.jini.lookup.entry.UIDescriptor
(UIDescriptor)
is a net.jini.core.lookup.Entry
(Entry)
that enables a UI to be associated with a service in the service item's
attribute sets. A UIDescriptor
holds a marshalled UI factory object in the factory field, a role type name in the
role
field, a toolkit package name in the toolkit field, and an attribute set
that describes the factory-generated UI in the attributes field.

The UIDescriptor
not only houses a marshalled UI factory that produces a UI, but also describes
the produced UI to help clients decide whether or not to unmarshal the UI
factory. The UI is described in the role, toolkit, and attributes
fields.

Because the marshalled UI factory is referenced from a public field, programs
can simply invoke get()
directly on the marshalled object to unmarshal the factory client. Clients must
ensure, however, that the class loader that loads the class files for the UI
can also (likely via a parent class loader) load the class files of the service
proxy with which the UI will interact. The UIDescriptor includes a convenience
method named getUIFactory()
to help clients unmarshal the UI factory with the proper class loader context.

The getUIFactory() method saves a reference
to the current context class loader, sets the context class loader
to the class loader passed as parentLoader, invokes
get() on the marshalled object, then resets the
context class loader to the saved reference before returning
the object that get() produces.

The class loader passed to the getUIFactory() method in the parentLoader
parameter should be able to load types (classes and interfaces) needed when the
UI interacts with the role object, which is passed as the first
parameter to any factory method. A UI role's semantic description indicates,
among other things, what object should be passed to the factory as the role
object. For the net.jini.lookup.ui.MainUI
role, for example, the role object is the service item. Thus, to unmarshal a UI
factory for a main UI, the class loader passed to getUIFactory() should be able
to load types needed when the UI interacts with the service proxy contained in
the service item. For example,
the client could pass to getUIFactory()
the class loader the client previously used to load the service proxy.

The String
referenced from the toolkit
field (which names the main package of the primary UI toolkit) is determined by
the UI factory type. Each UI factory type's semantics should include a toolkit
string, so UI providers will know what string to put in the toolkit field
for their selected UI factory type. Two toolkit strings currently defined are java.awt, for
graphical UIs that depend on AWT but not Swing, and javax.swing,
for graphical UIs that depend on Swing (and AWT, since Swing is built on top
AWT).

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 AboutUIJFrame.

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.

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:

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:

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.

4. UI Attributes

The UI descriptor's attributes
field references a java.util.Set
of objects that describe the UI generated by the marshalled UI factory. Any
object can appear in this set, so long as it is serializable. (Note that if any
object in this set is not serializable, the entire set will not appear at the
client side -- the UI descriptor's attributes field will be null.)

If a UI provider wishes to register a UI descriptor that has no attributes,
it may register the UI descriptor with either a reference to an empty java.util.Set
or null
in the UI descriptor's attributes
field. Nevertheless, because clients would know little about the UI represented
by that UI descriptor, many clients would likely ignore the descriptor
entirely.

Although all attributes are optional, this specification recommends that all
UI descriptors include at least the attributes (all of which are members of the
net.jini.lookup.ui.attribute
package) described in this list:

If (and only if) the UI
supports the accessibility API, one AccessibleUI attribute

One Locales
attribute: Lists the locales the UI supports

One RequiredPackages
attribute: Lists packages the UI requires to be installed at the client

One UIFactoryTypes
attribute: Lists Java types of which the marshalled UI factory is an
instance

The remainder of this section describes these four attribute classes in
detail.

4.1. The AccessibleUI
Attribute

AccessibleUI
indicates that a generated UI implements the javax.accessibility.Accessible
interface and that the UI's designer made sure the UI would work well with Java
Accessibility API-aware assistive technologies.

The attribute should appear in a UIDescriptor's attributes set only if
the marshalled UI factory produces an Accessibility API-supported UI. This
attribute's presence in an attributes set means the produced UI will work well
with Java Accessibility API-aware assistive technologies.

4.2. The Locales
Attribute

The Locales
attribute lists locales supported by a generated UI.

Zero to many Locales
instances may appear in a UI descriptor's attributes set. UI providers are encouraged to
provide in any UI descriptor's attributes set one Locales object that contains the
complete set of locales supported by the UI. Given that UI providers are not required
to give complete or even accurate information about locales, clients should
program defensively and consider the supported locales a strong hint that
locales are supported by the UI, but not necessarily 100 percent complete or accurate.

4.3. The RequiredPackages
Attribute

RequiredPackages
lets clients obtain a list of fully qualified names and version numbers of
packages a UI requires.

Zero to many RequiredPackages
attributes may appear in a UIDescriptor'sattributes
set. Client programs interested in a UI may wish to verify that they have all
required packages mentioned in the RequiredPackages attributes (if any)
before they attempt to create the UI. If the client lacks any required packages
(either because the package is absent or because the package is incompatible),
the client will not be able to use the UI.

This attribute intends to provide a quick way for a client program to
determine that a client cannot use a UI, not to guarantee that a client can
definitely use a UI. If a client is missing a required package, or has an
incompatible version, the client cannot use the UI. But if the client has
compatible versions of all required packages, the client may or may not be able
to use the UI.

UI providers should attempt to list in a RequiredPackages attribute all
packages that must be installed at the client for the UI to work. In this case,
if the client has compatible versions of all listed packages and attempts to
generate the UI via the factory method, the client will likely succeed. (Note
that packages used by the UI that could potentially be installed at the client,
but are also available at the UI's or service's codebase, should not be listed
in a RequiredPackages
attribute. The client does not actually require such packages, because if the
client doesn't have them, it can download the packages.)

Client programmers should bear in mind that a RequiredPackages attribute
doesn't necessarily list all required packages. As a result,
satisfying all required packages doesn't guarantee the UI will work on the
client. Client programs should therefore program defensively. (For example,
clients should probably catch LinkageError in appropriate places when dealing
with UIs, even if they have compatible versions of all required packages.)

The version numbers listed in RequiredPackages attributes must take
the form of specification version numbers, as used by the java.lang.Package
class:

Specification version numbers use a "Dewey
Decimal" syntax that consists of positive decimal integers separated by
periods ".", for example, "2.0" or
"1.2.3.4.5.6.7". This allows an extensible number to be used to
represent major, minor, micro, etc versions. The version number must begin with
a number.

4.4. The UIFactoryTypes
Attribute

UIFactoryTypes
allows client programs to determine Java types of which a UI factory (marshalled
in the same UIDescriptor)
is an instance.

Zero to many UIFactoryTypes
may appear in the UI descriptor's attributes set. The marshalled UI factory in
a UI descriptor's factory field should be an instance of
each type that appears in any UIFactoryTypes
attribute in that UI descriptor's attributes set.

Of all attributes that could appear in the attributes set, UIFactoryTypes
is perhaps the most important. If a UI descriptor's attributes set includes no UIFactoryTypes
attribute, then the only way for clients to know what kind of factory a UI
descriptor represents is to unmarshal it. But unmarshalling a UI factory will
likely involve downloading code, which a client wants to avoid unless it is
fairly certain it can use the UI. As a result, UI providers are strongly
encouraged to include in every UI descriptor a UIFactoryTypes attribute that
includes those Java types (of which the UI factory is an instance) that clients
would likely be searching for. In general, clients will be looking for
well-known factory interface types, such as those appearing in the net.jini.lookup.ui.factory
package.

5. UI Factories

The UI factory object should implement one or more UI factory interfaces
appropriate to the type of UI generated (the factory method's return value) and
the options clients have at creation time (the parameters the client can and
must pass to the factory method). Factory interfaces can be implemented in many
ways, but in general, factory objects should use lazy instantiation of the UI object.
For example, rather than instantiating a UI object when the factory
instantiates, and returning that already-instantiated UI when a factory method
is invoked, a factory object should wait until a factory method is actually
invoked before instantiating the UI object. Lazy instantiation lets you marshal
the factory object without requiring the UI object's image to be included in
the UI factory's marshalled image.

UI factories define methods that indicate by their return type the generated
UI's Java type and indicate by their parameters the objects and primitive
values that the client can and must supply to the factory. The first parameter
to any UI factory method is a role object. The UI's role determines this
object's category (but not the type). As used here, category means how
the client program obtains the role object. For example, a role might specify
that its role object is the service item, the service proxy, or an object
obtained by invoking a method on the service proxy. The UI role describes how
the client acquires the object that must be passed as the first parameter to
the factory method. For example, the MainUI role's semantics indicate that
the role object is the service item.

You should write UI factories such that their factory methods can be invoked
multiple times. A client may wish to show a user the same UI several times, and
therefore may invoke a factory method on the same factory object multiple
times. Each time the factory method is invoked, it should produce and return a
new UI object copy.

The Jini Service UI API's first version defines eight factory interfaces:

DialogFactory: Returns an
instance of class java.awt.Dialog,
or one of its subclasses, that depends on the AWT, not the Swing,
libraries

FrameFactory: Returns an
instance of class java.awt.Frame,
or one of its subclasses, that depends on the AWT, not the Swing,
libraries

JComponentFactory: Returns
an instance of class javax.swing.JComponent,
or one of its subclasses, that depends on both the AWT and Swing libraries

JDialogFactory: Returns an
instance of class javax.swing.JDialog,
or one of its subclasses, that depends on both the AWT and Swing libraries

JFrameFactory: Returns an
instance of class javax.swing.JFrame,
or one of its subclasses, that depends on both the AWT and Swing libraries

JWindowFactory: Returns an
instance of class javax.swing.JWindow,
or one of its subclasses, that depends on both the AWT and Swing libraries

PanelFactory: Returns an
instance of class java.awt.Panel,
or one of its subclasses, that depends on the AWT, but not the Swing,
libraries

WindowFactory: Returns an
instance of class java.awt.Window,
or one of its subclasses other than Frame or Dialog,
that depends on the AWT, not the Swing, libraries

Future incarnations of the Jini Service UI Specification or any other party
may define additional UI factory interface types. The fully qualified names of
UI factory interface types 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.

Given that only one toolkit field exists, all UIFactory interfaces implemented
by a UI factory class must have the same toolkit.

5.1. Defining New Factory Types

Although anyone can define new factory types, to prevent a chaotic explosion
of factory types, you should define new factory types with the utmost care. In
general, new factory types will be justified only when new UI toolkits appear
on the scene. If possible, new factory types should be agreed upon by the Jini
Community and placed into the net.jini.lookup.ui.factory package so they are easy
to find. For example, if a toolkit is defined for speech-only UIs, a set of
factory methods for speech-only UIs could be added to those already in net.jini.lookup.ui.factory.
If a graphical toolkit is defined for extremely small screens, a set of factory
methods for small-screen UIs could be added to those already in net.jini.lookup.ui.factory.

A UI factory must be an interface, and each method in the interface must
take an Object
called the roleObject
as its first parameter. Other than the role object, nothing should be passed to
a factory method except information or context required by the toolkit.

It is recommended that all UI factory interfaces include two compile time String
constants:

TOOLKIT: Gives the package
name of the produced UI's toolkit, which should appear in the UI descriptor's
toolkit
field

TYPE_NAME: Gives the fully
qualified string type name of the UI factory, as it should appear in UIFactoryTypes
attributes

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 toolkit strings and type names added
to UIFactoryTypes
attributes.

6. UI Objects

UI objects should be user adapters, as shown in Figure 2. Two temptations
that service and UI providers may have are:

Put UI code in the service
proxy

Put service code in the UI
object

Both temptations should be avoided. The Jini service proxy
should contain the service functionality, the whole service functionality, and
nothing but the service functionality. No user-interface code should appear in
the service proxy, and no service functionality should appear in the UI object
unless it also appears in the service proxy. In short, Jini Service UIs should
merely offer users all or part of the functionality available to direct-use
clients via the Jini service proxy's methods.

Note that even though the service item may be passed as the role object for
some roles -- as it is to factories that produce MainUIs, AdminUIs, and AboutUIs --
the full service functionality should nevertheless be available
exclusively through the service proxy. The service item may be passed as the
role object to UI factories because extra information (but not extra
functionality) could exist elsewhere in the service item, in the service ID
or attribute sets, and the UI may wish to display that extra information to
the user.

It is strongly encouraged that service and UI providers decouple the class
files required by a particular service item from the class files required by any
UIs associated with that service via UI descriptors in the service item. If the
class files for the service item and those of all service-associated UIs via UI
descriptors are placed into the same JAR file, then a client must download all
class files for all UIs just to download the service item, even if the client
never uses a single UI.

6.1. What to Provide

This specification does not mandate any UI types to be associated with
services. Service providers are free to provide any types of UI, or no UIs, with
their services. Nevertheless, some discussion of client expectations may help
service providers decide what UI types to supply.

First, if a service provider only supplies one UI, it should likely be an
embeddable component, such as an AWT Panel or Swing JComponent.
Although Swing UIs can be more attractive than AWT UIs, an AWT Panel may
allow the greatest reach with one UI type.

A Panel
allows clients to show a UI without another pop-up window, whether they support
AWT or Swing. If a client wants to pop up a UI, it can embed a Panel UI in a
new Frame
and pop that up. If a client wants to display a Panel title and icon, it can use the
localized name and icon provided by a ServiceType.

A Panel
doesn't usually provide an exit for the client, and a menu bar at the top of a Panel
is uncommon.
So as a UI provider, you may also want to provide either a Frame or a Window in
which Panel is placed
and add other UI elements, such as menu bar, status bar, and title. If you take
this approach, one factory object could implement both the PanelFactory
and the FrameFactory
interfaces, because their toolkit is the same. This might make sense if the Panel is used
in the Frame,
and the Frame
doesn't require many classes not already used by the panel. Alternatively, you could produce the Panel and Frame by two
different UI factories sitting in two different UI descriptors.

You may also wish to support Swing in addition to, or instead of,
AWT. If so, at a minimum a Swing JComponent UI, or a JComponent
with either a JFrame
or a JWindow, may
be more suitable. If you take the second approach, one factory object could
implement both the JComponentFactory
and the JFrameFactory
interfaces, because their toolkit is the same. Alternatively, two different UI
factories sitting in two different UI descriptors could produce the JComponent and
JFrame.

On the other hand, for those UI roles that represent user dialogs, an AWT Dialog or
Swing JDialog
may be more appropriate.

Currently no direct support exists in the Jini Service UI API for
speech-only interfaces, but an AWT or Swing UI could be enhanced with speech
capabilities, produced by an appropriate AWT or Swing UI factory type, and
identified as speech-enabled with the appropriate required package names (such
as javax.speech)
in the RequiredPackages
attribute. If a speech-enhanced GUI is provided, a GUI-only version should also
be provided, as many clients won't have speech capabilities.

6.2. Avoid Service-Level Data and Client Context

Service-level data and client-context data are two data types you may be tempted
to pass to UI objects, either directly or via factory methods (which may then
tempt you to define new factories). It is strongly recommended that you avoid
both temptations.

For example, imagine a service provider requires a user name and password for
its service. The service provider wants clients to be able to save a user's
name and password locally and enter them automatically the next time the user
uses the service. If no user name and password were previously saved, the
service UI would prompt the user to type them into a logon dialog box. But if
the user name and password were saved, the user would never see the logon
dialog box. Rather, the client program would log on automatically with the
saved user name and password, and display to the user only the service UI that
appears after a successful logon.

To implement this functionality, a service provider might be tempted to
define interfaces that allow the client to pass a saved user name and password
to the UI. Alternatively, a service provider might be tempted to define new
factory methods that enable clients to pass a user name and password to the
factory, which could then send them to the UI.

The trouble with either of these approaches is that functionality is being put into the UI that isn't in the service.
As mentioned previously, a Jini service's
functionality should be modeled in the service proxy, so direct-use client
code can just use the service directly. If a service requires a user name and
password, the service proxy's interface should allow the client to provide the
user name and password. Thus, a client with a user could give the user name and
password to the service proxy first, then create the UI. The UI could ask the
service proxy if it has a user name and password yet. If not, the UI would
show the logon dialog box prompting for the user name and password. Otherwise,
the UI wouldn't show the logon dialog box.

The recommended way to design a Jini service and its UIs is to make sure the
full functionality is available via the service proxy interface, and keep the
UIs focused on being user adapters -- adapting some or all functionality
available via the service proxy interface, but offering no more functionality
available via the service proxy interface.

Service providers are not the only Jini Community members who will face
UI-related temptations in the years ahead; client providers may also be tempted
to pass client context data to UI objects.

For example, a client provider wishing to differentiate his or her product
from the competition might add a toolbar and status bar to the client program.
The client provider might be tempted to define interfaces that allow the client
to pass references to the toolbar and status bar to the UI. Alternatively, the
client might be tempted to define new factory interfaces whose factory methods
include parameters that allow the client to pass references to the toolbar and
status bar to the factory, which could then pass it along to the UI. UIs that
obtain references to the toolbar and status bar in either of these two ways
could then put buttons on the toolbar and write messages to the status bar.

The trouble lurking behind this seemingly innocuous value-add is that the
toolbar and status bar references represent client context data, which complicates
the UI providers' jobs. If other clients devise their own toolbar and status
bar interfaces, and perhaps even up the ante by also defining other client
context innovations, UI providers will have to worry about which kinds of
client context to support. To the extent a UI provider supports various kinds
of client context, that UI provider's test matrix will expand. To the extent
that client context becomes complicated, such as the invention of a general
compound document model for Jini Service UIs, everyone's job, and the user's
experience, become more complicated.

Client providers, therefore, should avoid the temptation to invent client
context for Jini Service UIs. The only context data that should be passed to UI
factory methods is context a UI toolkit requires, such as the Frame or Window
reference required by an AWT Dialog. Similarly, the only context in which Jini
Service UIs should be embedded is context the toolkit provides. For example, a
client could embed a Jini Service UI JComponent in a JFrame, and
then pop up the JFrame.
The JComponent's ability to embed
is provided by its toolkit, Swing.

UI providers can do their part by ensuring that their UIs don't depend on
any context other than that provided by the UI toolkit. Jini Service UIs should
be self-contained and care only about the context of their toolkit. If a UI
provider wants its UI to write messages to a status bar, the UI should not look
for a status bar provided by the client, the UI should itself include a status
bar.

7. Add Third-Party UIs

To add a third-party UI to an existing service's attribute sets, you must
have the service's cooperation. The service can veto your request at any of
several points in the process. The steps are:

Check to see if the service
proxy implements net.jini.admin.Administrable
(Administrable).

If the service proxy does not implement Administrable,
the service provider has already thwarted your wishes. You won't be able to add
a third-party UI directly to the service item's attribute sets.

Cast the service proxy to Administrable
and invoke getAdmin().

Check to see if the admin
object returned by getAdmin()
implements the net.jini.admin.JoinAdmin
(JoinAdmin).

If the admin object does not implement JoinAdmin, the
service provider has thwarted your wishes. You won't be able to add a
third-party UI directly to the service item's attribute sets.

Cast the service proxy to JoinAdmin,
and invoke appropriate methods to add or modify one or more UIDescriptors.

You add or modify UIDescriptors in the same manner as
you would add or modify any kind of Entry in the service's attribute sets.
The JoinAdmin's
addLookupAttribute()
method lets you add new UIDescriptors.
Its modifyLookupAttribute()
method lets you modify existing UIDescriptors. Once again, the service provider
can veto your request, even at this step, by throwing an exception from these
methods.

Once a new UIDescriptor
for a third-party UI is successfully added via the process described
previously, the third party won't need to add it again. From that point
forward, whenever a service registers itself with a lookup service, its service
item will include the third-party UIDescriptor. It will also reregister
itself with any lookup services with which it is currently registered, so that
the new UIDescriptor
will appear there as well. Even if the service provider crashes and restarts,
it should remember the new UIDescriptor and include it in its registrations
after the crash and restart.

On the other hand, the UI, UI factory, and possibly the attributes require
class files to be available in some codebase. Although the third party never
needs to worry about the UIDescriptor
being included in future service registrations, the third party must make sure
the class files are forever available at some codebase.

One potential problem with adding a third-party UI is that in a strict
client-side security policy, downloaded code will by default only have
permission to connect back to the host from which the code was downloaded. In
that case, if the third-party UI's codebase is on a different host than the
service proxy's codebase, the service proxy won't be allowed to talk back to
its host at the behest of the UI. Therefore, for a third-party UI to work in
practice, either the third-party UI's codebase must be on the same host that
serves the service's codebase, or the client must specifically relax its
security policy in order to use the third-party UI.

8. Evolution and Prior Knowledge

In the future, the Service UI API can evolve in several different ways. Any
party can define new role types and their meanings, new attribute classes, and
new factory types. Any party can identify new toolkit types. For clients to be
able to use these new types, the new types will need to be publicized. Before a
client will be able to use a role, factory, or attribute type, that client's
programmers must have had prior knowledge of the type.

Other than service-specific UI roles created under Jini Service APIs, new
roles should come from the Service UI project at the Jini Community. Service
providers should resist temptation to define new role types, as that
complicates clients' jobs. Clients should be able to program to the interface
(particular Jini Service APIs about which they have prior knowledge), rather
than be forced to program to one or more implementations of that interface.
Whether role types are being defined for particular Jini Service APIs, or
globally for the Jini Service UI API, the preferred way to define the role
interfaces is via the Jini Community Process.

As mentioned previously, new UI factory interface types should be defined
with great care. The main justification for a new set of UI factory types is
when new UI toolkits appear on the scene. The preferred way to define these
interfaces is via the Jini Community Process. Similarly, although anyone can
define new attribute types, the preferred way to define these types is through
the Jini Community Process.

The Jini Community is the preferred process to define new role, factory, and
attribute types because it is the best way to avoid a explosion of types. For
example, if a certain attribute type is needed, and twenty different parties
define basically the same attribute, but with twenty slightly different names
and behaviors, and in twenty different packages, then clients wanting to use
that kind of attribute would need to support all twenty variations. It would be
far better if those twenty parties agreed on one attribute class. Enabling such
collaborations is the Jini Community's main purpose. If twenty parties can agree
upon one attribute class, then clients need to be aware of less
information (one attribute class versus twenty), and the resulting client
programs would likely work more reliably.

9. Consistent Serialized Forms

Because the Jini lookup service uses exact matching of the serialized forms of entry fields, it is critical that fields that will be used in template lookups have serialized forms that are consistent across all virtual machines. However, there is no guarantee that implementations of the Set interface, the declared type of the attributes field of UIDescriptor, have consistent serialized forms across all virtual machines. For example, java.util.HashSet, perhaps the most commonly used implementation of Set, does not guarantee a consistent serialized form. As a result, if a UIDescriptor that contains a HashSet in its attributes field is retrieved from a Jini lookup service, the serialized a form of the attributes field could be different if the UIDescriptor is reserialized as part of a template. This means that a UIDescriptor, when retrieved from a Jini lookup service and used immediately in a lookup template, may not match itself.

The Service UI API was defined under the assumption that
UIDescriptors in
Jini lookup templates might contain non-nullrole and toolkit fields, but
would always contain null in their
attributes and factory fields.
It was expected that attributes could be inspected on the client side to
select between multiple matches of a Jini lookup. Once a
UIDescriptor was selected, it was expected that clients would use
the factory field to produce the selected UI. Because of
these assumptions, the UIDescriptor class was not designed to
ensure a template in which all four fields were non-null
would work. In other words, the designers were aware that the
attributes field could not be used in lookup templates,
but did not imagine that anyone would ever need to do that.

When used in templates intended for basic lookup of Jini services,
UIDescriptors will likely never have non-nullattributes fields. Nevertheless, UIDescriptors
used in templates intended to modify the attribute sets of
already-registered Jini services could very likely contain
non-nullattributes fields. For example,
to add an object to the attributes set of a
UIDescriptor already registered as part
particular Jini service item, you must pass a template UIDescriptor
that exactly matches the registered UIDescriptor in
the attrSetTemplates parameter of either:

modifyAttributes method of net.jini.core.lookup.ServiceRegistration

modifyLookupAttributes method of net.jini.admin.ServiceRegistration

Unfortunately, the use case of modifying a UIDescriptor in
an already-registered Jini service item was never considered during the initial
design discussions leading to 1.0 release of the Service UI API. To
address this need, the 1.1 version of this specification narrows slightly
the contracts of these methods and constructors:

The 1.1 specification adds to the contracts of each of these constructors
a requirement that they copy the contents of the passed Set
or Map into a serializable read-only version that has a consistent serialized
form across all VMs. This new requirement yields the desired behavior when
attempting to modify UIDescriptors already part of service items registered in lookup
services.

10. Package net.jini.lookup.entry

The Service UI API defines two classes, UIDescriptor and UIDescriptorBean,
that were placed in a pre-existing package,
net.jini.lookup.entry.
This specification does not provide a complete specification of
the net.jini.lookup.entry package. It does, however,
provide a complete specification of classes
net.jini.lookup.entry.UIDescriptor and
net.jini.lookup.entry.UIDescriptorBean.

10.1. Class net.jini.lookup.entry.UIDescriptor

public class UIDescriptor
extends net.jini.entry.AbstractEntry

Entry that enables a UI for a service to be associated
with the service in the attribute sets of the service item.
UIDescriptor holds a marshalled UI factory object, as
well as a role string, a sub-role string, and set of attributes that describe the
UI generated by the factory.

Constructs a UIDescriptor with the fields set to passed values.
This constructor copies the contents of the passed attributes Set into a
serializable read-only Set that has a
consistent serialized form across all VMs, and initializes the attributes
field with the consistent Set.

Parameters:

role - the role

toolkit - the toolkit

attributes - the attributes

factory - the factory

10.1.3. Field role

public role

Gives the fully qualified name of the interface that represents
the role of the UI generated by the marshalled UI factory.
If the client program unmarshals the UI factory and invokes a factory method, the
UI returned by the factory method must implement the role the interface specified by
role.

For a client program to be able to use a UI, the client has to have prior knowledge
of the UI semantics, which is defined by the UI's role type. Thus, for a client
to be able to use a UI, the client must understand the semantics
of the type whose fully qualified name is given in the String
referenced from the role field of that UI's UIDescriptor.

For example, two role types that are defined in the net.jini.lookup.ui
package by the Jini Service UI Specification are MainUI, for a main UI
to a Jini service, and AdminUI, for an administration UI. Other role types
may be defined by the Jini Service UI Specification and by individual Jini service API
specifications.

As the strings referenced from the role field are Java type names, they
are intended to be manipulated by client programs only. They should not be shown to a user.

10.1.4. Field toolkit

public toolkit

A String to facilitate searching whose value represents the main UI toolkit (for example
Swing or AWT) which the produced UI makes use of. The value to which this field should
be set is defined by the semantics of the factory type. (This field is intended
to facilitate searches. For example, a client can search for all blender services that have Swing
MainUI's.)

10.1.5. Field attributes

public attributes

A set of objects that describe the UI generated by the marshalled UI factory.

10.1.6. Field factory

public factory

The get() method of this MarshalledObject
must return an object that implements one or more UI factory interfaces. The actual
UI factory type or types implemented by the returned object
must be described by a UIFactoryTypes attribute placed in
the attributes set of this UIDescriptor.

10.1.7. Method getUIFactory(java.lang.ClassLoader)

A convenience method for unmarshalling the UI factory stored
in the MarshalledObject referenced from the
factory field. This method saves a reference
to the current context class loader, sets the context class loader
to the class loader passed as parentLoader, invokes
get() on the marshalled object, then resets the
context class loader to the saved reference before returning
the object produced by get().

The class loader
passed in parentLoader should be able to load classes
needed when the UI interacts with the roleObject passed as the first
parameter to the factory method. For example, if the roleObject is
the service item (as it is for the MainUI and AdminUI
roles), the class loader passed in parentLoader could be
the class loader with which the service proxy object referenced
from the service item's service field was loaded.
For example:

10.1.8. Serialized Form of net.jini.lookup.entry.UIDescriptor

10.1.8.1. Serialized Field role

java.lang.String role

Gives the fully qualified name of the interface that represents
the role of the UI generated by the marshalled UI factory.
If the client program unmarshals the UI factory and invokes a factory method, the
UI returned by the factory method must implement the role the interface specified by
role.

For a client program to be able to use a UI, the client has to have prior knowledge
of the UI semantics, which is defined by the UI's role type. Thus, for a client
to be able to use a UI, the client must understand the semantics
of the type whose fully qualified name is given in the String
referenced from the role field of that UI's UIDescriptor.

For example, two role types that are defined in the net.jini.lookup.ui
package by the Jini Service UI Specification are MainUI, for a main UI
to a Jini service, and AdminUI, for an administration UI. Other role types
may be defined by the Jini Service UI Specification and by individual Jini service API
specifications.

As the strings referenced from the role field are Java type names, they
are intended to be manipulated by client programs only. They should not be shown to a user.

10.1.8.2. Serialized Field toolkit

java.lang.String toolkit

A String to facilitate searching whose value represents the main UI toolkit (for example
Swing or AWT) which the produced UI makes use of. The value to which this field should
be set is defined by the semantics of the factory type. (This field is intended
to facilitate searches. For example, a client can search for all blender services that have Swing
MainUI's.)

10.1.8.3. Serialized Field attributes

java.util.Set attributes

A set of objects that describe the UI generated by the marshalled UI factory.

10.1.8.4. Serialized Field factory

java.rmi.MarshalledObject factory

The get() method of this MarshalledObject
must return an object that implements one or more UI factory interfaces. The actual
UI factory type or types implemented by the returned object
must be described by a UIFactoryTypes attribute placed in
the attributes set of this UIDescriptor.

10.2.1. Constructor UIDescriptorBean()

Construct a new JavaBeans component, linked to a new empty UIDescriptor object.

10.2.2. Field assoc

protected assoc

The UIDescriptor object associated with this JavaBeans component.

10.2.3. Method makeLink(net.jini.core.entry.Entry)

public void makeLink(net.jini.core.entry.Entry e)

Make a link to a UIDescriptor object.

Parameters:

e - the Entry object, which must be a UIDescriptor, to which to link

Throws:

java.lang.ClassCastException - the Entry is not
a UIDescriptor, the correct type for this JavaBeans component

10.2.4. Method followLink()

public net.jini.core.entry.Entry followLink()

Return the UIDescriptor linked to by this JavaBeans component.

10.2.5. Method getRole()

public java.lang.String getRole()

Return the value of the role field in the object linked to by
this JavaBeans component.

10.2.6. Method setRole(java.lang.String)

public void setRole(java.lang.String role)

Set the value of the role field in the object linked to by this
JavaBeans component.

Parameters:

role - a String specifying the role value

10.2.7. Method getToolkit()

public java.lang.String getToolkit()

Return the value of the toolkit field in the object linked to by
this JavaBeans component.

10.2.8. Method setToolkit(java.lang.String)

public void setToolkit(java.lang.String toolkit)

Set the value of the toolkit field in the object linked to by this
JavaBeans component.

Parameters:

toolkit - a String specifying the toolkit value

10.2.9. Method getAttributes()

public java.util.Set getAttributes()

Return the value of the attributes field in the object linked to by
this JavaBeans component.

10.2.10. Method setAttributes(java.util.Set)

public void setAttributes(java.util.Set attributes)

Set the value of the attributes field in the object linked to by this
JavaBeans component.

Parameters:

attributes - a Set specifying the attributes value

10.2.11. Method getFactory()

public java.rmi.MarshalledObject getFactory()

Return the value of the factory field in the object linked to by
this JavaBeans component.

10.2.12. Method setFactory(java.rmi.MarshalledObject)

public void setFactory(java.rmi.MarshalledObject factory)

Set the value of the factory field in the object linked to by this
JavaBeans component.

Parameters:

factory - a MarshalledObject specifying the factory value

10.2.13. Serialized Form of net.jini.lookup.entry.UIDescriptorBean

10.2.13.1. Serialized Field assoc

net.jini.lookup.entry.UIDescriptor assoc

The UIDescriptor object associated with this JavaBeans component.

11. Package net.jini.lookup.ui

Provides UI role interfaces used to associate service UIs with Jini services.

11.1. Summary of Interfaces In Package net.jini.lookup.ui

AboutUI - UI role interface implemented by About UIs, which enable users to
view (or in some way experience) information about a service.

AdminUI - UI role interface implemented by Admin UIs,
which enable users to administer a service.

MainUI - UI role interface implemented by Main UIs,
which enable client programs to grant users general access to a service.

11.2. Summary of Classes In Package net.jini.lookup.ui

No classes are declared in package net.jini.lookup.ui.

11.3. Summary of Exceptions In Package net.jini.lookup.ui

No Exceptions are declared in package net.jini.lookup.ui.

11.4. Summary of Errors In Package net.jini.lookup.ui

No Errors are declared in package net.jini.lookup.ui.

11.5. Interface net.jini.lookup.ui.AboutUI

public interface AboutUI

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 a 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 an
object called the "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
with which the About UI is associated.

About UIs should allow clients to configure them before they
begin. For example, About UIs produced by FrameFactory,
JFrameFactory, WindowFactory
and JWindowFactory (all members of the net.jini.lookup.ui.factory package)
should not be visible when they are returned 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 About UI factory method multiple times sequentially. In other words, if a user
uses a service via a About UI, then says exit, then double clicks once again on the service icon,
the client can just simply invoke a UI factory method again, and get another About UI for the same
service. About UIs, therefore, should be written so that they work no matter what state
the service object happens to be in when the About UI is created.

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

11.5.1. Field ROLE

public static final ROLE

Convenience constant to use in the role
field of UIDescriptors for AboutUI role UIs.
The value of this constant is "net.jini.lookup.ui.AboutUI".

11.6. Interface net.jini.lookup.ui.AdminUI

public interface AdminUI

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 a 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 an
object called the "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
with which the Admin UI is associated.

Admin UIs should allow clients to configure them before they
begin. For example, Admin UIs produced by FrameFactory,
JFrameFactory, WindowFactory
and JWindowFactory (all members of the net.jini.lookup.ui.factory package)
should not be visible when they are returned 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 Admin UI factory method multiple times sequentially. In other words, if a user
uses a service via a Admin UI, then says exit, then double clicks once again on the service icon,
the client can just simply invoke a UI factory method again, and get another Admin UI for the same
service. Admin UIs, therefore, should be written so that they work no matter what state
the service object happens to be in when the Admin UI is created.

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

11.6.1. Field ROLE

public static final ROLE

Convenience constant to use in the role
field of UIDescriptors for AdminUI role UIs.
The value of this constant is "net.jini.lookup.ui.AdminUI".

11.7. Interface net.jini.lookup.ui.MainUI

public interface MainUI

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 an
object called the "role object."
Any factory method that produces an Main UI must accept as the role object the
service item (the net.jini.core.lookup.ServiceItem) of the service
with which the Main UI is associated.

Main UIs should allow clients to 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 are returned 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 says exit, then double clicks once again on the service icon,
the client can just simply invoke a UI factory method again, and get another Main UI for the same
service. Main UIs, therefore, should be written so that they work no matter what state
the service object happens to be in when the Main UI is created.

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

11.7.1. Field ROLE

public static final ROLE

Convenience constant to use in the role
field of UIDescriptors for MainUI role UIs.
The value of this constant is "net.jini.lookup.ui.MainUI".

12. Package net.jini.lookup.ui.factory

Provides UI factory interfaces used to associate service UIs with Jini services.

12.1. Summary of Interfaces In Package net.jini.lookup.ui.factory

DialogFactory - UI factory for a modal or non-modal AWT Dialog with a
predetermined title.

FrameFactory - UI factory for an AWT Frame with a predetermined
title.

JComponentFactory - UI factory for a Swing JComponent.

JDialogFactory - UI factory for a modal or non-modal Swing JDialog
with a predetermined title.

JFrameFactory - UI factory for a Swing JFrame with a predetermined
title.

JWindowFactory - UI factory for a Swing JWindow.

PanelFactory - UI factory for an AWT Panel.

WindowFactory - UI factory for an AWT Window that isn't a Frame
or a Dialog.

12.2. Summary of Classes In Package net.jini.lookup.ui.factory

No classes are declared in package net.jini.lookup.ui.factory.

12.3. Summary of Exceptions In Package net.jini.lookup.ui.factory

No Exceptions are declared in package net.jini.lookup.ui.factory.

12.4. Summary of Errors In Package net.jini.lookup.ui.factory

No Errors are declared in package net.jini.lookup.ui.factory.

12.5. Interface net.jini.lookup.ui.factory.DialogFactory

public interface DialogFactory
extends java.io.Serializable

UI factory for a modal or non-modal AWT Dialog with a
predetermined title.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.5.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
DialogFactory.
The value of this constant is "java.awt".

12.5.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a DialogFactory.
The value of this constant is "net.jini.lookup.ui.factory.DialogFactory".

12.5.6. Method getDialog(java.lang.Object, java.awt.Frame, boolean)

Returns a Dialog with predetermined title and the
specified modality and owner Frame.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

owner - the Frame to act as owner of the returned
Dialog

modal - if true, the returned Dialog will block
input to other windows when shown

12.6. Interface net.jini.lookup.ui.factory.FrameFactory

public interface FrameFactory
extends java.io.Serializable

UI factory for an AWT Frame with a predetermined
title.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.6.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
FrameFactory.
The value of this constant is "java.awt".

12.6.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a FrameFactory.
The value of this constant is "net.jini.lookup.ui.factory.FrameFactory".

12.6.3. Method getFrame(java.lang.Object)

public java.awt.Frame getFrame(java.lang.Object roleObject)

Returns a Frame with predetermined title.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

12.7. Interface net.jini.lookup.ui.factory.JComponentFactory

public interface JComponentFactory
extends java.io.Serializable

UI factory for a Swing JComponent.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.7.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
JComponentFactory.
The value of this constant is "javax.swing".

12.7.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a JComponentFactory.
The value of this constant is "net.jini.lookup.ui.factory.JComponentFactory".

12.7.3. Method getJComponent(java.lang.Object)

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

12.8. Interface net.jini.lookup.ui.factory.JDialogFactory

public interface JDialogFactory
extends java.io.Serializable

UI factory for a modal or non-modal Swing JDialog
with a predetermined title.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.8.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
JDialogFactory.
The value of this constant is "javax.swing".

12.8.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a JDialogFactory.
The value of this constant is "net.jini.lookup.ui.factory.JDialogFactory".

12.8.3. Method getJDialog(java.lang.Object)

public javax.swing.JDialog getJDialog(java.lang.Object roleObject)

Returns a non-modal JDialog with
predetermined title and no specified owner.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

12.8.7. Method getJDialog(java.lang.Object, java.awt.Frame, boolean)

Returns a JDialog with predetermined title and the
specified modality and owner Frame.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

owner - the Frame to act as owner of the returned
JDialog

modal - if true, the returned JDialog will block
input to other windows when shown

12.9. Interface net.jini.lookup.ui.factory.JFrameFactory

public interface JFrameFactory
extends java.io.Serializable

UI factory for a Swing JFrame with a predetermined
title.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.9.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
JFrameFactory.
The value of this constant is "javax.swing".

12.9.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a JFrameFactory.
The value of this constant is "net.jini.lookup.ui.factory.JFrameFactory".

12.9.3. Method getJFrame(java.lang.Object)

public javax.swing.JFrame getJFrame(java.lang.Object roleObject)

Returns a JFrame with predetermined title.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

12.10. Interface net.jini.lookup.ui.factory.JWindowFactory

public interface JWindowFactory
extends java.io.Serializable

UI factory for a Swing JWindow.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.10.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
JWindowFactory.
The value of this constant is "javax.swing".

12.10.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a JWindowFactory.
The value of this constant is "net.jini.lookup.ui.factory.JWindowFactory".

12.10.3. Method getJWindow(java.lang.Object)

public javax.swing.JWindow getJWindow(java.lang.Object roleObject)

Returns a JWindow with no specified
owner.

Parameters:

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

12.10.5. Method getJWindow(java.lang.Object, java.awt.Frame)

roleObject - an object defined by the semantics of the UI role interface
implemented by the returned UI object. (UI role is indicated in the
role field of UIDescriptors.)

owner - the Frame to act as owner of the returned
JWindow

12.11. Interface net.jini.lookup.ui.factory.PanelFactory

public interface PanelFactory
extends java.io.Serializable

UI factory for an AWT Panel.

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

A PreferredTitle may be placed in the attributes set to indicate
a preferred title of a pop-up window containing this component.

12.11.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
PanelFactory.
The value of this constant is "java.awt".

12.11.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a JPanelFactory.
The value of this constant is "net.jini.lookup.ui.factory.PanelFactory".

12.11.3. Method getPanel(java.lang.Object)

public java.awt.Panel getPanel(java.lang.Object roleObject)

Returns a Panel.

12.12. Interface net.jini.lookup.ui.factory.WindowFactory

public interface WindowFactory
extends java.io.Serializable

UI factory for an AWT Window that isn't a Frame
or a Dialog.
AWT Frames should be produced by a FrameFactory.
AWT Dialogs should be produced by a DialogFactory.)

If the UI generated by the method declared in this interface implements
javax.accessibility.Accessible and supports the Java Accessibility
API, an AccessibleUI attribute
should be placed in the UIDescriptor's attributes set.

12.12.1. Field TOOLKIT

public static final TOOLKIT

Convenience constant to use in the toolkit
field of UIDescriptors that contain a
WindowFactory.
The value of this constant is "java.awt".

12.12.2. Field TYPE_NAME

public static final TYPE_NAME

Convenience constant to use in the UIFactoryTypes
set in the attributes set of UIDescriptors
that contain a WindowFactory.
The value of this constant is "net.jini.lookup.ui.factory.WindowFactory".

13. Package net.jini.lookup.ui.attribute

Provides attribute classes used to associate service UIs with Jini services.

13.1. Summary of Interfaces In Package net.jini.lookup.ui.attribute

No interfaces are declared in package net.jini.lookup.ui.attribute.

13.2. Summary of Classes In Package net.jini.lookup.ui.attribute

AccessibleUI - UI attribute that indicates a generated
UI implements the the javax.accessibility.Accessible interface
and that the designer of the UI did the necessary work to make sure the UI
would work well with assistive technologies that are aware of the Java Accessibility API.

Locales - UI attribute that lists the locales supported
by a generated UI.

RequiredPackages - UI attribute that enables clients to get a list of
the fully qualified names and version numbers of packages
required by a UI.

UIFactoryTypes - UI attribute that lists UI factory interfaces of which a UI factory
is an instance.

13.3. Summary of Exceptions In Package net.jini.lookup.ui.attribute

No Exceptions are declared in package net.jini.lookup.ui.attribute.

13.4. Summary of Errors In Package net.jini.lookup.ui.attribute

No Errors are declared in package net.jini.lookup.ui.attribute.

13.5. Class net.jini.lookup.ui.attribute.AccessibleUI

UI attribute that indicates a generated
UI implements the the javax.accessibility.Accessible interface
and that the designer of the UI did the necessary work to make sure the UI
would work well with assistive technologies that are aware of the Java Accessibility API.

Only UIDescriptors whose marshalled UI factory produces
a UI that supports the Accessibility API should include this attribute.
The presence of this attribute in an attribute set means the produced
UI will work well with assistive technologies that are aware of the Java
Accessibility API.

13.5.1. Constructor AccessibleUI()

public AccessibleUI()

Constructs a new AccessibleUI attribute.

13.5.2. Method equals(java.lang.Object)

public boolean equals(java.lang.Object o)

Compares the specified object (passed in o) with this
AccessibleUI object for equality. Returns true if
o is non-null and the fully qualified class name of the specified object (passed
in o) is the same as the fully qualified class name of this object.

Parameters:

o - the object to compare against

13.5.3. Method hashCode()

public int hashCode()

Returns the hash code value for this AccessibleUI. As
all AccessibleUI objects are conceptually equivalent, this
method returns the hash code value for this object's fully qualified
class name String.

13.5.4. Serialized Form of net.jini.lookup.ui.attribute.AccessibleUI

Serialized form of class
net.jini.lookup.ui.attribute.AccessibleUI
has no serialized fields.

13.6. Class net.jini.lookup.ui.attribute.Locales

13.6.1. Constructor Locales(java.util.Set)

public Locales(java.util.Set locales)

Constructs a Locales using the
passed Set. The Set can
be mutable or immutable, and must contain only
java.util.Locale objects. Each Locale must
represent a locale that is supported by the UI generated
by the UI factory stored in marshalled form in the
same UIDescriptor. This constructor copies
the contents of the passed Set into a
serializable read-only Set that has a
consistent serialized form across all VMs.

Parameters:

locales - A Set of Locale
objects. Each element must be non-null and an instance
of java.util.Locale.

Throws:

NullPointerException - if locales
is null or any element of locales
set is null.

IllegalArgumentException - if any non-null element of
locales set is not an instance of
java.util.Locale.

13.6.2. Method isLocaleSupported(java.util.Locale)

public boolean isLocaleSupported(java.util.Locale locale)

Indicates whether or not a locale is supported
by the UI generated by the UI factory stored in
the marshalled object of the same UIDescriptor.
This method returns true only if the passed
Locale exactly matches a Locale
supported by the UI, as defined by the equals()
method of class java.util.Locale. For example, imagine the UI supports the
"en" (General English) locale, but not the "en_US" (US English) locale.
Then, if "en_US" is passed to this method, the method will return
false.

Parameters:

locale - the locale to check

Throws:

NullPointerException - if locale
is null.

13.6.3. Method getFirstSupportedLocale(java.util.Locale[])

Looks through the passed array of Locales
(in the order they appear in the array)
and returns the first Locale that is
supported by the UI (as defined by isLocaleSupported()),
or null, if none of the Locales in
the passed array are supported by the UI.

Parameters:

locales - an array of locales in order of most desired to
least desired

Throws:

NullPointerException - if locales
is null.

13.6.4. Method getFirstSupportedLocale(java.util.List)

Iterates through the passed List of Locales
and returns the first Locale that is
supported by the UI (as defined by isLocaleSupported()),
or null, if none of the Locales in
the passed array are supported by the UI.

Parameters:

locales - a List of locales in order of most
desired to least desired

Throws:

NullPointerException - if locales
is null.

13.6.5. Method iterator()

public java.util.Iterator iterator()

Returns an iterator over the set of java.util.Locale
objects, one for each locale supported
by the UI generated by the UI factory stored in
the marshalled object of the same UIDescriptor.
The returned Iterator does not support
remove().

13.6.6. Method getLocales()

public java.util.Set getLocales()

Returns an unmodifiable java.util.Set that contains
java.util.Locale objects, one for each locale supported
by the UI generated by the UI factory stored in
the marshalled object of the same UIDescriptor.

13.6.7. Method equals(java.lang.Object)

public boolean equals(java.lang.Object o)

Compares the specified object (the Object passed
in o) with this Locales
object for equality. Returns true if the specified object
is not null, if the specified object's class is
Locales, if the two sets of
supported locales are the same size, and if every locale mentioned in the
specified Locales object (passed in o) is also mentioned
in this Locales object.

Parameters:

o - the object to compare against

13.6.8. Method hashCode()

public int hashCode()

Returns the hash code value for this Locales object.

13.6.9. Serialized Form of net.jini.lookup.ui.attribute.Locales

13.6.9.1. Serialized Field supportedLocales

java.util.Set supportedLocales

A Set of java.util.Locale objects,
each of which represents one locale supported by the UI generated
by the UI factory stored in marshalled form in the same
UIDescriptor.

13.7. Class net.jini.lookup.ui.attribute.RequiredPackages

UI attribute that enables clients to get a list of
the fully qualified names and version numbers of packages
required by a UI.

One or more RequiredPackages attributes may appear
in the attributes of a UIDescriptor. Client programs
interested in a UI may wish to verify that they have all required
packages mentioned in the RequiredPackages attributes
(if any) contained in the UI's UIDescriptor, before
they attempt to create the UI. If the client is lacking any required
packages (either because the entire package is absent or because the
package is present but of an incompatible version), the client will
not be able to use the UI,

The intent of this attribute is to provide a quick way for a client program
to determine that a UI is unusable by a client, not to grant a guarantee that a UI
is definitely usable by the client. If a client is missing a required package,
or has an incompatible version of a required package, the client cannot use the UI.
But if the client has compatible versions of all required packages listed in a
RequiredPackage attribute, the client may or may not be able to
use the UI.

UI providers should take bold and valiant strides to list in a RequiredPackage
attribute all known packages required of the client, so that if
the client discovers it has compatible versions of all listed packages and
attempts to generate the UI via the factory method, the client will likely
succeed. However, client programmers should bear in mind that a
RequiredPackage attribute doesn't necessarily list
all required packages. As a result, satisfying all required packages
doesn't absolutely guarantee the UI will work on the client.
As a result, client programs should program defensively.
(For example, clients should probably catch LinkageError
in appropriate places when dealing with UIs, even if they find they have
compatible versions of all required packages listed in RequiredPackage
attributes.)
The version numbers must take the form of "specification version numbers," as used
by the java.lang.Package class:

Specification version numbers use a "Dewey Decimal" syntax that consists of positive
decimal integers separated by periods ".", for example, "2.0" or "1.2.3.4.5.6.7". This
allows an extensible number to be used to represent major, minor, micro, etc versions.
The version number must begin with a number.

13.7.1. Constructor RequiredPackages(java.util.Map)

public RequiredPackages(java.util.Map packages)

Constructs a RequiredPackages attribute
with the passed Map. The keys contained
in the passed Map must be Strings
that represent fully qualified names of required packages.
Each value contained in the passed Map must
be the oldest version number of the package (defined by the
key) that is compatible with the UI. Version numbers are
Strings in the form of
"specification version numbers," as used
by the java.lang.Package class. This constructor copies
the contents of the passed Map into a
serializable unmodifiable Map that has a
consistent serialized form across all VMs.

Parameters:

packages - a map of String fully qualified
names of required packages to String version
numbers

Throws:

NullPointerException - if packages
is null or if any keys or values contained
in packages are null.

IllegalArgumentException - if any non-null key or
value contained in packages set is not an instance of
java.lang.String.

13.7.2. Method iterator()

public java.util.Iterator iterator()

Returns an iterator over the set of String
fully qualified package names required
by the UI generated by the UI factory stored in
the marshalled object of the same UIDescriptor.
The returned Iterator does not support
remove().

13.7.3. Method getVersion(java.lang.String)

public java.lang.String getVersion(java.lang.String packageName)

Returns a version number for the required package
whose fully qualified package name is passed as
the packageName parameter. If the
passed String does not represent a
required package listed in this RequiredPackage
attribute, this method returns null.
The version number returned should be a "specification version number," as used
by the java.lang.Package class:

Specification version numbers use a "Dewey Decimal" syntax that consists of positive
decimal integers separated by periods ".", for example, "2.0" or "1.2.3.4.5.6.7". This
allows an extensible number to be used to represent major, minor, micro, etc versions.
The version number must begin with a number.

Throws:

NullPointerException - if packageName
is null.

13.7.4. Method getRequiredPackages()

public java.util.Map getRequiredPackages()

Returns a java.util.Map whose keys
are Strings that represent fully
qualified names of required packages and whose
values are be the oldest version number of the
package (defined by the
key) that is compatible with the UI. Version numbers are
Strings in the form of
"specification version numbers," as used
by the java.lang.Package class:
The version numbers contained as values in the returned Map
should be a "specification version number," as used
by the java.lang.Package class:

Specification version numbers use a "Dewey Decimal" syntax that consists of positive
decimal integers separated by periods ".", for example, "2.0" or "1.2.3.4.5.6.7". This
allows an extensible number to be used to represent major, minor, micro, etc versions.
The version number must begin with a number.

13.7.5. Method equals(java.lang.Object)

public boolean equals(java.lang.Object o)

Compares the specified object (the Object passed
in o) with this RequiredPackages
object for equality. Returns true if the specified object
is not null, if the specified object's class is
RequiredPackages, if the two sets of
package-version pairs are the same size, and if every package-version pair mentioned in the
specified RequiredPackages object (passed in o) is also mentioned
in this RequiredPackages object.

Parameters:

o - the object to compare against

13.7.6. Method hashCode()

public int hashCode()

Returns the hash code value for this RequiredPackages object.

13.7.7. Serialized Form of net.jini.lookup.ui.attribute.RequiredPackages

13.7.7.1. Serialized Field requiredPackages

java.util.Map requiredPackages

A Map of String keys to
String values. The keys contained
in the Map must be Strings
that represent fully qualified names of required packages.
Each value contained in the Map must
be the oldest version number of the package (defined by the
key) that is compatible with the UI. Version numbers are
Strings in the form of "specification version
numbers," as used by the java.lang.Package class.

13.8. Class net.jini.lookup.ui.attribute.UIFactoryTypes

UI attribute that lists UI factory interfaces of which a UI factory
is an instance.

13.8.1. Constructor UIFactoryTypes(java.util.Set)

public UIFactoryTypes(java.util.Set typeNames)

Constructs a UIFactoryTypes attribute using the
passed Set. The Set can
be mutable or immutable, and must contain only
Strings. Each String should
represent a fully qualified Java type name of a UI factory
interface. This constructor copies
the contents of the passed Set into a
serializable read-only Set that has a
consistent serialized form across all VMs.

The isAssignableTo method of this class will only
return true for types whose names are passed
explicitly to this constructor via the typeNames parameter.
This constructor does not inspect the inheritance hierarchies of the
types whose names are passed via the typeNames
parameter. It is the client's responsibility to include the name of
every UI factory interface of which the relevant UI factory (the UI factory being described
by this class) is an instance.

Parameters:

typeNames - A Set of String
objects. Each element must be non-null and an instance
of java.lang.String.

Throws:

NullPointerException - if typeNames
is null or any element of typeNames
set is null.

IllegalArgumentException - if any non-null element of
typeNames set is not an instance of
java.lang.String.

13.8.2. Method isAssignableTo(java.lang.Class)

public boolean isAssignableTo(java.lang.Class classObj)

Returns true if the UI factory (contained in
marshalled form in the same UIDescriptor) is
an instance of the UI factory interface
type passed in parameter classObj.
Else, returns false.

This method compares the fully qualified name
of the type represented by the passed Class with
the fully qualified names of UI factory interfaces implemented
by the UI factory's class. If
an exact string match is found, this method returns true.
If the UI factory is ultimately loaded with a class loader whose
parent-delegation chain doesn't include the class loader
that defined the passed class, a type with the same name
would be loaded into a different namespace of
the virtual machine. If so, the two types would
be considered different by the virtual machine, even though
they shared the same fully qualified name.

Parameters:

classObj - the type to check

Throws:

NullPointerException - if classObj
is null

13.8.3. Method iterator()

public java.util.Iterator iterator()

Returns an iterator over the set of types of which
a UI factory object is an instance in no particular order.
The returned Iterator does not support
remove().

13.8.4. Method getTypeNames()

public java.util.Set getTypeNames()

Returns an unmodifiable Set of fully qualified type name
Strings of which
a UI factory is an instance in no particular order.

13.8.5. Method equals(java.lang.Object)

public boolean equals(java.lang.Object o)

Compares the specified object (the Object passed
in o) with this UIFactoryTypes
object for equality. Returns true if the specified object
is not null, if the specified object's class is
UIFactoryTypes, if the two sets of
factory types are the same size, and if every factory type mentioned in the
specified UIFactoryTypes object (passed in o) is also mentioned
in this UIFactoryTypes object.

Parameters:

o - the object to compare against

13.8.6. Method hashCode()

public int hashCode()

Returns the hash code value for this UIFactoryTypes object.

13.8.7. Serialized Form of net.jini.lookup.ui.attribute.UIFactoryTypes

13.8.7.1. Serialized Field typeNames

java.util.Set typeNames

A Set of Strings,
each of which represents one fully qualified type name.
Each String type name should indicate one
UI factory interface implemented by the UI factory contained
in marshalled form in the same UIDescriptor in
which this UIFactoryTypes appears.