001/* 002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Stephane Lacoin 018 */ 019package org.nuxeo.ecm.core.storage.sql.jdbc; 020 021import java.lang.reflect.InvocationHandler; 022import java.lang.reflect.InvocationTargetException; 023import java.lang.reflect.Method; 024import java.lang.reflect.Proxy; 025import java.util.Arrays; 026 027import javax.transaction.SystemException; 028import javax.transaction.xa.XAResource; 029 030import org.nuxeo.ecm.core.storage.sql.Mapper; 031 032public class JDBCMapperConnector implements InvocationHandler { 033 034 protected final Mapper mapper; 035 036 protected JDBCMapperConnector(Mapper mapper) { 037 this.mapper = mapper; 038 } 039 040 protected Object doInvoke(Method method, Object[] args) throws Throwable { 041 try { 042 return method.invoke(mapper, args); 043 } catch (InvocationTargetException cause) { 044 throw cause.getTargetException(); 045 } 046 } 047 048 @Override 049 public Object invoke(Object proxy, Method method, Object[] args) 050 throws Throwable { 051 String name = method.getName(); 052 if (mapper.isConnected()) { 053 if (Arrays.asList("start", "end", "prepare", "commit", "rollback").contains(name)) { 054 throw new SystemException("wrong tx management invoke on managed connection"); 055 } 056 return doInvoke(method, args); 057 } 058 // should not operate with tx mamagement (managed connection) 059 if ("start".equals(name)) { 060 return XAResource.XA_OK; 061 } 062 if ("end".equals(name)) { 063 return null; 064 } 065 if ("prepare".equals(name)) { 066 return XAResource.XA_OK; 067 } 068 if ("commit".equals(name)) { 069 return null; 070 } 071 if ("rollback".equals(name)) { 072 return null; 073 } 074 if ("clearCache".equals(name)) { 075 return doInvoke(method, args); 076 } 077 if ("receiveInvalidations".equals(name)) { 078 return doInvoke(method, args); 079 } 080 if ("sendInvalidations".equals(name)) { 081 return doInvoke(method, args); 082 } 083 mapper.connect(); 084 try { 085 return doInvoke(method, args); 086 } finally { 087 if (mapper.isConnected()) { 088 mapper.disconnect(); 089 } 090 } 091 } 092 093 public static Mapper newConnector(Mapper mapper) { 094 return (Mapper) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 095 new Class<?>[] { Mapper.class }, new JDBCMapperConnector(mapper)); 096 } 097 098 public static Mapper unwrap(Mapper mapper) { 099 if (!Proxy.isProxyClass(mapper.getClass())) { 100 return mapper; 101 } 102 return ((JDBCMapperConnector)Proxy.getInvocationHandler(mapper)).mapper; 103 } 104}