Sponsored Link •
|
Advertisement
|
For the latest version of the specification, see: http://www.artima.com/jini/cyberspace/Spec.html.
URLLink
to URLFactoryLink
, and dropped
all constructors from it except the constructor that takes a String
URL. Added
ServiceURLLink
. Added DynamicLinkMap
, LinkMapListener
, and
LinkMapEvent
to support the idea of a place whose contents can change while the client
is using it. Added more text to description of ServicePresenter
.
Link
has only one method now, activate()
. Progress events are defined to indicate
major, not minor, percentages. Described changes to URLFactoryLink
, including a description
of URLFactory
. Changed the proposal for a fourth component of the jini:
URL to be the service ID rather than a URL name. Dropped the service context in favor of the
ServicePresenter
. Main change in this iteration is that Link
represents
a link to a Jini service item, not a "resource." All resources will be wrapped in Jini service objects,
yielding a more Jini-like view of the network: Everything on the network is a service. Every
service is represented by an object.
ResourceInfo
Interface." Mentioned
possibility of application/x-service
and .service
in section 9.1, "HTTP: URLs." Also, fixed a typo.
A new computer is on the horizon, a meta-computer made of up every computer connected to every other
computer. As embedded devices with high bandwidth network connections become increasingly common,
this new meta-computer may gradually supplant the desktop PC as the primary computer
people use. The coming change in the hardware status quo provides an opportunity to rethink the basic
user-interface metaphors by which people use software. This Jini Place
API
proposes a simple "space metaphor" by which users could relate to and use the services offered
by the emerging meta-computer.
Two fundamental metaphors currently dominate most people's experience of software: the desktop metaphor and the web metaphor. The abstraction that plays the starring role in both of these metaphors is the file.
The personality of a desktop computer is its hard disk, and the desktop metaphor primarily helps users manage files on disks. Users are told that some of those files are applications, the rest are documents. All files are represented by icons. If you double click on an application's icon, the application launches. If you double click on a document icon, an application is launched that opens the clicked-upon document.
Each document on the desktop is associated with an application. The application, which is the behavior that knows how to use the document's data, can be thought of as the document's type. The type of a document is usually indicated in some manner external to the document file contents. On Windows, for example, the document type is indicated by the three-character extension of the filename. The filename (and its extension) is known to the file system, but is not generally an intrinsic part of the file itself.
The World Wide Web popularized hypertext, a user-interface metaphor distinctly different from the desktop. Yet on the web, the fundamental unit is still the file. Rather than helping users manage files on nearby disks, however, the web helps people use files delivered by servers on in internet. Most files, but not all, show up as HTML web pages. As on the desktop, each file on the web has a type, which is external to the contents of the file itself. When an HTTP server sends a file, it includes a MIME type header that indicates the type of the file. The browser uses the file type to decide how to present the file to the user.
The browser understands certain MIME types, such as text/html
. For such types, the browser
itself is the behavior that knows how to use the file's data. If the browser receives a file with a MIME
type it doesn't understand, it looks around for a plug-in that understands the type. If it finds a
suitable plug-in, it passes the file to the plug-in, and the plug-in decides what to do. In this case,
the plug-in is the behavior that understands how to use the file.
In either case, the software that represents
the behavior for a particular file type must already reside on the client
side, either in the browser itself or as a plug-in.
In contrast to the desktop and web metaphors, where the fundamental abstraction is the file, the fundamental abstraction in the space metaphor is the object. In Jini, network-delivered services are represented by network-mobile objects. Each object has a class, which represents its type. In contrast to files, whose types in general external to the files themselves, the types of objects are intrinsic to the objects. The type is intrinsic because objects are a bundles of behavior. Many objects carry data in instance variables, but most objects keep that data private and use it to decide how to behave when their methods are invoked. The fundamental character of an object is its behavior.
To present the behavior of a service object to a human user, a user interface (UI) object can be inserted between the user and the service object. If the client has prior knowledge of the object's type, the UI object can be provided by the client. Alternatively, the UI object can be delivered across the network with the service. Such network-delivered UIs are called service UIs, because they are provided by the service. Here's a diagram from the Jini Service UI specification, which defines a standard way to associate UIs with Jini services. This diagram shows a user using a Jini service via a service UI:
Figure 1. A user interacts with a service via a UI object.
Although the service UI standard shows how users can interact with any individual
service, it doesn't address how users will interact with the set all
the services offered by the emerging meta-computer. The purpose of the Jini Place
API is to address this
second question: to provide users with a metaphor by which they interact with the meta-computer as a whole.
In the metaphor established by the Place
API, all services are represented by objects.
Objects are organized into places.
To do something on the meta-computer, users go to a place and use an object.
This "objects in places" metaphor encourages users to think of the meta-computer as a space.
Most users of the World Wide
Web already tend to think in spatial terms. You might hear someone say, "Jini.org is the main Jini web
site." Or, "Jini.org is now easier to navigate." Or, "If you want to start a Jini project,
go to Jini.org." The italicized words -- site, navigate, go to -- demonstrate the tendency for users
to form their own ad hoc space metaphor when thinking about the World Wide Web.
The Place
API formalizes this space metaphor.
Place
is a Jini service interface
that will enable service objects, in addition to whatever other services they
provide via their interface, to offer a "collection of links" service.
Thus, the conceptual objects and places that users interact with are both
implemented as network-mobile Jini service objects. To be a conceptual place, a Jini service need only
implement the Place
interface.
In the sense that they offer a "collection of links" service, Place
services are similar to web pages.
Two main characteristics distinguish a web page from a traditional page, such as a page from a book or magazine. First, a
web page is delivered across a network.
Second, a web page contains links to other resources on the network, primarily other web pages.
Both web pages and traditional pages offer information services, but a web page also offers a "collection
of links" service in addition to its information service.
The following diagram depicts the organization of the current World Wide Web. Each rectangle is a web page, which offers both an information service and a collection of links service. The links are depicted as arrows drawn from one web page to another.
Figure 2. The web is a graph of files.
Like web pages, Jini service objects offer network-delivered services. Whereas an individual web page offers primarily an information service, a collection of links service, and perhaps a form service, a Jini service object is more generic. A Jini service object offers the types of service inherent in the object's class. The services themselves are available via the object's interface. Any type of service for which an interface can be defined, therefore, could be delivered across the network as a Jini service object.
The Place
interface
enables service objects, in addition to whatever other services they
provide via their interface, to offer a "collection of links" service. The aim of Place
is to enable
the set of all services to be organized into a graph, as depicted in the following
diagram. In this diagram, the circles are Jini service objects, arrows show
links from one object to another.
Figure 3. The space is a graph of objects.
The space metaphor says that everything is a conceptual "object." Conceptual objects are implemented as network-mobile service objects, accessed by users via network-mobile service UIs. Every object has an intrinsic class, which defines the types of services offered by the object. Users and service providers organize objects by placing links to those objects in places. The existence of places on the network continues the "everything is an object" metaphor, because a place is just another type of object -- an object used to organize user relationships to other objects. As objects link to other objects, the graph organization shown in Figure 3 emerges.
One of the motivations of the Place
API is to give users a more seamless experience than
is possible with the web. Because the web is file-based, users must already have installed behavior that
understands the type of a network-mobile file. Because objects are behavior, network-mobile
objects can provide users with a more seamless experience of interacting network-delivered services.
Users needn't worry about installing plug-ins. They can just use the objects.
Given that the World Wide Web is rather popular, however, the Place
API includes a way
to wrap files in objects. Instead of plug-ins, files can be viewed with network-mobile service UIs.
The space metaphor subsumes the web metaphor, because in the space metaphor, web pages become a special
kind of document object.
Figure 4. The space subsumes the web.
Place
Interfacenet.artima.place.Place
interface contains only one method, getLinkMap()
, which
takes no parameters and returns a LinkMap
object, an object that implements
the net.artima.place.LinkMap
interface.
A LinkMap
object is a collection of links to resources on the network. Jini services of any type
can, in addition to other services they offer through their interface, offer a "collection
of links" service
through their interface by implementing net.artima.place.Place
.
Here's the Place
interface:
package net.artima.place; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.Remote; public interface Place extends Serializable, Remote { LinkMap getLinkMap() throws RemoteException; }
(Note: If we can convince the Jini community,
we'd like to ultimately place Place
in the net.jini.place
package.)
LinkMap
InterfaceLinkMap
holds a collection of links to resources on the network. The methods declared
in interface net.artima.place.LinkMap
allow clients to access, but not change those
links. Interface ModifiableLinkMap
, a subinterface of LinkMap
described
later in this specification, allows clients to modify the links contained in a LinkMap
.
The links contained in a DynamicLinkMap
, yet another subinterface of LinkMap
described later in this specification,
may asynchronously change while the client is
using the DynamicLinkMap
.
LinkMap
is called a map because each link contained in a LinkMap
is
associated with an Object
key. Clients can obtain an unmodifiable
java.util.Set
of all keys via the keySet()
method. In addition,
clients can obtain an unmodifiable java.util.Collection
of all the links
contained in the LinkMap
via the values()
method. To obtain the
link value for a particular key, clients can invoke the get()
method, which
takes an Object
key as its only parameter and returns a LinkItem
.
LinkItem
is described in the next section of this specification.
Here's the LinkMap
interface:
package net.artima.place; import java.io.Serializable; import java.rmi.RemoteException; import java.util.Set; import java.util.Collection; public interface LinkMap extends Serializable { LinkItem get(Object key) throws RemoteException; boolean containsKey(Object key) throws RemoteException; boolean containsValue(LinkItem value) throws RemoteException; boolean isEmpty() throws RemoteException; Set keySet() throws RemoteException; int size() throws RemoteException; Collection values() throws RemoteException; }
LinkItem
, Link
, and ResourceInfo
The object returned by LinkMap
's get()
method is an instance
of net.artima.place.LinkItem
. LinkItem
is a simple container
for two other objects, a net.artima.place.Link
and a net.artima.place.ResourceInfo
.
The Link
object represents the actual link to a resource on the network. The
ResourceInfo
object provides information, suitable for presentation to users,
about the resource referenced by the Link
.
The motivation for having a LinkItem
that associates a ResourceInfo
with
a Link
, rather than allowing Link
s themselves
to contain a ResourceInfo
, is that the information stored in the ResourceInfo
belongs to the Place
, not to the Link
or the service it references.
Just as current users of the World Wide Web bookmark pages they want to return to, users of
a web of objects may want to copy Link
s to resources to their own modifiable home places.
They may then wish to change the name, description, and/or icons associated with that
copied and saved Link
. By keeping Link
and ResourceInfo
separate, each client can change the ResourceInfo
associated with their own copies
of Link
s.
Note: It just occurred to me that the security manager probably won't let most copied
ResourceInfo's go out and load JAR files that contain icon images. Therefore, we should investigate
having a SelfContainedResourceInfo
that stores its names and descriptions in String
s
and icons in byte arrays, all referenced from the SelfContainedResourceInfo
.
Another possibility is adding a service context interface that will grab icons and strings
out of property files for the service. Seems grabbing an icon or a string across the network
and passing that back to the client shouldn't be a security risk.
Here are the public portions of LinkItem
:
package net.artima.place; import java.io.Serializable; public class LinkItem implements Serializable { public LinkItem(Link link, ResourceInfo resourceInfo) {...} public Link getLink() {...} public ResourceInfo getResourceInfo() {...} public boolean equals(Object o) {...} public int hashCode() {...} }
Link
Interface
An object that implements interface net.artima.place.Link
represents a link to a resource
on the network. In the current World Wide Web, links to resources are expressed in terms of
URLs, a string that represents an address or unique name of a resource. Link
s are
intended to serve the same purpose as URLs, but Link
s a distinctly different from URLs.
Although like URLs, Link
s represent links to resources on the network,
Link
s are not just wrappers for URLs.
Link
is an attempt to raise the level of abstraction of
URLs. A URL is data. You can send a URL across the network to a client, but for the client to use the
URL, the client needs code already existing on the client side that knows how to interpret the URL data.
In particular, the client needs to know the protocol indicated in the first portion of the URL. What's more,
the person doing the sending of the URL needs to know the host and port number where the resource is available,
in addition to the name of the resource.
By contrast, a Link
is not a chunk of data like the URL, a Link
is an object.
You can send a Link
across the network to the client, just as you can send a URL across the network. But in the case of a Link
,
you are not sending data across the network, you are sending behavior.
To follow a Link
,
you ask the Link
to get the resource for you. The behavior determining how
the resource is retrieved does not reside in client side code, but
is contained in the code that defines the Link
's class, code that is sent across the
network as part of the Link
object.
To retrieve a resource, the Link
can do anything it wants (so long as
it is allowed by the local security policy) to retrieve the resource.
Here's the Link
interface:
package net.artima.place; import java.io.Serializable; import java.rmi.RemoteException; public interface Link extends Serializable { LinkActivation activate(ActivationClient ac) throws RemoteException; }
One of the motivations of raising the level of abstraction of a URL is that a
Link
will be
able to do fancy things with Jini lookup services that would be very difficult to express in a URL.
For example, a Link
could do multicast discovery to get references to nearby Jini lookup
services. It could then perform lookups by type and attributes in those lookup services, and sort through multiple
responses using some algorithm that is also part of the network-delivered code of the Link
.
One of the goals for Link
is to provide an abstraction that everyday users
can understand that enables those users to access the functionality of the ServiceRegistrar
interface.
More discussion of link activation is given later in this specification.
ResourceInfo
Interface
Accompanying each Link
in a LinkItem
is an object that implements
net.artima.place.ResourceInfo
. ResourceInfo
allows
clients to retrieve information, suitable for presentation to users, about the resource referenced
by the Link
. ResourceInfo
encapsulates three basic kinds of information,
a name, a description, and icons. Names and descriptions are returned as String
s.
Icons are returned either as java.net.URL
s pointing to image data, or as java.net.InputStream
s
containing the actual image data.
Icons can be requested in the four flavors available from
java.beans.BeanInfo
or via the net.jini.lookup.entry.ServiceType
entry:
All information retrieved from a ResourceInfo
can either be requested for a specific locale
or allowed to adapt to the default locale. A method, getSupportedLocales()
allows clients
to get an array of all locales supported by the ResourceInfo
. The ability to query for
supported locales and retrieve information for specific locales is actually targetted at search engine
spiders, which will likely be interacting with ResourceInfo
objects retrieved from
net.artima.place.SpiderFodder
entries, not from LinkItem
s. Class SpiderFodder
is described later in this document.
Here's the ResourceInfo
interface:
package net.artima.place; import java.util.Locale; import java.io.Serializable; import java.io.InputStream; import java.net.URL; public interface ResourceInfo extends Serializable { int ICON_COLOR_16x16; int ICON_COLOR_32x32; int ICON_MONO_16x16; int ICON_MONO_32x32; Locale[] getSupportedLocales(); String getName(); String getName(Locale locale); String getDescription(); String getDescription(Locale locale); URL getIconImageFile(int iconKind); InputStream getIconImageFileAsStream(int iconKind); URL getIconImageFile(Locale locale, int iconKind); InputStream getIconImageFileAsStream(Locale locale, int iconKind); }
Of course, ResourceInfo
only defines the minimum kind of user-presentable information that can be
associated with a Link
. Other kinds of informatoin, such as for example compressed view icons or
sound bites, could
be made available via the class that implements ResourceInfo
, or via Place
service UIs.
Not sure get methods that return a URL make sense. If the icon is sent in the state of the ResourceInfo
,
then there is no URL.
Link
s
When the activate()
method is invoked on a Link
, the Link
will attempt to retrieve the referenced Jini service.
Here's the signature of the activate()
method:
LinkActivation activate(ActivationClient al) throws RemoteException;
ActivationClient
Interface
The activate()
method accepts a single parameter, an object that implements
net.artima.place.ActivationClient
.
The ActivationClient
passed to activate()
is notified when a link
activation completes, either with success, failure, or as a result of
being aborted. Only one of the methods in this interface will be
invoked (only once) for each link activation. This enables clients to indicate to users
that an activation is in progress. For example, a client could show an animation while
the activation is in progress, then stop the animation after the activation completes.
Here's the ActivationClient
interface:
package net.artima.place; public interface ActivationClient { void activationSucceeded(ServiceItem serviceItem); void activationFailed(String message, Throwable exception); void activationAborted(); }
The result of every successful link activation is a Jini ServiceItem
,
which is passed to the activationSucceeded()
method.
The String
message passed to the activationFailed
method
contains a localized message that may be displayed to users. (A localized
message is chosen first, then that message is passed to the activationFailed()
method.) If some exception caused the activation to fail, it may be handed to the
client in the The Throwable
passed to the activationAborted()
method.
LinkActivation
Interface
The activate()
method returns an object that implements
the net.artima.place.LinkActivation
interface.
The activate()
method should never block until the
activation completes. Rather, activate()
should return promptly. The
LinkActivation
object returned by activate()
represents the
ongoing activation to the client.
The LinkActivation
object allows the client to abort the activation via the
abort()
method. The object
may optionally implement other interfaces, such as ProgressEventGenerator
and
StatusEventGenerator
, or include other methods in its class, which allow other kinds of
client interaction. ProgressEventGenerator
and StatusEventGenerator
are described later in this specification.
Here's the LinkActivation
interface:
package net.artima.place; import java.io.Serializable; public interface LinkActivation extends Serializable { void abort(); }
ProgressEventGenerator
InterfaceLinkActivation
object returned from activate()
may optionally implement
the net.artima.place.ProgressEventGenerator
interface, which enables clients to register
interest in receiving progress updates, expressed in terms of percent complete,
during the course of the activation. Here's the
ProgressEventGenerator
interface:
package net.artima.place; public interface ProgressEventGenerator { void addProgressListener(ProgressListener pl); void removeProgressListener(ProgressListener pl); }
The methods of ProgressEventGenerator
accept an object that implements
the net.artima.place.ProgressListener
interface. ProgressListener
contains one method, progressUpdated()
, which is invoked
when the progress of an activation has changed. Progress is reported
as percent complete. Although users would expect that the percent complete reported
would in general increase over time, the actual progress events need not report
consecutive percentages, or even increasing percentages.
Here's the ProgressListener
interface:
package net.artima.place; public interface ProgressListener { void progressUpdated(ProgressEvent pe); }
To notify a ProgressListener
of a change in percentage complete, the event generator
passes a net.artima.place.ProgressEvent
to the ProgressListener
's
progressUpdated()
method.
The ProgressEvent
contains an int
percent complete, which may be
communicated to users via a explicit percentage number, a progress bar, or other means.
Here's the public portions of the ProgressEvent
class:
package net.artima.place; import java.util.EventObject; public class ProgressEvent extends EventObject { public ProgressEvent(ProgressEventGenerator source, int percentComplete) {...} public int getPercentComplete() {...} }
ProgressEvent
s indicate the overall activation progress (major progress),
not the the progress of each individual activity (minor progress).
Thus, the progress should not snap from zero to 100 percent quickly and repetitively
during the lifetime of the activation. Progress should in general move from zero
to 100 percent once for each activation.
Could make the ProgressEvent
constructor private, and declare a public static
factory method that returns a ProgressEvent
object for a passed percentage. This would
allow these to be instantiated lazily, then cached and shared by everyone.
StatusEventGenerator
InterfaceLinkActivation
object returned from activate()
may optionally implement
the net.artima.place.StatusEventGenerator
interface, which enables clients to register
interest in receiving status updates, expressed as localized String
s suitable for
display to users, during the course of the activation. Here's the
StatusEventGenerator
interface:
package net.artima.place; public interface StatusEventGenerator { void addStatusListener(StatusListener sl); void removeStatusListener(StatusListener sl); }
The methods of StatusEventGenerator
accept an object that implements
the net.artima.place.StatusListener
interface. StatusListener
contains one method, statusUpdated()
, which is invoked
when the status of an activation has changed.
Here's the StatusListener
interface:
package net.artima.place; public interface StatusListener { void statusUpdated(StatusEvent se); }
To notify a StatusListener
of a new status message, the event generator
passes a net.artima.place.StatusEvent
to the StatusListener
's
statusUpdated()
method.
The StatusEvent
contains a String
status message, which may be
communicated to users via a status bar or other means. A localized
String
message should be selected first, then passed to the StatusEvent
constructor.
Here's the public portions of the StatusEvent
class:
package net.artima.place; import java.util.EventObject; public class StatusEvent extends EventObject { public StatusEvent(StatusEventGenerator source, String status) {...} public String getStatus() {...} }
ModifiableLinkMap
Interface
Service providers can use Place
services to present multiple services to
users. In such Place
s, links will be controlled by the service provider.
Users will be allowed to activate links at those Places
, but not add, delete,
or change the links.
But some Place
services will be provided to users, so that the users can organize their own
links to resources on the network. At this kind of Place
, links will be controlled by the user.
The net.artima.place.ModifiableLinkMap
interface enables
users to maintain links to their favorite resources. Regardless of whether the links at a Place
are intended to be controlled by the service provider or user, the service object implements the same
interface, net.artima.place.Place
. In either case, clients obtain a LinkMap
by
invoking getLinkMap()
on the Place
service object. The returned object definitely
implements LinkMap
, but may also implement ModifiableLinkMap
, which is a
subinterface of LinkMap
. If the object
is a ModifiableLinkMap
, the client will be able to add, delete, and change links contained in
the LinkMap
via the methods declared in ModifiableLinkMap
interface. The changes
requested via the ModifiableLinkMap
interface are persistent with respect to the Place
.
The next time a user visits the same Place
, the users will see all the changes made the previous
visit.
With a ModifiableLinkMap
,
a client can add a new LinkItem
to a Place
via the put()
method, can remove a LinkItem
via the remove()
method, and can
associate a new ResourceInfo
with an existing Link
via the
update()
method.
Here's the ModifiableLinkMap
interface:
package net.artima.place; import java.rmi.RemoteException; public interface ModifiableLinkMap extends LinkMap { void clear() throws RemoteException; LinkItem put(Object key, LinkItem value) throws RemoteException; LinkItem update(Object key, ResourceInfo resourceInfo) throws RemoteException; void putAll(LinkMap map) throws RemoteException; LinkItem remove(Object key) throws RemoteException; }
DynamicLinkMap
Interface
A DynamicLinkMap
represents a dynamic map of links to resources on the network. The map is "dynamic"
because it may asynchronously change while the client using it. For example, a
Place
service may provide a client with links to the Jini services registered
in a particular lookup service that match a particular template. As matching
services arrive and depart the lookup service, links to those services will be dynamically added
and removed from the Place
's LinkMap
.
The DynamicLinkMap
interface contains methods that enable the client to
register and unregister itself as an interested listener for events that describe changes to the
map. A LinkMap
implementation class can optionally implement
ModifiableLinkMap
and/or DynamicLinkMap
.
A class that implements both ModifiableLinkMap
and DynamicLinkMap
will notify LinkMapListener
s of
all changes to the LinkMap
, including changes resulting from the client
invoking methods declared in ModifiableLinkMap
.
Here's the DynamicLinkMap
interface:
package net.artima.place; import java.io.Serializable; import java.rmi.RemoteException; import java.util.Set; import java.util.Collection; public interface DynamicLinkMap extends LinkMap { void addLinkMapListener(LinkMapListener lml); void removeLinkMapListener(LinkMapListener lml); }The
linkMapChanged()
method of all registered LinkMapListener
s are
invoked when one or more links in a DynamicLinkMap
are
altered, added, and/or removed. Here's the LinkMapListener
interface:
package net.artima.place; public interface LinkMapListener { void linkMapChanged(LinkMapEvent lme); }
A LinkMapEvent
indicates a change in the contents of a DynamicLinkMap
. This
event will only be fired if at least one link was altered, added, or removed.
On the other hand, a single LinkMapEvent
may be used to report multiple alterations, additions, and/or removals.
Each alteration, addition, or removal of a particular DynamicLinkMap
is reported in one and only one LinkMapEvent
.
Each get method in LinkMapEvent
returns an array of Object
keys for those links
that have been either altered, added, or removed.
Here's the public portions of LinkMapEvent
:
package net.artima.place; import java.util.EventObject; public class LinkMapEvent extends EventObject { private Object[] keysAltered; private Object[] keysAdded; private Object[] keysRemoved; private static Object[] emptyKeyArray = new Object[0]; public LinkMapEvent(DynamicLinkMap source, Object[] keysAltered, Object[] keysAdded, Object[] keysRemoved) {...} public Object[] getKeysAltered() {...} public Object[] getKeysAdded() {...} public Object[] getKeysRemoved() {...} }
The net.artima.place
package contains a handful of convenience implementations of interfaces also declared
in net.artima.place
.
URLFactoryLink
Class
URLFactoryLink
is an implementation of the Link
interface that produces a Jini
ServiceItem
that contains a URLFactory
service and null
references
in the service id and attribute sets fields. Here are the public portions of
URLFactoryLink
:
package net.artima.place; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceID; import net.jini.core.entry.Entry; import java.net.MalformedURLException; public final class URLFactoryLink implements Link { public URLFactoryLink(String url) throws MalformedURLException {...} public LinkActivation activate(ActivationClient al) {...} }
The URLFactory
Jini service interface
has just one method, getURL()
, which
returns a java.net.URL
. Here's the URLFactory
interface
:
package net.artima.place; import java.io.Serializable; import java.net.URL; import java.net.MalformedURLException; public final class URLFactory implements Serializable { public URLFactory(String url) throws MalformedURLException {...} public URL getURL() throws MalformedURLException {...} }
URLFactory
is used to wrap existing file-based resources, such as web pages. Instead of plug-ins that
must be installed at the client by the user, a network-mobile service UI can automatically provide a user
access to the file-based resource. If a URLFactory
doesn't contain a suitable UI for a file
with a MIME type, a client could conceivably pass a MIME type to a Jini service that returns a set of
UIDescriptor
s describing UIs for that kind of MIME type.
ServiceURLLink
Class
Represents a URL-based link to a Jini service on the network. This class assumes that the MIME type of
the resource refered to by the URL passed to the constructor is application/x-serviceui
.
The two kinds of URLs that will work initially are the http:
and jini:
Jini service URLs described later in this specification.
Here are the public portions of the ServiceURLLink
class:
package net.artima.place; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceID; import net.jini.core.entry.Entry; import java.net.MalformedURLException; public final class ServiceURLLink implements Link { public ServiceURLLink(String url) throws MalformedURLException {...} public LinkActivation activate(ActivationClient al) {...} }
PropertyFileResourceInfo
Class
Although Place
s are collections of Link
s, not URLs, for resources on the existing web
to link into the web of objects, objects will need to be accessible via URLs.
To enable Jini services and service UIs to be referenced via HTTP: URLs, the following MIME type is
proposed: application/x-serviceui
. (This could be application/x-jini
, if
Sun were to agree. Another possibility is application/x-service
.) A file delivered via
this MIME type should be a serialized java.rmi.MarshalledObject
,
that contains a marshalled net.jini.core.lookup.ServiceItem
.
An HTTP server could product the file in any way. A servlet could, for example, do a lookup in a
Jini lookup service, marshal the resulting ServiceItem
, serialize the marshalled object,
and return it to the client. Alternatively, an HTTP service could just grab a file that already
contains a serialized marshalled ServiceItem
, and return that file. This specification
recommends using .serviceui
(this could be .jini
, if Sun were to agree. Another
possibility is .service
.)
as the standard extension for such files.
The jini:
URL as currently defined identifies a Jini lookup service. The host
name or IP address specifies the host on which the lookup service is running, such as:
If no port number is given, as shown in the previous examples, the default port number for Jini services, 4160, is implied. As with all URLs, if you need to address a lookup service at a different port besides the default, you can specify the port explicitly, as in:jini://www.artima.com
or
jini://123.45.678.9
Although URLs often have a fourth component after the protocol, host, and port number,jini://www.artima.com:2000
or
jini://123.45.678.9:2001
jini:
no
fourth component is currently defined for jini:
URLs. This specification proposes that the Jini
Community define that fourth component to mean a Jini service that is registered within the Jini lookup
service identified by the host and port number of the URL.
A Jini service can be uniquely identified inside a lookup service is by its service ID.
This specification proposes that the jini:
protocol indicate a service ID
of a Jini service registered at the indicated host and port. For example:
jini://www.artima.com:7777/a1366531-5805-4f2e-8b40-e6b9b36f78fb
To locate a service referenced by a jini:
URL with a fourth component, the Jini client that is
handed the URL first checks to see if it already has a ServiceRegistrar
for
the lookup service identified by the host and port number specified in the URL. If not, the
client attempts to perform unicast discovery on that lookup service.
If successful, the client instantiates a net.jini.core.lookup.ServiceID
of the same value
represented in the file portion of the URL.
The client places this ServiceID
in the serviceID
field of a ServiceTemplate
, and makes a lookup()
query. If no service matches the
query, then the service identified by the URL is not available. Otherwise, the matching service is
selected and returned.
The Jini lookup service is designed to help software, not users, find network-delivered services. Nowadays, when users are looking for a network-delivered service, they go to search engines. Many search engine databases are constructed by autonomous robots, which "spider" the web. A spider visits a page, places information about that page into its search engine database, then follows links from that page to other pages.
Once Jini services and service UIs begin to participate in the web, users will want to be able to find
them via search engines. The Place
API includes a new entry that contains information for
search engine spiders. Instances of class net.artima.place.SpiderFodder
can be placed in
the attribute sets of a Jini service item. (SpiderFodder
means "food for spiders.")
When a spider retrieves a Jini service, it can look for SpiderFodder
entries, extract
information from them, and place the information in its search engine database. If the service is
a Place
, the spider can follow the Link
s contained in the Place
to discover still more resources, some of which may be more Jini services.
Here's the SpiderFodder
class:
package net.artima.place; import net.jini.entry.AbstractEntry; /** * A bundle of information that search engines spiders can * use to record information about this service in their database. */ public class SpiderFodder extends AbstractEntry { /** *ResourceInfo
object that provides localized name, description, * and icons for this service, suitable for presenting to users. */ public ResourceInfo resourceInfo; /** *KeywordInfo
object that provides localized keywords, * suitable for presenting to users, with which search engine spiders may * wish to use when recording information about this service in their * database. */ public KeywordInfo keywordInfo; /** * Constructs aSpiderFodder
with all fields set tonull
. */ public SpiderFodder() { } /** * Constructs aSpiderFodder
with fields set to passed values. */ public SpiderFodder(ResourceInfo resourceInfo, KeywordInfo keywordInfo) { this.resourceInfo = resourceInfo; this.keywordInfo = keywordInfo; } }
The KeywordInfo
object allows Jini services to offer a list of
keywords that search engine spiders can use when entering information about the
service in their database. The keywords are intended to serve the same purpose
as the keywords that appear in the keywords
META tag in
HTML files.
Here's the KeywordInfo
interface
:
package net.artima.place; import java.util.Locale; import java.io.Serializable; public interface KeywordInfo extends Serializable { String[] getKeywords(); String[] getKeywords(Locale locale); }
Class ServicePresenter
contains a static method that
allows Place
service UIs to
request that the service host present a service to the user.
Because the passed Link
is activated by the host, the host can give the user feedback about the activation
progress in a uniform way. The host can, for example, show an animation, status messages, progress bar, etc.,
during the activation of the Link
. The host can provide this feedback in the same manner for
every link activation, yielding a more uniform experience for the user.
The presentService()
method can
wrap its activate()
method invocation on any URLFactoryLink
s and
ServiceURLLink
s in a doPrivileged()
invocation, so that those
trusted Link
implementations can make socket connections,
create class loaders, etc. Untrusted code that invokes presentService()
won't get a reference to the resulting service item, but the user will be able to interact
with the service via a service UI. If untrusted code invokes activate()
directly
on a ServiceURLLink()
or URLFactoryLink
, it may get a security exception.
Because a URLFactoryLink
always returns a ServiceItem
that contains no
attribute sets, no UIDescriptor
s will be available. If the presentService()
method can get a MIME type from the URL, however, the method can go look up a batch of UIDescriptor
s
given the MIME type. It can have its own repertiore of UIDescriptor
s, and can also possible
consult a "UI descriptor service" over the network. This UI descriptor service is kind of like Netscape
Navigator giving you information about potential plug-ins that will let you view some content, but
in this case the information about each service UI "plug-in"
is encapsulated in a UIDescriptor
, a form that will allow
the client code to decide on a UI and seamlessly "install" it. Thus, besides granting users access
to the space of Jini services on the network, this architecture attempts to
give users a more seamless experience when using web resources than is possible with existing
web browsers.
package net.artima.place; import java.rmi.RemoteException; public class ServicePresenter { public static void presentService(Link link) throws RemoteException {...} }
Sponsored Links
|