View Javadoc

1   /*******************************************************************************
2    *  Copyright (c) 2005, 2006 Imola Informatica.
3    *  All rights reserved. This program and the accompanying materials
4    *  are made available under the terms of the LGPL License v2.1
5    *  which accompanies this distribution, and is available at
6    *  http://www.gnu.org/licenses/lgpl.html
7    ******************************************************************************/
8   
9   package it.imolinfo.jbi4cics.connection.jdbc.util;
10  
11  import it.imolinfo.jbi4cics.jbi.Messages;
12  import java.lang.reflect.Method;
13  import java.sql.CallableStatement;
14  import java.sql.SQLException;
15  import java.sql.Statement;
16  import java.util.Arrays;
17  import java.util.HashMap;
18  import java.util.Iterator;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Vector;
22  import it.imolinfo.jbi4cics.Logger;
23  import it.imolinfo.jbi4cics.LoggerFactory;
24  
25  
26  /**
27   * @author raffaele
28   *
29   */
30  public class CallableStatementInvocationHandler extends PreparedStatementInvocationHandler {
31      
32    /**
33     * The logger for this class and its instances.
34     */
35    private static final Logger LOG
36            = LoggerFactory.getLogger(CallableStatementInvocationHandler.class);
37    
38    /**
39     * The responsible to translate localized messages.
40     */
41    private static final Messages MESSAGES
42            = Messages.getMessages(CallableStatementInvocationHandler.class);
43  
44    private List<Object> paramterNameList=new Vector<Object>();
45    private List<Object> parameterIndexList=new Vector<Object>();
46    private Map<String, Object> nameValueParamterMap=new HashMap<String, Object>();
47    private Map<Integer, Object> indexValueParamterMap=new HashMap<Integer, Object>();
48  
49    /**
50     * @param sql    The SQL
51     */
52    public CallableStatementInvocationHandler(String sql) {
53      super(sql);
54      // TODO Auto-generated constructor stub
55    }
56  
57    /**
58     * @param sql    The SQL
59     * @param resultSetType    The result set type
60     * @param resultSetConcurrency    The result set Councurrency
61     */
62    public CallableStatementInvocationHandler(String sql, int resultSetType, int resultSetConcurrency) {
63      super(sql, resultSetType, resultSetConcurrency);
64      // TODO Auto-generated constructor stub
65    }
66  
67    /**
68     * @param sql    The SQL
69     * @param resultSetType    The result set type
70     * @param resultSetConcurrency    The result set Councurrency
71     * @param resultSetHoldability    The result set Holdability
72     */
73    public CallableStatementInvocationHandler(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
74      super(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
75      // TODO Auto-generated constructor stub
76    }
77    
78    /**
79     * @return    The create statement
80     * @throws SQLException    The SQL exception
81     */
82    protected Statement createStatement() throws SQLException {
83      return getConnection().prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
84    }
85    
86    
87    /**
88     * La gestione e' simile a quella degli altri statement, ma in questo caso bisogna aggiungere 
89     * la gestione dei parametri della stored procedur. In particolare e' importante gestire gli outparameter.
90     * 
91     * @param proxy    The proxy    
92     * @param method    The method   
93     * @param args    The args  
94     * @return object    The invoked object 
95     * @throws Throwable    The Throwable    
96     */
97    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
98      if (method.getName().startsWith("execute")){
99        Object object=super.invoke(proxy,method,args);
100       handlePostExecute();
101       return object;
102     }
103     // per prima cosa cerchiamo di capire se il metodo è chiamato sull'interfaccia CallableStatement
104     Class clazz=method.getDeclaringClass();
105     if (!(clazz.equals(CallableStatement.class))){
106       // se il metodo non appartiene a CallableStatement lo può gestire la classe madre
107       return super.invoke(proxy,method,args);
108     }
109     if (method.getName().startsWith("set")){
110       // anche in questo caso lo può gestire la classe madre
111       return super.invoke(proxy,method,args);
112     }
113     
114 
115     /* a questo punto rimangono due tipi di metodi:
116      * i register
117      * e i get
118      * 
119      * poi c'e' was null che fa eccezione
120      */
121     
122     if (method.getName().startsWith("register")){
123       return handleRegister(proxy, method, args);
124     }
125     
126     if (method.getName().startsWith("get")){
127       return handleGetParameter(method, args);
128     }
129     
130     return null;
131   }
132 
133   /**
134    * @param proxy    The proxy
135    * @param method    The method
136    * @param args    The args
137    * @throws Throwable    The throwable
138    * @throws SQLException    The SQL Exception
139    * @return    The return object
140    */
141   private Object handleRegister(Object proxy, Method method, Object[] args) throws Throwable, SQLException {
142     // se il primo argomento e' di tipo stringa
143     LOG.debug("method.getParameterTypes(): "+Arrays.toString(method.getParameterTypes()));
144     if (method.getParameterTypes()[0].equals(String.class)){
145       //memorizzo che esiste un parametro con questo nome
146       paramterNameList.add(args[0]);
147       // faccio gestire il parametro dalla classe madre
148       return super.invoke(proxy,method,args);
149     }
150     if (method.getParameterTypes()[0].equals(int.class)){
151       //memorizzo che esiste un parametro con questo nome
152       parameterIndexList.add(args[0]);
153       // faccio gestire il parametro dalla classe madre
154       return super.invoke(proxy,method,args);  
155     }
156     throw new SQLException(MESSAGES.getString("CIC000700_Error_registering_parameter", new Object[] {Arrays.toString(args)}));
157   }
158   
159   private Object handleGetParameter(Method method, Object[] args) throws SQLException {
160     if (isConnected()) {
161       return invokeMethod(method,args);
162     }
163     else {
164       if (args.length>1) {
165         throw new SQLException (MESSAGES.getString("CIC000701_Getting_multiple_parameters_unsupported"));
166       }
167       if (method.getParameterTypes()[0].equals(String.class)){
168         return nameValueParamterMap.get(args[0]);
169       }
170       if (method.getParameterTypes()[0].equals(int.class)){
171         return indexValueParamterMap.get(args[0]);
172       }
173       throw new SQLException(MESSAGES.getString("CIC000702_Unknown_arguments", new Object[] {Arrays.toString(args)}));
174     }
175   }
176   
177   private void handlePostExecute() throws SQLException {
178     // dopo l'esecuzione devo leggere e cacheare tutti gli out parameter che sono stati registrati
179     for (Iterator<Object> i=paramterNameList.iterator();i.hasNext();){
180       String parameterName=(String)i.next();
181       Object value=((CallableStatement)getUnderlyingStatement()).getObject(parameterName);
182       nameValueParamterMap.put(parameterName,value);
183     }
184     for (Iterator<Object> i=parameterIndexList.iterator();i.hasNext();){
185       int index=((Integer)i.next()).intValue();
186       Object value=((CallableStatement)getUnderlyingStatement()).getObject(index);
187       indexValueParamterMap.put(new Integer(index),value);
188     }
189     LOG.debug("name : value keys: "+Arrays.toString(nameValueParamterMap.keySet().toArray()));
190     LOG.debug("name : value values: "+Arrays.toString(nameValueParamterMap.values().toArray()));
191     LOG.debug("index : value keys: "+Arrays.toString(indexValueParamterMap.keySet().toArray()));
192     LOG.debug("index : value values: "+Arrays.toString(indexValueParamterMap.values().toArray()));
193   }
194 }
195 
196