character.
values
A Vector of one or more attribute values. Vector contents
must be uniform in type and one of Integer, String, Boolean,
or byte[]. If the attribute is a keyword attribute, then the
parameter should be null. String values can consist of any
Unicode character.
5.3.2.4. Class Methods
public static String escapeId(String id)
Returns an escaped version of the id parameter, suitable for
inclusion in a query. Any reserved characters as specified in [7]
are escaped using UTF-8 encoding. If any characters in the tag are
illegal, throws IllegalArgumentException.
Parameters:
id
The attribute id to escape. ServiceLocationException is thrown
if any characters are illegal for an attribute tag.
public static String escapeValue(Object value)
Returns a String containing the escaped value parameter as a string,
suitable for inclusion in a query. If the parameter is a string,
any reserved characters as specified in [7] are escaped using UTF-8
encoding. If the parameter is a byte array, then the escaped string
begins with the nonUTF-8 sequence `\ff` and the rest of the string
consists of the escaped bytes, which is the encoding for opaques.
If the value parameter is a Boolean or Integer, then the returned
string contains the object converted into a string. If the value
is any type other than String, Integer, Boolean or byte[], an
IllegalArgumentException is thrown.
Parameters:
value
The attribute value to be converted into a string and escaped.
5.3.2.5. Instance Methods
public Vector getValues()
Returns a cloned vector of attribute values, or null if the attribute
is a keyword attribute. If the attribute is single-valued, then the
vector contains only one object.
public String getId()
Returns the attribute's name.
public boolean equals(Object o)
Overrides Object.equals(). Two attributes are equal if their
identifiers are equal and their value vectors contain the same number
of equal values as determined by the Object equals() method. Values
having byte[] type are equal if the contents of all byte arrays in
both attribute vectors match. Note that the SLP string matching
algorithm [7] MUST NOT be used for comparing attribute identifiers or
string values.
public String toString()
Overrides Object.toString(). The string returned contains a
formatted representation of the attribute, giving the attribute's
id, values, and the Java type of the values. The returned string is
suitable for debugging purposes, but is not in SLP wire format.
public int hashCode()
Overrides Object.hashCode(). Hashes on the attribute's identifier.
5.3.3. Class ServiceType
5.3.3.1. Synopsis
public class ServiceType extends Object implements Serializable
5.3.3.2. Description
The ServiceType object models the SLP service type. It parses a
string based service type specifier into its various components, and
contains property accessors to return the components. URL schemes,
protocol service types, and abstract service types are all handled.
5.3.3.3. Constructors
public ServiceType(String type)
Construct a service type object from the service type specifier.
Throws IllegalArgumentException if the type name is syntactically
incorrect.
Parameters:
type
The service type name as a String. If the service type is from
a service: URL, the "service:" prefix must be intact.
5.3.3.4. Methods
public boolean isServiceURL()
Returns true if the type name contains the "service:" prefix.
public boolean isAbstractType()
Returns true if the type name is for an abstract type.
public boolean isNADefault()
Returns true if the naming authority is the default, i.e. is the
empty string.
public String getConcreteTypeName()
Returns the concrete type name in an abstract type, or the empty
string if the service type is not abstract. For example, if the type
name is "service:printing:ipp", the method returns "ipp". If the
type name is "service:ftp", the method returns "".
public String getPrincipleTypeName()
Returns the abstract type name for an abstract type, the protocol
name in a protocol type, or the URL scheme for a generic URL. For
example, in the abstract type name "service:printing:ipp", the method
returns "printing". In the protocol type name "service:ftp", the
method returns "ftp".
public String getAbstractTypeName()
If the type is an abstract type, returns the fully formatted abstract
type name including the "service:" and naming authority but without
the concrete type name or intervening colon. If not an abstract
type, returns the empty string. For example, in the abstract type
name "service:printing:ipp", the method returns "service:printing".
public String getNamingAuthority()
Return the naming authority name, or the empty string if the naming
authority is the default.
public boolean equals(Object obj)
Overrides Object.equals(). The two objects are equal if they are
both ServiceType objects and the components of both are equal.
public String toString()
Returns the fully formatted type name, including the "service:" if
the type was originally from a service: URL.
public int hashCode()
Overrides Object.hashCode(). Hashes on the string value of the
"service" prefix, naming authority, if any, abstract and concrete
type names for abstract types, protocol type name for protocol types,
and URL scheme for generic URLs.
5.3.4. Class ServiceURL
5.3.4.1. Synopsis
public class ServiceURL extends Object implements Serializable
5.3.4.2. Description
The ServiceURL object models the advertised SLP service URL. It can
be either a service: URL or a regular URL. These objects are
returned from service lookup requests, and describe the registered
services. This class should be a subclass of java.net.URL but can't
since that class is final.
5.3.4.3. Class Variables
public static final int NO_PORT = 0
Indicates that no port information is required or was returned for
this URL.
public static final int LIFETIME_NONE = 0
Indicates that the URL has a zero lifetime. This value is never
returned from the API, but can be used to create a ServiceURL object
to deregister, delete attributes, or find attributes.
public static final int LIFETIME_DEFAULT = 10800
The default URL lifetime (3 hours) in seconds.
public static final int LIFETIME_MAXIMUM = 65535
The maximum URL lifetime (about 18 hours) in seconds.
public static final int LIFETIME_PERMANENT = -1
Indicates that the API implementation should continuously re-register
the URL until the application exits.
5.3.4.4. Constructors
public ServiceURL(String URL,int lifetime)
Construct a service URL object having the specified lifetime.
Parameters:
URL
The URL as a string. Must be either a service: URL or a valid
generic URL according to RFC2396 [2].
lifetime
The service advertisement lifetime in seconds. This value may
be between LIFETIME_NONE and LIFETIME_MAXIMUM.
5.3.4.5. Methods
public ServiceType getServiceType()
Returns the service type object representing the service type name of
the URL.
public final void setServiceType(ServiceType type)
throws ServiceLocationException
Set the service type name to the object. Ignored if the URL is a
service: URL.
Parameters:
type
The service type object.
public String getTransport()
Get the network layer transport identifier. If the transport is IP,
an empty string, "", is returned.
public String getHost()
Returns the host identifier. For IP, this will be the machine name
or IP address.
public int getPort()
Returns the port number, if any. For non-IP transports, always
returns NO_PORT.
public String getURLPath()
Returns the URL path description, if any.
public int getLifetime()
Returns the service advertisement lifetime. This will be a positive
int between LIFETIME_NONE and LIFETIME_MAXIMUM.
public boolean equals(Object obj)
Compares the object to the ServiceURL and returns true if the two are
the same. Two ServiceURL objects are equal if their current service
types match and they have the same host, port, transport, and URL
path.
public String toString()
Returns a formatted string with the URL. Overrides Object.toString().
The returned URL has the original service type or URL scheme, not the
current service type.
public int hashCode()
Overrides Object.hashCode(). Hashes on the current service type,
transport, host, port, and URL part.
5.4. SLP Access Interfaces
5.4.1. Interface Advertiser
5.4.1.1. Synopsis
public interface Advertiser
5.4.1.2. Description
The Advertiser is the SA interface, allowing clients to register new
service instances with SLP, to change the attributes of existing
services, and to deregister service instances. New registrations and
modifications of attributes are made in the language locale with
which the Advertiser was created, deregistrations of service
instances are made for all locales.
5.4.1.3. Instance Methods
public abstract Locale getLocale()
Return the language locale with which this object was created.
public abstract void register(ServiceURL URL,
Vector attributes)
throws ServiceLocationException
Register a new service with SLP having the given attributes.
The API library is required to perform the operation in all
scopes obtained through configuration.
Parameters:
URL
The URL for the service.
attributes
A vector of ServiceLocationAttribute objects describing the
service.
public abstract void deregister(ServiceURL URL)
throws ServiceLocationException
Deregister a service from the SLP framework. This has the effect
of deregistering the service from every language locale. The API
library is required to perform the operation in all scopes obtained
through configuration.
Parameters:
URL
The URL for the service.
public abstract void
addAttributes(ServiceURL URL,
Vector attributes)
throws ServiceLocationException
Update the registration by adding the given attributes. The API
library is required to perform the operation in all scopes obtained
through configuration.
Parameters:
URL
The URL for the service.
attributes
A Vector of ServiceLocationAttribute objects to add to the
existing registration. Use an empty vector to update the URL
alone. May not be null.
public abstract void
deleteAttributes(ServiceURL URL,
Vector attributeIds)
throws ServiceLocationException
Delete the attributes from a URL for the locale with which the
Advertiser was created. The API library is required to perform the
operation in all scopes obtained through configuration.
Parameters:
URL
The URL for the service.
attributeIds
A vector of Strings indicating the ids of the attributes
to remove. The strings may be attribute ids or they
may be wildcard patterns to match ids. See [7] for the
syntax of wildcard patterns. The strings may include SLP
reserved characters, they will be escaped by the API before
transmission. May not be the empty vector or null.
5.4.2. Interface Locator
5.4.2.1. Synopsis
public interface Locator
5.4.2.2. Description
The Locator is the UA interface, allowing clients to query the SLP
framework about existing service types, services instances, and about
the attributes of an existing service instance or service type.
Queries for services and attributes are made in the locale with which
the Locator was created, queries for service types are independent of
locale.
5.4.2.3. Instance Methods
public abstract Locale getLocale()
Return the language locale with which this object was created.
public abstract ServiceLocationEnumeration
findServiceTypes(String namingAuthority,
Vector scopes)
throws ServiceLocationException
Returns an enumeration of ServiceType objects giving known service
types for the given scopes and given naming authority. If no service
types are found, an empty enumeration is returned.
Parameters:
namingAuthority
The naming authority. Use "" for the default naming authority
and "*" for all naming authorities.
scopes
A Vector of scope names. The vector should be selected from
the results of a findScopes() API invocation. Use "DEFAULT"
for the default scope.
public abstract ServiceLocationEnumeration
findServices(ServiceType type,
Vector scopes,
String searchFilter)
throws ServiceLocationException
Returns a vector of ServiceURL objects for services matching the
query, and having a matching type in the given scopes. If no
services are found, an empty enumeration is returned.
Parameters:
type
The SLP service type of the service.
scopes
A Vector of scope names. The vector should be selected from
the results of a findScopes() API invocation. Use "DEFAULT"
for the default scope.
searchFilter
An LDAPv3 [4] string encoded query. If the filter is empty,
i.e. "", all services of the requested type in the specified
scopes are returned. SLP reserved characters must be escaped
in the query. Use ServiceLocationAttribute.escapeId() and
ServiceLocationAttribute.escapeValue() to construct the query.
public abstract ServiceLocationEnumeration
findAttributes(ServiceURL URL,
Vector scopes,
Vector attributeIds)
throws ServiceLocationException
For the URL and scope, return a Vector of ServiceLocationAttribute
objects whose ids match the String patterns in the attributeIds
Vector. The request is made in the language locale of the Locator.
If no attributes match, an empty enumeration is returned.
Parameters:
URL
The URL for which the attributes are desired.
scopes
A Vector of scope names. The vector should be selected from
the results of a findScopes() API invocation. Use "DEFAULT"
for the default scope.
attributeIds
A Vector of String patterns identifying the desired attributes.
An empty vector means return all attributes. As described
in [7], the patterns may include wildcards to match substrings.
The strings may include SLP reserved characters, they will be
escaped by the API before transmission.
public abstract ServiceLocationEnumeration
findAttributes(ServiceType type,
Vector scopes,
Vector attributeIds)
throws ServiceLocationException
For the type and scope, return a Vector of all ServiceLocationAttribute
objects whose ids match the String patterns in the attributeIds
Vector regardless of the Locator's locale. The request is made
independent of language locale. If no attributes are found, an empty
vector is returned.
Parameters:
serviceType
The service type.
scopes
A Vector of scope names. The vector should be selected from
the results of a findScopes() API invocation. Use "DEFAULT"
for the default scope.
attributeIds
A Vector of String patterns identifying the desired
attributes. An empty vector means return all attributes.
As described in [7], the patterns may include wildcards to
match all prefixes or suffixes. The patterns may include SLP
reserved characters, they will be escaped by the API before
transmission.
5.5. The Service Location Manager
5.5.1. Class ServiceLocationManager
5.5.1.1. Synopsis
public class ServiceLocationManager
extends Object
5.5.1.2. Description
The ServiceLocationManager manages access to the service location
framework. Clients obtain the Locator and Advertiser objects for UA
and SA, and a Vector of known scope names from the
ServiceLocationManager.
5.5.1.3. Class Methods
public static int getRefreshInterval()
throws ServiceLocationException
Returns the maximum across all DAs of the min-refresh-interval
attribute. This value satisfies the advertised refresh interval
bounds for all DAs, and, if used by the SA, assures that no
refresh registration will be rejected. If no DA advertises a
min-refresh-interval attribute, a value of 0 is returned.
public static Vector findScopes()
throws ServiceLocationException
Returns an Vector of strings with all available scope names. The
list of scopes comes from a variety of sources, see Section 2.1 for
the scope discovery algorithm. There is always at least one string
in the Vector, the default scope, "DEFAULT".
public static Locator
getLocator(Locale locale)
throws ServiceLocationException
Return a Locator object for the given language Locale. If the
implementation does not support UA functionality, returns null.
Parameters:
locale
The language locale of the Locator. The default SLP locale is
used if null.
public static Advertiser
getAdvertiser(Locale locale)
throws ServiceLocationException
Return an Advertiser object for the given language locale. If the
implementation does not support SA functionality, returns null.
Parameters:
locale
The language locale of the Advertiser. The default SLP locale
is used if null.
5.6. Service Template Introspection
5.6.1. Abstract Class TemplateRegistry
5.6.1.1. Synopsis
public abstract class TemplateRegistry
5.6.1.2. Description
Subclasses of the TemplateRegistry abstract class provide access to
service location templates [8]. Classes implementing
TemplateRegistry perform a variety of functions. They manage the
registration and access of service type template documents. They
create attribute verifiers from service templates, for verification
of attributes and introspection on template documents. Note that
clients of the Advertiser are not required to verify attributes
before registering (though they may get a TYPE_ERROR if the
implementation supports type checking and there is a mismatch with
the template).
5.6.1.3. Class Methods
public static TemplateRegistry getTemplateRegistry();
Returns the distinguished TemplateRegistry object for performing
operations on and with service templates. Returns null if the
implementation doesn't support TemplateRegistry functionality.
5.6.1.4. Instance Methods
public abstract void
registerServiceTemplate(ServiceType type,
String documentURL,
Locale locale,
String version)
throws ServiceLocationException
Register the service template with the template registry.
Parameters:
type
The service type.
documentURL
A string containing the URL of the template document. May not
be the empty string.
locale
A Locale object containing the language locale of the template.
version
The version number identifier of template document.
public abstract void
deregisterServiceTemplate(ServiceType type,
Locale locale,
String version)
throws ServiceLocationException
Deregister the template for the service type.
Parameters:
type
The service type.
locale
A Locale object containing the language locale of the template.
version
A String containing the version number. Use null to indicate
the latest version.
public abstract
String findTemplateURL(ServiceType type,
Locale locale,
String version)
throws ServiceLocationException
Returns the URL for the template document.
Parameters:
type
The service type.
locale
A Locale object containing the language locale of the template.
version
A String containing the version number. Use null to indicate
the latest version.
public abstract
ServiceLocationAttributeVerifier
attributeVerifier(String documentURL)
throws ServiceLocationException
Reads the template document URL and returns an attribute verifier
for the service type. The attribute verifier can be used for
verifying that registration attributes match the template, and for
introspection on the template definition.
Parameters:
documentURL
A String containing the template document's URL. May not be the
empty string.
5.6.2. Interface ServiceLocationAttributeVerifier
5.6.2.1. Synopsis
public interface ServiceLocationAttributeVerifier
5.6.2.2. Description
The ServiceLocationAttributeVerifier provides access to service
templates. Classes implementing this interface parse SLP template
definitions, provide information on attribute definitions for service
types, and verify whether a ServiceLocationAttribute object matches a
template for a particular service type. Clients obtain
ServiceLocationAttributeVerifier objects for specific SLP service
types through the TemplateRegistry.
5.6.2.3. Instance Methods
public abstract ServiceType getServiceType()
Returns the SLP service type for which this is the verifier.
public abstract Locale getLocale()
Return the language locale of the template.
public abstract String getVersion()
Return the template version number identifier.
public abstract String getURLSyntax()
Return the URL syntax expression for the service: URL.
public abstract String getDescription()
Return the descriptive help text for the template.
public abstract ServiceLocationAttributeDescriptor
getAttributeDescriptor(String attrId)
Return the ServiceLocationAttributeDescriptor for the attribute
having the named id. If no such attribute exists in this template,
return null. This method is primarily for GUI tools to display
attribute information. Programmatic verification of attributes
should use the verifyAttribute() method.
public abstract Enumeration
getAttributeDescriptors()
Returns an Enumeration allowing introspection on the attribute
definition in the service template. The Enumeration returns
ServiceLocationAttributeDescriptor objects for the attributes.
This method is primarily for GUI tools to display attribute
information. Programmatic verification of attributes should use the
verifyAttribute() method.
public abstract void
verifyAttribute(
ServiceLocationAttribute attribute)
throws ServiceLocationException
Verify that the attribute matches the template definition. If the
attribute doesn't match, ServiceLocationException is thrown with the
error code as ServiceLocationException.PARSE_ERROR.
Parameters:
attribute
The ServiceLocationAttribute object to be verified.
public abstract void
verifyRegistration(
Vector attributeVector)
throws ServiceLocationException
Verify that the Vector of ServiceLocationAttribute objects matches
the template for this service type. The vector must contain all the
required attributes, and all attributes must match their template
definitions. If the attributes don't match, ServiceLocationException
is thrown with the error code as ServiceLocationException.PARSE_ERROR
Parameters:
attributeVector
A Vector of ServiceLocationAttribute objects for the
registration.
5.6.3. Interface ServiceLocationAttributeDescriptor
5.6.3.1. Synopsis
public interface
ServiceLocationAttributeDescriptor
5.6.3.2. Description
The ServiceLocationAttributeDescriptor interface provides
introspection on a template attribute definition. Classes
implementing the ServiceLocationAttributeDescriptor interface return
information on a particular service location attribute definition
from the service template. This information is primarily for GUI
tools. Programmatic attribute verification should be done through
the ServiceLocationAttributeVerifier.
5.6.3.3. Instance Methods
public abstract String getId()
Return a String containing the attribute's id.
public abstract String getValueType()
Return a String containing the fully package-qualified Java type of
the attribute. SLP types are translated into Java types as follows:
STRING
"java.lang.String"
INTEGER
"java.lang.Integer"
BOOLEAN
"java.lang.Boolean"
OPAQUE
"[B" (i.e. array of byte, byte[])
KEYWORD
empty string, ""
public abstract String getDescription()
Return a String containing the attribute's help text.
public abstract Enumeration
getAllowedValues()
Return an Enumeration of allowed values for the attribute type.
For keyword attributes returns null. For no allowed values (i.e.
unrestricted) returns an empty Enumeration.
public abstract Enumeration
getDefaultValues()
Return an Enumeration of default values for the attribute type.
For keyword attributes returns null. For no allowed values (i.e.
unrestricted) returns an empty Enumeration.
public abstract boolean
getRequiresExplicitMatch()
Returns true if the "X"" flag is set, indicating that the attribute
should be included in an any Locator.findServices() request search
filter.
public abstract boolean getIsMultivalued()
Returns true if the "M" flag is set.
public abstract boolean getIsOptional()
Returns true if the "O"" flag is set.
public abstract boolean getIsLiteral()
Returns true if the "L" flag is set.
public abstract boolean getIsKeyword()
Returns true if the attribute is a keyword attribute.
5.7. Implementation Notes
5.7.1. Refreshing Registrations
A special lifetime constant, ServiceURL.LIFETIME_PERMANENT, is used
by clients to indicate that the URL should be automatically refreshed
until the application exits. The API implementation should interpret
this flag as indicating that the URL lifetime is
ServiceURL.LIFETIME_MAXIMUM, and MUST arrange for automatic refresh
to occur.
5.7.2. Parsing Alternate Transports in ServiceURL
The ServiceURL class is designed to handle multiple transports. The
standard API performs no additional processing on transports other
than IP except to separate out the host identifier and the URL path.
However, implementations are free to subclass ServiceURL and support
additional methods that provide more detailed parsing of alternate
transport information. For IP transport, the port number, if any, is
returned from the getPort() method. For non-IP transports, the
getPort() method returns NO_PORT.
5.7.3. String Attribute Values
In general, translation between Java types for attribute values and
the SLP on-the-wire string is straightforward. However, there are
two corner cases. If the Java attribute value type is String and the
value of the string has an on-the-wire representation that is
inferred by SLP as an integer, the registered attribute value may not
be what the API client intended. A similar problem could result if
the Java attribute value is the string "true" or "false", in which
case the on-the-wire representation is inferred to boolean. To
handle these corner cases, the Java API prepends a space onto the
string. So, for example, if the string attribute value is "123", the
Java API transforms the value to "123 ", which will have an on-the-
wire representation that is inferred by SLP to be string. Since
appended and prepended spaces have no effect on query handling, this
procedure should cause no problem with queries. API clients need to
be aware, however, that the transformation is occurring.
5.7.4. Client Side Syntax Checking
The syntax of scope names, service type names, naming authority
names, and URLs is described in [7] and [8]. The various methods and
classes taking String parameters for these entities SHOULD type check
the parameters for syntax errors on the client side, and throw an
IllegalArgumentException if an error occurs. In addition, character
escaping SHOULD be implemented before network transmission for
escapable characters in attribute ids and String values. This
reduces the number of error messages transmitted. The
ServiceLocationAttribute class provides methods for clients to obtain
escaped attribute id and value strings to facilitate query
construction.
5.7.5. Language Locale Handling
The Locator and Advertiser interfaces are created with a Locale
parameter. The language locale with which these objects are created
is used in all SLP requests issued through the object. If the Locale
parameter is null, the default SLP locale is used. The default SLP
locale is determined by, first, checking the net.slp.locale System
property. If that is unset, then the default SLP locale [7] is used,
namely "en". Note that the default SLP locale may not be the same as
the default Java locale.
5.7.6. Setting SLP System Properties
SLP system properties that are originally set in the configuration
file can be overridden programmatically in API clients by simply
invoking the System.getProperties() operation to get a copy of the
system properties, modifying or adding the SLP property in question,
then using System.setProperties() to set the properties to the
modified Property object. Program execution continues without
interruption by substituting the default for the erroneous parameter.
Errors are checked when the property is used and are logged.
The SLP configuration file cannot be read with the
java.util.Properties file reader because there are some syntactic
differences. The SLP configuration file syntax defines a different
escape convention for non-ASCII characters than the Java syntax.
However, after the file has been read, the properties are stored and
retrieved from java.util.Properties objects.
Properties are global for a process, affecting all threads and all
Locator and Advertiser objects obtained through the
ServiceLocationManager. With the exception of the net.slp.locale,
net.slp.typeHint, and net.slp.maxResults properties, clients should
rarely be required to override these properties, since they reflect
properties of the SLP network that are not of concern to individual
agents. If changes are required, system administrators should modify
the configuration file.
5.7.7. Multithreading
Thread-safe operation is relatively easy to achieve in Java. By
simply making each method in the classes implementing the Locator and
Advertiser interfaces synchronized, and by synchronizing access to
any shared data structures within the class, the Locator and
Advertiser interfaces are made safe. Alternatively, finer grained
synchronization is also possible within the classes implementing
Advertiser and Locator.
5.7.8. Modular Implementations
While, at first glance, the API may look rather heavyweight, the
design has been carefully arranged so that modular implementations
that provide only SA, only UA, or only service template access
capability, or any combination of the three, are possible.
Because the objects returned from the
ServiceLocationManager.getLocator() and
ServiceLocationManager.getAdvertiser() operations are interfaces, and
because the objects returned through those interfaces are in the set
of base data structures, an implementation is free to omit either UA
or SA capability by simply returning null from the instance creation
operation if the classes implementing the missing function cannot be
dynamically linked. API clients are encouraged to check for such a
contingency, and to signal an exception if it occurs. Similarly, the
TemplateRegistry concrete subclass can simply be omitted from an
implementation that only supports UA and/or SA clients, and the
TemplateRegistry.getRegistry() method can return null. In this way,
the API implementation can be tailored for the particular memory
requirements at hand.
In addition, if an implementation only supports the minimal subset of
SLP [7], the unsupported Locator and Advertiser interface operations
can throw an exception with ServiceLocationException.NOT_IMPLEMENTED
as the error code. This supports better source portability between
low and high memory platforms.
5.7.9. Asynchronous and Incremental Return Semantics
The Java API contains no specific support for asynchronous operation.
Incremental return is not needed for the Advertiser because service
registrations can be broken up into pieces when large. Asynchronous
return is also not needed because clients can always issue the
Advertiser operation in a separate thread if the calling thread can't
block.
The Locator can be implemented either synchronously or
asynchronously. Since the return type for Locator calls is
ServiceLocationEnumeration, a Java API implementation that supports
asynchronous semantics can implement ServiceLocationEnumeration to
dole results out as they come in, blocking when no results are
available. If the client code needs to support other processing
while the results are trickling in, the call into the enumeration to
retrieve the results can be done in a separate thread.
Unlike the C case, collation semantics for return of attributes when
an attribute request by service type is made require that the API
collate returned values so that only one attribute having a collation
of all returned values appear to the API client. In practice, this
may limit the amount of asynchronous processing possible with the
findAttributes() method. This requirement is imposed because memory
management is much easier in Java and so implementing collation as
part of the API should not be as difficult as in C, and it saves the
client from having to do the collation.
5.8. Example
In this example, a printer server advertises its availability to
clients. Additionally, the server advertises a service template for
use by client software in validating service requests:
//Get the Advertiser and TemplateRegistry.
Advertiser adv = null;
TemplateRegistry tr = null
try {
adv = ServiceLocationManager.getAdvertiser("en");
tr = TemplateRegistry.getTemplateRegistry();
} catch( ServiceLocationException ex ) { } //Deal with error.
if( adv == null ) {
//Serious error as printer can't be registered
// if the implementation doesn't support SA
// functionality.
}
//Get the printer's attributes, from a file or
// otherwise. We assume that the attributes
// conform to the template, otherwise, we
// could register the template here and verify
// them.
Vector attributes = getPrinterAttributes();
//Create the service: URL for the printer.
ServiceURL printerURL =
new ServiceURL(
"service:printer:lpr://printshop/color2",
ServiceURL.LIFETIME_MAXIMUM);
try {
//Register the printer.
adv.register(printerURL, attributes);
//If the template registry is available,
// register the printer's template.
if( tr != null ) {
tr.registerServiceTemplate(
new ServiceType("service:printer:lpr"),
"http://shop.arv/printer/printer-lpr.slp",
new Locale("en",""),
"1.0");
}
} catch( ServiceLocationException ex ) { } //Deal with error.
Suppose a client is looking for color printer. The following code is
used to issue a request for printer advertisements:
Locator loc = null;
TemplateRegistry tr = null;
try {
loc = ServiceLocationManager.getLocator("en");
} catch( ServiceLocationException ex ) { } //Deal with error.
if( loc == null ) {
//Serious error as client can't be located
// if the implementation doesn't support
// UA functionality.
}
//We want a color printer that does CMYK
// and prints at least 600 dpi.
String query = "(&(marker-type=CMYK)(resolution=600))";
//Get scopes.
Vector scopes = ServiceLocationManager.findScopes();
Enumeration services;
try {
services =
loc.findServices(new ServiceType("service:printer"),scopes,query);
} catch { } //Deal with error.
if (services.hasMoreElements() ) {
//Printers can now be used.
ServiceURL surl = (ServiceURL) services.next();
Socket sock = new Socket(surl.getHost, surl.getPort());
// Use the Socket...
}
6. Internationalization Considerations
6.1. service URL
The service URL itself must be encoded using the rules set forth in
[2]. The character set encoding is limited to specific ranges within
the UTF-8 character set [3].
The attribute information associated with the service URL must be
expressed in UTF-8. See [8] for attribute internationalization
guidelines.
6.2. Character Set Encoding
Configuration and serialized registration files are encoded in the
UTF-8 character set [3]. This is fully compatible with US-ASCII
character values. C platforms that do not support UTF-8 are required
to check the top bit of input bytes to determine whether the incoming
character is multibyte. If it is, the character should be dealt with
accordingly. This should require no additional implementation
effort, since the SLP wire protocol requires that strings are encoded
as UTF-8. C platforms without UTF-8 support need to supply their own
support, if only in the form of multibyte string handling.
At the API level, the character encoding is specified to be Unicode
for Java and UTF-8 for C. Unicode is the default in Java. For C, the
standard US-ASCII 8 bits per character, null terminated C strings are
a subset of the UTF-8 character set, and so work in the API. Because
the C API is very simple, the API library needs to do a minimum of
processing on UTF-8 strings. The strings primarily just need to be
reflected into the outgoing SLP messages, and reflected out of the
API from incoming SLP messages.
6.3. Language Tagging
All SLP requests and registrations are tagged to indicate in which
language the strings included are encoded. This allows multiple
languages to be supported. It also presents the possibility that
error conditions result when a request is made in a language that is
not supported. In this case, an error is only returned when there is
data available, but not obtainable in the language requested.
The dialect portion of the Language Tag is used on 'best effort'
basis for matching strings by SLP. Dialects that match are preferred
over those which don't. Dialects that do not match will not prevent
string matching or comparisons from occurring.
7. Security Considerations
Security is handled within the API library and is not exposed to API
clients except in the form of exceptions. The
net.slp.securityEnabled, property determines whether an SA client's
messages are signed, but a UA client should be prepared for an
authentication exception at any time, because it may contact a DA
with authenticated advertisements.
An adversary could delete valid service advertisements, provide false
service information and deny UAs knowledge of existing services
unless the mechanisms in SLP for authenticating SLP messages are
used. These mechanisms allow DAAdverts, SAAdverts, Service URLs and
Service Attributes to be verified using digital cryptography. For
this reason, all SLP agents should be configured to use SLP SPIs.
See [7] for a description of how this mechanism works.
8. Acknowledgements
The authors would like to thank Don Provan for his pioneering work
during the initial stages of API definition.
9. References
[1] Bradner, S., "Key Words for Use in RFCs to Indicate
Requirement Levels", BCP 14, RFC2119, March 1997.
[2] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
Resource Identifiers (URI): Generic Syntax", RFC2396,
August 1998.
[3] Yergeau, F., "UTF-8, a transformation format of ISO 10646",
RFC2279, January 1998.
[4] Howes, T., "The String Representation of LDAP Search Filters",
RFC2254 December 1997.
[5] Crocker, D. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", RFC2234, November 1997.
[6] Alvestrand, H., "Tags for the Identification of Languages",
RFC1766, March 1995.
[7] Guttman, E., Perkins, C., Veizades, J. and M. Day, "Service
Location Protocol, Version 2", RFC2608, June 1999.
[8] Guttman, E., Perkins, C. and J. Kempf, "Service Templates and
Service: Schemes", RFC2609, June 1999.
10. Authors' Addresses
Questions about this memo can be directed to:
James Kempf
Sun Microsystems
901 San Antonio Rd.
Palo Alto, CA, 94303
USA
Phone: +1 650 786 5890
Fax: +1 650 786 6445
EMail: james.kempf@sun.com
Erik Guttman
Sun Microsystems
Bahnstr. 2
74915 Waibstadt
Germany
Phone: +49 7263 911 701
EMail: erik.guttman@sun.com
11. Full Copyright Statement
Copyright (C) The Internet Society (1999). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
Acknowledgement
Funding for the RFCEditor function is currently provided by the
Internet Society.