1   package com.atlassian.spring;
2   
3   import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
4   
5   import java.sql.*;
6   import java.util.Iterator;
7   import java.util.Map;
8   
9   public class AutomaticJdbcExtractor implements NativeJdbcExtractor
10  {
11      private Map extractors;
12      private NativeJdbcExtractor defaultJdbcExtractor;
13      private NativeJdbcExtractor jdbcExtractor;
14  
15      public boolean isNativeConnectionNecessaryForNativeStatements()
16      {
17          return true;
18      }
19  
20      public boolean isNativeConnectionNecessaryForNativePreparedStatements()
21      {
22          return true;
23      }
24  
25      public boolean isNativeConnectionNecessaryForNativeCallableStatements()
26      {
27          return true;
28      }
29  
30      /**
31       * When this method is called, the connection object passed in is checked to determine
32       * what type of connection pooling is being used (based on class prefix)
33       * <p/>
34       * <p> Once we find out what pooling is used we then set the jdbcExtractor field to the appropriate
35       * extractor and delegate all method calls to this extractor
36       *
37       * @param con
38       * @return
39       * @throws SQLException
40       */
41      public Connection getNativeConnection(Connection con) throws SQLException
42      {
43          return getJdbcExtractor(con).getNativeConnection(con);
44      }
45  
46      private synchronized NativeJdbcExtractor getJdbcExtractor(Object o)
47      {
48          if (jdbcExtractor == null)
49          {
50              String objClass = o.getClass().getName();
51  
52              for (Iterator iterator = extractors.keySet().iterator(); iterator.hasNext();)
53              {
54                  String classPrefix = (String) iterator.next();
55                  if (objClass.indexOf(classPrefix) != -1)
56                  {
57                      // set the extractor to delegate to
58                      jdbcExtractor = (NativeJdbcExtractor) extractors.get(classPrefix);
59                  }
60              }
61  
62              if (jdbcExtractor == null)
63                  jdbcExtractor = defaultJdbcExtractor;
64          }
65          
66          return jdbcExtractor;
67      }
68  
69      public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException
70      {
71          return getJdbcExtractor(stmt).getNativeConnectionFromStatement(stmt);
72      }
73  
74      public Statement getNativeStatement(Statement stmt) throws SQLException
75      {
76          return getJdbcExtractor(stmt).getNativeStatement(stmt);
77      }
78  
79      public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException
80      {
81          return getJdbcExtractor(ps).getNativePreparedStatement(ps);
82      }
83  
84      public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException
85      {
86          return getJdbcExtractor(cs).getNativeCallableStatement(cs);
87      }
88  
89      public ResultSet getNativeResultSet(ResultSet rs) throws SQLException
90      {
91          return getJdbcExtractor(rs).getNativeResultSet(rs);
92      }
93  
94      public Map getExtractors()
95      {
96          return extractors;
97      }
98  
99      public void setExtractors(Map extractors)
100     {
101         this.extractors = extractors;
102     }
103 
104     public NativeJdbcExtractor getDefaultJdbcExtractor()
105     {
106         return defaultJdbcExtractor;
107     }
108 
109     public void setDefaultJdbcExtractor(NativeJdbcExtractor defaultJdbcExtractor)
110     {
111         this.defaultJdbcExtractor = defaultJdbcExtractor;
112     }
113 
114 }