|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
RepositoryConnection | A connection to a repository source. |
RepositoryConnectionFactory | An interface for a factory of RepositoryConnection s using the names of the RepositorySource from which the
connections are to be obtained. |
RepositoryContext | The context for a repository. |
RepositorySource | A repository source is a description of a resource that can be used to access or store repository information. |
Class Summary | |
---|---|
RepositoryConnectionPool | A reusable implementation of a managed pool of connections that is optimized for safe concurrent operations. |
RepositorySourceCapabilities | The capabilities of a RepositorySource . |
Exception Summary | |
---|---|
LockFailedException | Exception that indicates that a lock request failed at the repository level. |
RepositorySourceException | A runtime exception signalling an error within a RepositorySource . |
UuidAlreadyExistsException | Exception that indicates that a copy request failed because one of the UUIDs in the source branch already exists in the target
workspace and the UUID conflict behavior is set to throw an exception instead of
removing the existing nodes. |
JBoss DNA uses connectors to access information from external systems (such as databases, other repositories, services, applications, etc.) and create graph representations of that information. This package defines the interfaces that a connector must implement.
A connector is the runnable code packaged in one or more JAR files that contains implementations of several interfaces (described below). A Java developer writes a connector to a type of source, such as a particular database management system, LDAP directory, source code management system, etc. It is then packaged into one or more JAR files (including dependent JARs) and deployed for use in applications that use JBoss DNA repositories.
The description of a particular source system (e.g., the "Customer" database, or the company LDAP system) is
called a repository source. JBoss DNA defines a RepositorySource
interface that defines methods
describing the behavior and supported features and a method for establishing connections. A connector will
have a class that implements this interface and that has JavaBean properties for all of the connector-specific
properties required to fully describe an instance of the system. Use of JavaBean properties is not required,
but it is highly recommended, as it enables reflective configuration and administration. Applications that
use JBoss DNA create an instance of the connector's RepositorySource
implementation and set the properties
for the external source that the application wants to access with that connector.
A repository source instance is then used to establish connections to that source.
A connector provides an implementation of the RepositoryConnection
interface, which defines methods for
interacting with the external system. In particular, the execute(...) method takes an ExecutionContext
instance and a Request
object. The object defines the environment in which
the processing is occurring, including information about the JAAS Subject and LoginContext. The
Request
object describes the requested
operations on the content, with different concrete subclasses representing each type of activity.
Examples of commands include (but not limited to) getting a node, moving a node, creating a node,
changing a node, and deleting a node. And, if the repository source is able to participate in JTA/JTS
distributed transactions, then the RepositoryConnection
must implement the RepositoryConnection#getXAResource()
method by returning a valid XAResource
object that can be used by the transaction monitor.
As an example, consider that we want JBoss DNA to give us access through JCR to the schema information contained
in a relational databases. We first have to develop a connector that allows us to interact with relational
databases using JDBC. That connector would contain a JdbcRepositorySource
Java class that
implements RepositorySource
, and that has all of the various JavaBean properties for setting the
name of the driver class, URL, username, password, and other properties. (Or we might have a JavaBean property
that defines the JNDI name where we can find a JDBC DataSource instance pointing to our JDBC database.)
Our new connector would also have a JdbcRepositoryConnection
Java class that implements the
RepositoryConnection
interface. This class would probably wrap a JDBC database connection
,
and would implement the RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext, org.jboss.dna.graph.request.Request)
method such that the nodes exposed by the connector describe the database schema of the database. For example,
the connector might represent each database table as a node with the table's name, with properties that describe
the table (e.g., the description, whether it's a temporary table), and with child nodes that represent each of
the columns, keys and constraints.
To use our connector in an application that uses JBoss DNA, we need to create an instance of the
JdbcRepositorySource
for each database instance that we want to access. If we have 3 MySQL databases,
9 Oracle databases, and 4 PostgreSQL databases, then we'd need to create a total of 16 JdbcRepositorySource
instances,
each with the properties describing a single database instance. Those sources are then available for use by
JBoss DNA components, including the JCR implementation.
As mentioned earlier, a connector consists of the Java code that is used to access content from a system.
Perhaps the most important class that makes up a connector is the implementation of the RepositorySource
.
This class is analogous to JDBC's DataSource
in that it is instantiated to represent a single
instance of a system that will be accessed, and it contains enough information (in the form of JavaBean properties)
so that it can create connections to the source.
Why is the RepositorySource implementation a JavaBean? Well, this is the class that is instantiated, usually reflectively, and so a no-arg constructor is required. Using JavaBean properties makes it possible to reflect upon the object's class to determine the properties that can be set (using setters) and read (using getters). This means that an administrative application can instantiate, configure, and manage the objects that represent the actual sources, without having to know anything about the actual implementation.
Testing connectors is not really that much different than testing other classes. Using mocks may help to isolate your instances so you can create more unit tests that don't require the underlying source system.
JBoss DNA does provide a set of unit tests
that you can use to
verify that your connector "behaves correctly". These are useful because you only have to set up the test case
classes (by extending one of the provided test case classes and overriding the appropriate set up methods),
but you don't have to write any test methods (since they're all inherited).
However, there may be times when you have to use the underlying source system in your tests. If this is the case, we recommend using Maven integration tests, which run at a different point in the Maven lifecycle. The benefit of using integration tests is that by convention they're able to rely upon external systems. Plus, your unit tests don't become polluted with slow-running tests that break if the external system is not available.
|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |