Title:
Notice:    Licensed to the Apache Software Foundation (ASF) under one
           or more contributor license agreements.  See the NOTICE file
           distributed with this work for additional information
           regarding copyright ownership.  The ASF licenses this file
           to you under the Apache License, Version 2.0 (the
           "License"); you may not use this file except in compliance
           with the License.  You may obtain a copy of the License at
           .
             http://www.apache.org/licenses/LICENSE-2.0
           .
           Unless required by applicable law or agreed to in writing,
           software distributed under the License is distributed on an
           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
           KIND, either express or implied.  See the License for the
           specific language governing permissions and limitations
           under the License.

#Making your own Resource Provider

The <code>TransactionControl</code> service is based around the use of <code>ResourceProvider</code>
instances. When combined the client receives a thread-safe resource instance that they can use.

Resource Provider implementations already exist for [JDBC][1], [XA JDBC][2], [JPA][3] and [XA JPA][4]

##Create an interface 

If you need to create your own Resource Provider then you should define a sub-interface which declares the
type of the resource. This allows clients type-safe access to the resources, and makes it easier to identify
the right Resource Provider at runtime.

    public interface MyCustomResourceProvider extends 
                        ResourceProvider<MyCustomResource> {}

## Create an implementation

The implementation of a ResourceProvider should return a thread-safe delegating proxy. This may be a
dynamic proxy or a static one. The proxy delegates to the real resource, and is responsible for ensuring
that the thread consistently accesses the same physical resource throughout the scope. Note that even 
when multiple proxies are created they should share the same physical resource throughout the life of the
context.

### Lifecycle - first access

Whenever the resource is accessed then it must check to see whether it has already been accessed 
within the current scope. If not then a resource should be selected and associated with the scope. This
physical resource must then be used for the rest of the scope.

Note that if there is no active scope when the resource is accessed then the resource access should 
fail with a TransactionException.

    /**
     *  A resource method
     */
    @Override
    public boolean doSomething() {
        if(!txControl.activeScope()) {
            throw new TransactionException("There is no scope currently active");
        }

        // Locate, or create and associate
        MyCustomResource delegate = locateDelegate(txControl.getCurrentContext());
        
        return delegate.doSomething();
    }

### Lifecycle - enlisting

If a transaction is active then the resource should enlist with it when it is first used. If the resource is
usable with XA transactions then it should register an XAResource.

    private MyCustomResource locateDelegate(TransactionContext context) {
        MyCustomResource resource = findExisting(context);

        if(resource != null) {
            resource = getNewDelegate(context);
            
            if(context.activeTransaction()) {
                if(context.supportsXA()) {
                    context.registerXAResource(resource.getXAResource());
                } else {
                    throw new TransactionException("The transaction does not support XA resources");
                }
            }
            // Other resource preparation
            ...
        }

        return resource;
    }

Local resources are similar, but they register a LocalResource, not an XAResource.

    private MyCustomResource locateDelegate(TransactionContext context) {
        MyCustomResource resource = findExisting(context);

        if(resource != null) {
            resource = getNewDelegate(context);
            
            if(context.activeTransaction()) {
                if(context.supportsLocal()) {
                    context.registerLocalResource(resource.getLocalesource());
                } else {
                    throw new TransactionException("The transaction does not support Local resources");
                }
            }
            // Other resource preparation
            ...
        }

        return resource;
    }

### Lifecycle - Tidying up

In addition to registering with an active transaction the resource should also register for cleanup at the end
of the scope. This may involve closing the physical resource, or returning it to a pool.

    // Other resource preparation
    
    context.postCompletion(s -> resource.release());

##Other things to look out for...

1. A client must have a friendly way to access the ResourceProvider. This may be directly via the OSGi Service 
Registry or via a factory service of some kind.

1. A resource must remain valid throughout a scope, therefore clients should not be able to close or return the
resource by making calls on the thread-safe proxy. Typically calls to close should be a silent no-op (the
actual close will occur when the scope ends).

1. When a transaction is active clients must not be able to manually commit or rollback the resource.
Methods like <code>commit</code>, <code>rollback</code> and <code>setRollbackOnly</code> must
fail with a TransactionException indicating the incorrect usage. This is different from <code>close</code>
behaviour because unlike deferring a <code>close</code> ignoring a <code>rollback</code> results in a 
different overall result from the client's perspective.

1. Resources must not rely on the Transaction Control service recognising duplicate enlistments. A resource
should be enlisted at most once.


  [1]: localJDBC.html
  [2]: xaJDBC.html
  [3]: localJPA.html
  [4]: xaJPA.html