|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
@ThreadSafe public interface RepositorySource
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,
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.
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.
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.)
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.
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 |
---|
void initialize(RepositoryContext context) throws RepositorySourceException
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.
context
-
RepositorySourceException
String getName()
RepositoryConnection getConnection() throws RepositorySourceException
RepositorySourceException
- if there is a problem obtaining a connection
IllegalStateException
- if the factory is not in a state to create or return connectionsint getRetryLimit()
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.
void setRetryLimit(int limit)
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.
limit
- the maximum number of allowable retries, or 0 if the source has no limitRepositorySourceCapabilities getCapabilities()
void close()
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.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |