org.modeshape.graph.connector
Interface RepositorySource

All Superinterfaces:
Referenceable, Serializable
All Known Subinterfaces:
BaseRepositorySource, MapRepositorySource, PathRepositorySource
All Known Implementing Classes:
AbstractPathRepositorySource, AbstractRepositorySource, BaseInfinispanSource, FederatedRepositorySource, FileSystemSource, InfinispanSource, InMemoryRepositorySource, JBossCacheSource, JcrRepositorySource, JdbcMetadataSource, JpaSource, RemoteInfinispanSource, SearchableRepositorySource, SvnRepositorySource, XmlFileRepositorySource

@ThreadSafe
public interface RepositorySource
extends Referenceable, Serializable

A repository source is a description of a resource that can be used to access or store repository information. This class serves as a factory for RepositoryConnection instances and provides some basic configuration information.

Typically this interface is implemented by classes that provide standard-style getters and setters for the various properties necessary for proper configuration via reflection or introspection. This interface expects nor defines any such properties, leaving that entirely to the implementation classes. Although any types can be used for these setters, other ModeShape components use reflection to set these properties and work best when the setters accept a single parameter that is a primitive, an array of primitives, a value compatible with PropertyType (e.g., Path, Name, URI, UUID, Reference, Binary, Long, Double, BigDecimal, DateTime, etc.), or an array of values that are compatible with PropertyType.

Implementations should also provide a no-arg constructor so that it is possible to easily create instances and initialize using the standard getters and setters. One example where this is required is when a RepositorySource instance is recorded in a repository (e.g., in a configuration area), and needs to be reinstantiated.

Objects that implement this RepositorySource interface are typically registered with a naming service such as Java Naming and Directory InterfaceTM (JNDI). This interface extends both Referenceable and Serializable so that such objects can be stored in any JNDI naming context and enable proper system recovery,

Pooling connections

If the connections created by a RepositorySource are expensive to create, then connection pooling is recommended. ModeShape provides this capability with a powerful and flexible RepositoryConnectionPool class. This is the pooling mechanism used by ModeShape, but you are free to use your own pools.

Cache Policy

Each connector is responsible for determining whether and how long ModeShape is to cache the content made available by the connector. This is referred to as the caching policy, and consists of a time to live value representing the number of milliseconds that a piece of data may be cached. After the TTL has passed, the information is no longer used.

ModeShape allows a connector to use a flexible and powerful caching policy. First, each connection returns the default caching policy for all information returned by that connection. Often this policy can be configured via properties on the RepositorySource implementation. This is optional, meaning the connector can return null if it does not wish to have a default caching policy.

Second, the connector is able to override its default caching policy on individual requests. Again, this is optional, meaning that a null caching policy on a request implies that the request has no overridden caching policy.

Third, if the connector has no default caching policy and none is set on the individual requests, ModeShape uses whatever caching policy is set up for that component using the connector. For example, the federating connector allows a default caching policy to be specified, and this policy is used should the sources being federated not define their own caching policy.

In summary, a connector has total control over whether and for how long the information it provides is cached.

Leveraging JNDI

Sometimes it is necessary (or easier) for a RepositorySource implementation to look up an object in JNDI. One example of this is the JBoss Cache connector: while the connector can instantiate a new JBoss Cache instance, more interesting use cases involve JBoss Cache instances that are set up for clustering and replication, something that is generally difficult to configure in a single JavaBean. Therefore the JBossCacheSource has optional JavaBean properties that define how it is to look up a JBoss Cache instance in JNDI.

This is a simple pattern that you may find useful in your connector. Basically, if your source implementation can look up an object in JNDI, simply use a single JavaBean String property that defines the full name that should be used to locate that object in JNDI. Usually it's best to include "Jndi" in the JavaBean property name so that administrative users understand the purpose of the property. (And some may suggest that any optional property also use the word "optional" in the property name.)

Capabilities

Each RepositorySource implementation provides some hint as to its capabilities by returning a RepositorySourceCapabilities object. This class currently provides methods that say whether the connector supports updates, whether it supports same-name-siblings (SNS), and whether the connector supports listeners and events. These may be hard-coded values, or the capabilities object returned by the connector may determine them at runtime based upon the system its connecting to. For example, a connector may interrogate the underlying system to decide whether it can support updates. The only criteria is that the capabilities must remain constant throughout the lifetime of the RepositorySource instance (assuming it doesn't change).

The RepositorySourceCapabilities can be used as is (the class is immutable), or it can be subclassed to provide more complex behavior. Why is this a concrete class and not an interface? By using a concrete class, connectors inherit the default behavior. If additional capabilities need to be added to the class in future releases, connectors may not have to override the defaults. This provides some insulation against future enhancements to the connector framework.

Security and authentication

The main method connectors have to process requests takes an ExecutionContext, which contains the JAAS security information of the subject performing the request. This means that the connector can use this to determine authentication and authorization information for each request.

Sometimes that is not sufficient. For example, it may be that the connector needs its own authorization information so that it can establish a connection (even if user-level privileges still use the ExecutionContext provided with each request). In this case, the RepositorySource implementation will probably need JavaBean properties that represent the connector's authentication information. This may take the form of a username and password, or it may be properties that are used to delegate authentication to JAAS. Either way, just realize that it's perfectly acceptable for the connector to require its own security properties.


Method Summary
 void close()
          Signal this source that it is no longer needed and should begin the process of reclaiming or closing all resources that it has acquired.
 RepositorySourceCapabilities getCapabilities()
          Get the capabilities for this source.
 RepositoryConnection getConnection()
          Get a connection from this source.
 String getName()
          Get the name for this repository source.
 int getRetryLimit()
          Get the maximum number of retries that may be performed on a given operation when using connections created by this source.
 void initialize(RepositoryContext context)
          Initialize this source to use the supplied RepositoryContext, from which this source can obtain the configuration defining this source, connections to other sources, and the execution context.
 void setRetryLimit(int limit)
          Set the maximum number of retries that may be performed on a given operation when using connections created by this source.
 
Methods inherited from interface javax.naming.Referenceable
getReference
 

Method Detail

initialize

void initialize(RepositoryContext context)
                throws RepositorySourceException
Initialize this source to use the supplied RepositoryContext, from which this source can obtain the configuration defining this source, connections to other sources, and the execution context.

This method may be called each time the configuration changes, allowing the source to update itself.

Parameters:
context -
Throws:
RepositorySourceException

getName

String getName()
Get the name for this repository source.

Returns:
the name; never null or empty

getConnection

RepositoryConnection getConnection()
                                   throws RepositorySourceException
Get a connection from this source. Even though each RepositorySource need not be thread safe, this method should be safe to be called concurrently by multiple threads.

Returns:
a connection
Throws:
RepositorySourceException - if there is a problem obtaining a connection
IllegalStateException - if the factory is not in a state to create or return connections

getRetryLimit

int getRetryLimit()
Get the maximum number of retries that may be performed on a given operation when using connections created by this source. This value does not constitute a minimum number of retries; in fact, the connection user is not required to retry any operations.

Returns:
the maximum number of allowable retries, or 0 if the source has no limit

setRetryLimit

void setRetryLimit(int limit)
Set the maximum number of retries that may be performed on a given operation when using connections created by this source. This value does not constitute a minimum number of retries; in fact, the connection user is not required to retry any operations.

Parameters:
limit - the maximum number of allowable retries, or 0 if the source has no limit

getCapabilities

RepositorySourceCapabilities getCapabilities()
Get the capabilities for this source.

Returns:
the capabilities for this source; never null

close

void close()
Signal this source that it is no longer needed and should begin the process of reclaiming or closing all resources that it has acquired. Because connections may still be in use, this method may not necessarily close all resources immediately.

This is a required method, and must be called when this source is no longer needed if one or more connections have been obtained since the previous call to this method.

Note that calling this method also does not preclude obtaining more connections after this method is called. If that happens, this source should simply reacquire any resources necessary to provide additional connections, and this method needs to be called once again.



Copyright © 2008-2011 JBoss, a division of Red Hat. All Rights Reserved.