Spec Index A Collection of Jini Technology Helper Utilities and Services Specifications


Version 1.0

LS - JiniTM Lookup Attribute Schema Specification

LS.1 Introduction

The JiniTM lookup service provides facilities for services to advertise their availability and for would-be clients to obtain references to those services based on the attributes they provide. The mechanism that it provides for registering and querying based on attributes is centered on the JavaTM platform type system, and is based on the notion of an entry.

An entry is a class that contains a number of public fields of object type. Services provide concrete values for each of these fields; each value acts as an attribute. Entries thus provide aggregation of attributes into sets; a service may provide several entries when registering itself in the lookup service, which means that attributes on each service are provided in a set of sets.

The purpose of this document is to provide a framework in which services and their would-be clients can interoperate. This framework takes two parts:

LS.1.1 Terminology

Throughout this document, we will use the following terms in consistent ways:

LS.1.2 Design Issues

Several factors influence and constrain the design of the lookup service schema.

Matching Cannot Always Be Automated

No matter how much information it has at its disposal, a client of the lookup service will not always be able to find a single unique match without assistance when it performs a lookup. In many instances we expect that more than one service will match a particular query. Accordingly, both the lookup service and the attribute schema are geared toward reducing the number of matches that are returned on a given lookup to a minimum, and not necessarily to just one.

Attributes Are Mostly Static

We have designed the schema for the lookup service with the assumption that most attributes will not need to be changed frequently. For example, we do not expect attributes to change more often than once every minute or so. This decision is based on our expectation that clients that need to make a choice of service based on more frequently updated attributes will be able to talk to whatever small set of services the lookup service returns for a query, and on our belief that the benefit of updating attributes frequently at the lookup service is outweighed by the cost in network traffic and processing.

Humans Need to Understand Most Attributes

A corollary of the idea that matching cannot always be automated is that humans--whether they be users or administrators of services--must be able to understand and interpret attributes. This has several implications:

We will cover human accessibility of attributes soon.

Attributes Can Be Changed by Services or Humans, But Not Both

For any given attribute class we expect that attributes within that class will all be set or modified either by the service, or via human intervention, but not both. What do we mean by this? A service is unlikely to be able to determine that it has been moved from one room to another, for example, so we would not expect the fields of a "location" attribute class to be changed by the service itself. Similarly, we do not expect that a human operator will need to change the name of the vendor of a particular service. This idea has implications for our approach to ensuring that the values of attributes are valid.

Attributes Must Interoperate with JavaBeansTM Components

The JavaBeansTM specification provides a number of facilities relating to the localized display and modification of properties, and has been widely adopted. It is to our advantage to provide a familiar set of mechanisms for manipulating attributes in these ways.

LS.1.3 Dependencies

This document relies on the following other specifications:

LS.2 Human Access to Attributes

LS.2.1 Providing a Single View of an Attribute's Value

Consider the following entry class:

public class Foo implements net.jini.core.entry.Entry {
    public Bar baz;
}

public class Bar {
    int quux;
    boolean zot;
}

A visual search tool is going to have a difficult time rendering the value of an instance of class Bar in a manner that is comprehensible to humans. Accordingly, to avoid such situations, entry class implementors should use the following guidelines when designing a class that is to act as a value for an attribute:

One of the above guidelines should be followed for all attribute value classes. Authors of entry classes should assume that any attribute value that does not satisfy one of these guidelines will be ignored by some or all user interfaces.

LS.3 JavaBeans Components and Design Patterns

LS.3.1 Allowing Display and Modification of Attributes

We use JavaBeans components to provide a layer of abstraction on top of the individual classes that implement the net.jini.core.entry.Entry interface. This provides us with several benefits:

LS.3.1.1 Using JavaBeans Components with Entry Classes

Many, if not most, entry classes should have a bean class associated with them. Our use of JavaBeans components provides a familiar mechanism for authors of browse/search tools to represent information about a service's attributes, such as its icons and appropriately localized descriptions of the meanings and values of its attributes. JavaBeans components also play a role in permitting administrators of a service to modify some of its attributes, as they can manipulate the values of its attributes using standard JavaBeans component mechanisms.

For example, obtaining a java.beans.BeanDescriptor for a JavaBeans component that is linked to a "location" entry object for a particular service allows a programmer to obtain an icon that gives a visual indication of what that entry class is for, along with a short textual description of the class and the values of the individual attributes in the location object. It also permits an administrative tool to view and change certain fields in the location, such as the floor number.

LS.3.2 Associating JavaBeans Components with Entry Classes

The pattern for establishing a link between an entry object and an instance of its JavaBeans component is simple enough, as this example illustrates:

package org.example.foo;

import java.io.Serializable;
import net.jini.lookup.entry.EntryBean;
import net.jini.entry.AbstractEntry;

public class Size {
    public int value;
}

public class Cavenewt extends AbstractEntry {
    public Cavenewt() {
    }
    public Cavenewt(Size anvilSize) {
        this.anvilSize = anvilSize;
    }
    public Size anvilSize;
}

public class CavenewtBean implements EntryBean, Serializable {
    protected Cavenewt assoc;
    public CavenewtBean() {
        super();
        assoc = new Cavenewt();
    }
    public void setAnvilSize(Size x) {
        assoc.anvilSize = x;
    }
    public Size getAnvilSize() {
        return assoc.anvilSize;
    }
    public void makeLink(Entry obj) {
         assoc = (Cavenewt) obj;
    }
    public Entry followLink() {
        return assoc;
    }
}

From the above, the pattern should be relatively clear:

LS.3.3 Supporting Interfaces and Classes

The following classes and interfaces provide facilities for handling entry classes and their associated JavaBeans components.

package net.jini.lookup.entry;

public class EntryBeans {
    public static EntryBean createBean(Entry e)
        throws ClassNotFoundException, java.io.IOException {...}

    public static Class getBeanClass(Class c)
        throws ClassNotFoundException {...}
}

public interface EntryBean {
    void makeLink(Entry e);
    Entry followLink();
}

The EntryBeans class cannot be instantiated. Its sole method, createBean, creates and initializes a new JavaBeans component and links it to the entry object it is passed. If a problem occurs creating the JavaBeans component, the method throws either java.io.IOException or ClassNotFoundException.

The createBean method uses the same mechanism for instantiating a JavaBeans component as the java.beans.Beans.instantiate method. It will initially try to instantiate the JavaBeans component using the same class loader as the entry it is passed. If that fails, it will fall back to using the default class loader.

The getBeanClass method returns the class of the JavaBeans component associated with the given attribute class. If the class passed in does not implement the net.jini.core.entry.Entry interface, an IllegalArgumentException is thrown. If the given attribute class cannot be found, a ClassNotFoundException is thrown.

The EntryBean interface must be implemented by all JavaBeans components that are intended to be linked to entry objects. The makeLink method establishes a link between a JavaBeans component object and an entry object, and the followLink method returns the entry object linked to by a particular JavaBeans component. Note that objects that implement the EntryBean interface should not be assumed to perform any internal synchronization in their implementations of the makeLink or followLink methods, or in the setFoo or getFoo patterns.

LS.4 Generic Attribute Classes

We will now describe some attribute classes that are generic to many or all services and the JavaBeans components that are associated with each. Unless otherwise stated, all classes defined here live in the net.jini.lookup.entry package. The definitions assume the following classes to have been imported:

java.io.Serializable 
net.jini.entry.AbstractEntry 

LS.4.1 Indicating User Modifiability

To indicate that certain entry classes should only be modified by the service that registered itself with instances of these entry classes, we annotate them with the ServiceControlled interface.

public interface ServiceControlled {
}

Authors of administrative tools that modify fields of attribute objects at the lookup service should not permit users to either modify any fields or add any new instances of objects that implement this interface.

LS.4.2 Basic Service Information

The ServiceInfo attribute class provides some basic information about a service.

public class ServiceInfo extends AbstractEntry
    implements ServiceControlled
{
    public ServiceInfo() {...}
    public ServiceInfo(String name, String manufacturer,
                       String vendor, String version,
                       String model, String serialNumber) {...}

    public String name;
    public String manufacturer;
    public String vendor;
    public String version;
    public String model;
    public String serialNumber;
}

public class ServiceInfoBean
    implements EntryBean, Serializable
{
    public String getName() {...}
    public void setName(String s) {...}
    public String getManufacturer() {...}
    public void setManufacturer(String s) {...}
    public String getVendor() {...}
    public void setVendor(String s) {...}
    public String getVersion() {...}
    public void setVersion(String s) {...}
    public String getModel() {...}
    public void setModel(String s) {...}
    public String getSerialNumber() {...}
    public void setSerialNumber(String s) {...}
}

Each service should register itself with only one instance of this class. The fields of the ServiceInfo class have the following meanings:

LS.4.3 More Specific Information

The ServiceType class allows an author of a service to deliver information that is specific to a particular instance of a service, rather than to services in general.

public class ServiceType extends AbstractEntry
        implements ServiceControlled
{
    public ServiceType() {...}
    public java.awt.Image getIcon(int iconKind) {...}
    public String getDisplayName() {...}
    public String getShortDescription() {...}
}

Each service may register itself with multiple instances of this class, usually with one instance for each type of service interface it implements.

This class has no public fields and, as a result, has no associated JavaBeans component.

The getIcon method returns an icon of the appropriate kind for the service; it works in the same way as the getIcon method in the java.beans.BeanInfo interface, with the value of iconKind being taken from the possibilities defined in that interface. The getDisplayName and getShortDescription methods return a localized human-readable name and description for the service, in the same manner as their counterparts in the java.beans.FeatureDescriptor class. Each of these methods returns null if no information of the appropriate kind is defined.

In case the distinction between the information this class provides and that provided by a JavaBeans component's meta-information is unclear, the class ServiceType is meant to be used in the lookup service as one of the entry classes with which a service registers itself, and so it can be customized on a per-service basis. By contrast, the FeatureDescriptor and BeanInfo objects for all EntryBean classes provide only generic information about those classes and none about specific instances of those classes.

LS.4.4 Naming a Service

People like to associate names with particular services and may do so using the Name class.

public class Name extends AbstractEntry {
    public Name() {...}
    public Name(String name) {...}

    public String name;
}

public class NameBean implements EntryBean, Serializable {
    public String getName() {...}
    public void setName(String s) {...}
}

Services may register themselves with multiple instances of this class, and either services or administrators may add, modify, or remove instances of this class from the attribute set under which a service is registered.

The name field provides a short name for a particular instance of a service (for example, "Bob's toaster").

LS.4.5 Adding a Comment to a Service

In cases in which some kind of comment is appropriate for a service (for example, "this toaster tends to burn bagels"), the Comment class provides an appropriate facility.

public class Comment extends AbstractEntry {
    public Comment() {...}
    public Comment(String comment) {...}

    public String comment;
}

public class CommentBean implements EntryBean, Serializable {
    public String getComment() {...}
    public void setComment(String s) {...}
}

A service may have more than one comment associated with it, and comments may be added, removed, or edited by either a service itself, administrators, or users.

LS.4.6 Physical Location

The Location and Address classes provide information about the physical location of a particular service.

Since many services have no physical location, some have one, and a few may have more than one, it might make sense for a service to register itself with zero or more instances of either of these classes, depending on its nature.

The Location class is intended to provide information about the physical location of a service in a single building or on a small, unified campus. The Address class provides more information and may be appropriate for use with the Location class in a larger, more geographically distributed organization.

public class Location extends AbstractEntry {
    public Location() {...}
    public Location(String floor, String room,
                    String building) {...}

    public String floor;
    public String room;
    public String building;
}

public class LocationBean implements EntryBean, Serializable {
    public String getFloor() {...}
    public void setFloor(String s) {...}
    public String getRoom() {...}
    public void setRoom(String s) {...}
    public String getBuilding() {...}
    public void setBuilding(String s) {...}
}

public class Address extends AbstractEntry {
    public Address() {...}
    public Address(String street, String organization,
                   String organizationalUnit, String locality,
                   String stateOrProvince, String postalCode,
                   String country) {...}

    public String street;
    public String organization;
    public String organizationalUnit;
    public String locality;
    public String stateOrProvince;
    public String postalCode;
    public String country;
}

public class AddressBean implements EntryBean, Serializable {
    public String getStreet() {...}
    public void setStreet(String s) {...}
    public String getOrganization() {...}
    public void setOrganization(String s) {...}
    public String getOrganizationalUnit() {...}
    public void setOrganizationalUnit(String s) {...}
    public String getLocality() {...}
    public void setLocality(String s) {...}
    public String getStateOrProvince() {...}
    public void setStateOrProvince(String s) {...}
    public String getPostalCode() {...}
    public void setPostalCode(String s) {...}
    public String getCountry() {...}
    public void setCountry(String s) {...}
}

We believe the fields of these classes to be self-explanatory, with the possible exception of the locality field of the Address class, which would typically hold the name of a city.

LS.4.7 Status Information

Some attributes of a service may constitute long-lived status, such as an indication that a printer is out of paper. We provide a class, Status, that implementors can use as a base for providing status-related entry classes.

public abstract class Status extends AbstractEntry {
    protected Status() {...}
    protected Status(StatusType severity) {...}

    public StatusType severity;
}

public class StatusType implements Serializable {
    private final int type;
    private StatusType(int t) { type = t; }
    public static final StatusType ERROR =  new StatusType(1);
    public static final StatusType WARNING =
                                            new StatusType(2);
    public static final StatusType NOTICE = new StatusType(3);
    public static final StatusType NORMAL = new StatusType(4);
}

public abstract class StatusBean
    implements EntryBean, Serializable
{
    public StatusType getSeverity() {...}
    public void setSeverity(StatusType i) {...}
}

We define a separate StatusType class to make it possible to write a property editor that will work with the StatusBean class (we do not currently provide a property editor implementation).

LS.4.8 Serialized Forms

Class
serialVersionUID
Serialized Fields
Address
2896136903322046578L
all public fields
AddressBean
4491500432084550577L
Address asoc
Comment
7138608904371928208L
all public fields
CommentBean
5272583409036504625L
Comment asoc
Location
-3275276677967431315L
all public fields
LocationBean
-4182591284470292829L
Location asoc
Name
2743215148071307201L
all public fields
NameBean
-6026791845102735793L
Name asoc
ServiceInfo
-1116664185758541509L
all public fields
ServiceInfoBean
8352546663361067804L
ServiceInfo asoc
ServiceType
-6443809721367395836L
all public fields
Status
-5193075846115040838L
all public fields
StatusBean
-1975539395914887503L
Status asoc
StatusType
-8268735508512712203L
int type

LS.5 History

Version Description
v1.0 Initial release of this specification.

License

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Spec Index A Collection of Jini Technology Helper Utilities and Services Specifications

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.