001package org.nuxeo.ecm.core.storage.sql.jdbc;
002
003import java.lang.reflect.InvocationHandler;
004import java.lang.reflect.InvocationTargetException;
005import java.lang.reflect.Method;
006import java.lang.reflect.Proxy;
007
008import javax.transaction.xa.XAResource;
009
010import org.nuxeo.ecm.core.storage.sql.Mapper;
011
012public class JDBCMapperConnector implements InvocationHandler {
013
014    protected final Mapper mapper;
015
016    protected JDBCMapperConnector(Mapper mapper) {
017        this.mapper = mapper;
018    }
019
020    protected Object doInvoke(Method method, Object[] args) throws Throwable {
021        try {
022            return method.invoke(mapper, args);
023        } catch (InvocationTargetException cause) {
024            throw cause.getTargetException();
025        }
026    }
027
028    @Override
029    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
030        if (mapper.isConnected()) {
031            return doInvoke(method, args);
032        }
033        // should not operate with tx mamagement (managed connection)
034        String name = method.getName();
035        if ("start".equals(name)) {
036            return XAResource.XA_OK;
037        }
038        if ("end".equals(name)) {
039            return null;
040        }
041        if ("prepare".equals(name)) {
042            return XAResource.XA_OK;
043        }
044        if ("commit".equals(name)) {
045            return null;
046        }
047        if ("rollback".equals(name)) {
048            return null;
049        }
050        if ("clearCache".equals(name)) {
051            return doInvoke(method, args);
052        }
053        mapper.connect();
054        try {
055            return doInvoke(method, args);
056        } finally {
057            if (mapper.isConnected()) {
058                mapper.disconnect();
059            }
060        }
061    }
062
063    public static Mapper newConnector(Mapper mapper) {
064        return (Mapper) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
065                new Class<?>[] { Mapper.class }, new JDBCMapperConnector(mapper));
066    }
067}