|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
@NotThreadSafe public interface RepositoryConnection
A connection to a repository source.
These connections need not support concurrent operations by multiple threads.
While most of these methods are straightforward, a few warrant additional information. The ping(long, TimeUnit)
method
allows ModeShape to check the connection to see if it is alive. This method can be used in a variety of situations, ranging from
verifying that a RepositorySource
's JavaBean properties are correct to ensuring that a connection is still alive before
returning the connection from a connection pool.
The most important method on this interface, though, is the execute(ExecutionContext, Request)
method, which serves as
the mechanism by which the component using the connector access and manipulates the content exposed by the connector. The first
parameter to this method is the ExecutionContext
, which contains the information about environment as well as the
subject performing the request.
The second parameter, however, represents a request that is to be processed by the connector. Request
objects can take
many different forms, as there are different classes for each kind of request (see the {org.modeshape.graph.request} package
for more detail). Each request contains the information a connector needs to do the processing, and it also is the place where
the connector places the results (or the error, if one occurs).
Although there are over a dozen different kinds of requests, we do anticipate adding more in future releases. For example, ModeShape
will likely support searching repository content in sources through an additional subclass of Request
. Getting the
version history for a node will likely be another kind of request added in an upcoming release.
A connector is technically free to implement the execute(ExecutionContext, Request)
method in any way, as long as the
semantics are maintained. But ModeShape provides a RequestProcessor
class that can simplify writing your own connector and at
the same time help insulate your connector from new kinds of requests that may be added in the future. The
RequestProcessor
is an abstract class that defines a process(...)
method for each concrete Request
subclass. In other words, there is a RequestProcessor.process(org.modeshape.graph.request.CompositeRequest)
method, a
RequestProcessor.process(org.modeshape.graph.request.ReadNodeRequest)
method, and so on.
To use a request processor in your connector, simply subclass RequestProcessor
and override all of the abstract methods
and optionally override any of the other methods that have a default implementation. In many cases, the default implementations
of the process(...)
methods are sufficient but probably not efficient or optimum. If that is the
case, simply provide your own methods that perform the request in a manner that is efficient for your source. However, if
performance is not a big issue, all of the concrete methods will provide the correct behavior. And remember, you can always
provide better implementations later, so it's often best to keep things simple at first.
Then, in your connector's execute(ExecutionContext, Request)
method, instantiate your RequestProcessor
subclass and pass the execute(...)
method's Request parameter directly into the the
request processor's RequestProcessor.process(Request)
method, which will determine the appropriate method given the
actual Request object and will then invoke that method. For example:
public void execute( ExecutionContext context, Request request ) throws RepositorySourceException { RequestProcessor processor = new RequestProcessor(context); try { proc.process(request); } finally { proc.close(); } }If you do this, the bulk of your connector implementation will be in the RequestProcessor implementation methods. This not only is more maintainable, it also lends itself to easier testing. And should any new request types be added in the future, your connector may work just fine without any changes. In fact, if the
RequestProcessor
class can implement meaningful
methods for those new request types, your connector may "just work". Or, at least your connector will still be binary
compatible, even if your connector won't support any of the new features.
Finally, how should the connector handle exceptions? As mentioned above, each Request
object has a
slot
where the connector can set any exception encountered during processing. This not only
handles the exception, but in the case of a CompositeRequest
it also correctly associates the problem with the request.
However, it is perfectly acceptable to throw an exception if the connection becomes invalid (e.g., there is a communication
failure) or if a fatal error would prevent subsequent requests from being processed.
Method Summary | |
---|---|
void |
close()
Close this connection to signal that it is no longer needed and that any accumulated resources are to be released. |
void |
execute(ExecutionContext context,
Request request)
Execute the supplied commands against this repository source. |
CachePolicy |
getDefaultCachePolicy()
Get the default cache policy for this repository. |
String |
getSourceName()
Get the name for this repository source. |
XAResource |
getXAResource()
Return the transactional resource associated with this connection. |
boolean |
ping(long time,
TimeUnit unit)
Ping the underlying system to determine if the connection is still valid and alive. |
Method Detail |
---|
String getSourceName()
returned
by the same RepositorySource
that created this connection.
XAResource getXAResource()
boolean ping(long time, TimeUnit unit) throws InterruptedException
time
- the length of time to wait before timing outunit
- the time unit to use; may not be null
InterruptedException
- if the thread has been interrupted during the operationCachePolicy getDefaultCachePolicy()
void execute(ExecutionContext context, Request request) throws RepositorySourceException
context
- the environment in which the commands are being executed; never nullrequest
- the request to be executed; never null
PathNotFoundException
- if the request(s) contain paths to nodes that do not exist
ReferentialIntegrityException
- if the request is or contains a delete operation, where the delete could not be
performed because some references to deleted nodes would have remained after the delete operation completed
RepositorySourceException
- if there is a problem loading the node datavoid close()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |