mulgara - semantic store

skip navigation

SHOW SITE NAV
fixed
fluid
straight

Factories

Factories are an important part of the resolver framework as they are responsible for both creating resolver instances and registering themselves with the appropriate protocols. They also act as a bridge between resolvers and sessions, assigning it the session it will be working for, along with any other initial data or configuration that is required. For Internal Resolvers the factory also manages the cleanup of any persistent resources when the database or factory shuts down.

Most of the decisions to be made about the resolver are made when creating the resolver itself. See the Creating the Resolver section for more information. You should at least know the protocol the resolver is associating itself with when writing the factory. For this tutorial we are creating a resolver that resolves http URLs (both secure and non-secure). If the resolver's purpose is to handle a file type, such as MP3, then a content handler should be written instead of the resolver. See the Creating the Content Handler section for more information.

The resolver classes should be reserved mainly for resolving a protocol type, which then refers to the content handlers for the statements.

 
Writing a Factory

After deciding on the protocol to resolve, write the factory to obtain instances of the resolver. This is a compulsory step for any type of resolver, as without it, the database has no way of obtaining resolver instances for its sessions. The following code represents a factory that creates and manages our http resolver instances (extracted from HttpResolverFactory.java):

package org.mulgara.resolver.http;

// Java 2 standard packages
import java.io.*;
import java.net.*;
import java.util.List;

// Third party packages
import org.apache.log4j.Logger;

// Locally written packages
import org.mulgara.query.rdf.Mulgara;
import org.mulgara.query.rdf.URIReferenceImpl;
import org.mulgara.resolver.spi.*;

public class HttpResolverFactory implements ResolverFactory {
/**
* Logger.
*/
private static Logger logger =
Logger.getLogger(HttpResolverFactory.class.getName());

private final List contentHandlerList;

/**
* Instantiate a {@link HttpResolverFactory}.
*/
private HttpResolverFactory(ResolverFactoryInitializer resolverFactoryInitializer)
throws FactoryInitializerException {

// Validate "resolverFactoryInitializer" parameter
if (resolverFactoryInitializer == null) {

throw new IllegalArgumentException(
"Null \"resolverFactoryInitializer\" parameter");
}

// Obtain the content handler list
contentHandlerList = resolverFactoryInitializer.getContentHandlerList();

// Claim the http: protocol
resolverFactoryInitializer.addProtocol("http", this);
***resolverFactoryInitializer.addProtocol("https", this);***
}

/**
* {@inheritDoc ResolverFactory}
*
* This is actually a non-operation, because the only persistent resources
* are outside the database.
*/
public void close() {
// null implementation
}

/**
* {@inheritDoc ResolverFactory}
*
* This is actually a non-operation, because the only persistent resources
* are outside the database.
*/
public void delete() {
// null implementation
}

/**
* Register this resolver upon database startup.
*
* @param resolverFactoryInitializer the database within which to find or
* create the various XML Schema resources
* @throws FactoryInitializerException if the XML Schema resources
* can't be found or created
*/
public static ResolverFactory newInstance(ResolverFactoryInitializer resolverFactoryInitializer)
throws FactoryInitializerException {

return new HttpResolverFactory(resolverFactoryInitializer);
}

/**
* Obtain an http resolver.
*
* @param resolverSession the session which this query is local to
* @param canWrite {@inheritDoc}; ignored in this implementation
*
* @throws IllegalArgumentException if resolverSession is
* null
* @throws ResolverFactoryException {@inheritDoc}
*/
public Resolver newResolver(boolean canWrite, ResolverSession resolverSession,
Resolver systemResolver)
throws ResolverFactoryException {

return new HttpResolver(resolverSession, systemResolver, contentHandlerList);
}
}

An analysis of the factory is as follows:

package org.mulgara.resolver.http;

// Java 2 standard packages
import java.io.*;
import java.net.*;
import java.util.List;

// Third party packages
import org.apache.log4j.Logger;

// Locally written packages
import org.mulgara.query.rdf.Mulgara;
import org.mulgara.query.rdf.URIReferenceImpl;
import org.mulgara.resolver.spi.*;

Factories and resolvers are not required to be in the same package as the Mulgara resolvers. As long as the custom resolver classes are accessible by the Mulgara resolver framework it does not matter how you structure the packaging. The org.mulgara.resolver.spi package requires importing to allow access to the resolver framework and APIs.

public class HttpResolverFactory implements ResolverFactory {

All factories are required to implement the ResoverFactory API.

/**
* Instantiate a {@link HttpResolverFactory}.
*/
private HttpResolverFactory(ResolverFactoryInitializer resolverFactoryInitializer)
throws FactoryInitializerException {

// Validate "resolverFactoryInitializer" parameter
if (resolverFactoryInitializer == null) {

throw new IllegalArgumentException(
"Null \"resolverFactoryInitializer\" parameter");
}

// Obtain the content handler list
contentHandlerList = resolverFactoryInitializer.getContentHandlerList();

// Claim the http: protocol
resolverFactoryInitializer.addProtocol("http", this);
resolverFactoryInitializer.addProtocol("https", this);
}

Constructors for resolver factories should be private as they are managed by an API call that creates new instances as required. The ResolverFactoryInitializer object passed in contains initialization information for the parent resolver factory allowing new factory objects to register themselves so they can receive constraints to resolve.

Once the factory object is created it should not hold onto the initialization object as this causes errors if anything is invoked on it later. During construction the factory should register itself with the protocol or protocols, which lets the database know that queries against models with this protocol should be directed to our resolver. This is achieved using the resolverFactoryInitializer.addProtocol(String, Resolver); method.

/**
* {@inheritDoc ResolverFactory}
*
* This is actually a non-operation, because the only persistent resources
* are outside the database.
*/
public void close() {
// null implementation
}

/**
* {@inheritDoc ResolverFactory}
*
* This is actually a non-operation, because the only persistent resources
* are outside the database.
*/
public void delete() {
// null implementation
}

Both the delete() and close() operations are used for freeing persistent resources involved with the factory when either it or the database are being shut down. External Resolvers usually do not require any releasing of resources as they are managed externally and do not interact with the database resources.

/**
* Register this resolver upon database startup.
*
* @param resolverFactoryInitializer the database within which to find or
* create the various XML Schema resources
* @throws FactoryInitializerException if the XML Schema resources
* can't be found or created
*/
public static ResolverFactory newInstance(ResolverFactoryInitializer resolverFactoryInitializer)
throws FactoryInitializerException {

return new HttpResolverFactory(resolverFactoryInitializer);
}

Factories should have private constructors and are instantiated and returned via an API call to the newInstance(ResolverFactoryInitializer) method. Configuration of the factory should occur in the constructor, but any pre-initialization can occur in this method.

/**
* Obtain an http resolver.
*
* @param resolverSession the session which this query is local to
* @param canWrite {@inheritDoc}; ignored in this implementation
*
* @throws IllegalArgumentException if resolverSession is
* null
* @throws ResolverFactoryException {@inheritDoc}
*/
public Resolver newResolver(boolean canWrite, ResolverSession resolverSession,
Resolver systemResolver)
throws ResolverFactoryException {

return new HttpResolver(resolverSession, systemResolver, contentHandlerList);
}

The purpose of a resolver factory is to create resolver objects and the newResolver(boolean, ResolverSession, systemResolver) method handles this process. It is the responsibility of the resolver to manage its setup and configuration using the parameters entered. The factory might also be responsible for creating a read-only, or read-write resolver, depending on the allowWrites parameter.

Valid XHTML 1.0 TransitionalValid CSS 3.0!