|PREV PACKAGE NEXT PACKAGE||FRAMES NO FRAMES|
|RepositoryConnection||A connection to a repository source.|
|RepositoryConnectionFactory||An interface for a factory of
|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.|
|RepositoryConnectionPool||A reusable implementation of a managed pool of connections that is optimized for safe concurrent operations.|
|RepositorySourceCapabilities||The capabilities of a
|RepositorySourceException||A runtime exception signalling an error within a
|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
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
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
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
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
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
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
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|