Locators

TM4J provides a flexible and extensible mechanism for creating and managing locators of any number of different notations. Instances of the Locator interface are created by a factory object (which implements the org.tm4j.net.LocatorFactory) interface. The LocatorFactory interface supports runtime alteration of the classes used to represent a particular locator notation.

Locator

The org.tm4j.net.Locator interface defines the minimum set of operations which must be supported by an object which represents a resource locator. These operations include accessors to retrieve the string identifier of the notation of the locator and to retrieve the string representation of the locator's address. A copy of a locator can be made by calling the copy() method and Locators can be tested for equality using the equals() method.

The method resolveRelative() creates a new Locator object whose address is defined by resolving a supplied Locator instance or address string relative to the address of this Locator. For example, if you create a URI notation locator with the address string http://www.example.com/folder/doc1 and then call the resolveRelative() method on that Locator instance with the string "../folder2/doc2", a new Locator instance will be created and returned with its address string set to "http://www.example.com/folder2/doc2".

URILocator

The org.tm4j.net.URILocator interface extends the org.tm4j.net.Locator interface to provide a more fine-grained access to the URI address. A URI address string is split into 5 parts, the scheme, the authority, the path, a fragment identifier and a query string. Not all of these 5 parts is present in all URIs. In addition to providing methods to access these 5 parts of a URI, the URILocator interface also allows the path part to be accessed as an array of path element strings (each string is one element of the path and the path elements are presented in the order that they appear in the URI).

LocatorFactory

The org.tm4j.net.LocatorFactory interface provides a basic interface for the creation of new org.tm4j.net.Locator instances. In general, instances of the Locator interface should only ever be created using the either the copy() or resolveRelative() methods of the Locator interface or using the createLocator() method of the LocatorFactory interface.

The LocatorFactory interface also provides extensibile support for new locator notations. As already discussed, TM4J supports URI notation locators, however this extensibility mechanism allows applications to register supporting classes to handle other forms of addressing mechanism (e.g. HyTime locators).

When the createLocator() method of the LocatorFactory interface is called, the factory object will determine which class implements support for the notation of the locator and will create a new instance of that class and pass the notation and address strings to the initialise() method of the class. To define the class which implements support for a notation, you must call the method registerImplementation(), specifying the notation string of the supported notation and the Java class which provides this support - the specified class must implement the Locator interface.

Note

The default implementations of LocatorFactory provided by the in-memory and Ozone back-ends are provided "pre-initialised" with a mapping for the notation "URI" to the appropriate implementation class. This means that in normal operation using only URI locators (URIs, URLs or URNs), there is no need to call registerImplementation().

Note

At the time of writing, the Hibernate back-end only supports the "URI" notation and does not implement the registerImplementation() method. This will be implemented in a later version of TM4J.

LocatorResolver and LocatorResolverManager

The org.tm4j.net.LocatorResolverManager is responsible for managing a collection of org.tm4j.net.LocatorResolver objects. Each LocatorResolver instance can resolve locator addresses in one or more different notations into Java java.io.InputStream instancess which may be used to retrieve the resource content. To retrieve the LocatorResolver for a specific notation, simply call the getResolver() method passing in the notation string from the Locator to be resolved. New implementations may be registered with the LocatorResolverManager by calling the addResolver() method - if the LocatorResolverManager already manages a resolver for the specified notation, then the previous LocatorResolver will be replaced by the new one and the handle to the old LocatorResolver will be returned to the caller (allowing any clean-up to take place).

To retrieve the data that a Locator points to, you must first get the LocatorResolver for the Locator notation and then call the resolve() method of the LocatorResolver object. This method will return an InputStream from which the resource data may be read.