59d610cfae6ba8d17bc6ebb1c2038db58d3484fe
[dmaap/dbcapi.git] / src / main / java / org / onap / dmaap / dbcapi / database / DBFieldHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.onap.dmaap
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.dmaap.dbcapi.database;
22
23 import java.lang.reflect.*;
24 import java.sql.*;
25 import java.util.*;
26
27
28 import com.att.eelf.configuration.EELFLogger;
29 import com.att.eelf.configuration.EELFManager;
30
31 import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
32
33
34 public class DBFieldHandler     {
35         static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();       
36
37         public DBFieldHandler(Class<?> c, String fieldname, int fieldnum) throws Exception {
38                 this(c, fieldname, fieldnum, null);
39         }
40         public DBFieldHandler(Class<?> c, String fieldname, int fieldnum, SqlOp op) throws Exception {
41                 this.fieldnum = fieldnum;
42                 StringBuilder sb = new StringBuilder();
43                 for (String s: fieldname.split("_")) {  
44                         sb.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
45                 }
46                 String camelcase = sb.toString();
47                 try {
48                         objget = c.getMethod("is" + camelcase);
49                 } catch (Exception e) {
50                         errorLogger.error("Error", e);
51                         objget = c.getMethod("get" + camelcase);
52                 }
53                 objset = c.getMethod("set" + camelcase, objget.getReturnType());
54                 sqlop = op;
55                 if (sqlop != null) {
56                         return;
57                 }
58                 Class<?> x = objget.getReturnType();
59                 if (x.isEnum()) {
60                         sqlop = new EnumSql(x);
61                         return;
62                 }
63                 sqlop = sqltypes.get(x.getName());
64                 if (sqlop != null) {
65                         return;
66                 }
67                 errorLogger.error(DmaapbcLogMessageEnum.DB_NO_FIELD_HANDLER,  c.getName(),  fieldname,  Integer.toString(fieldnum),  x.getName());
68         }
69         
70         public static interface SqlOp   {
71                 public Object get(ResultSet rs, int index) throws Exception;
72                 public void set(PreparedStatement ps, int index, Object value) throws Exception;
73         }
74         private static class    AofString implements SqlOp {
75                 public Object get(ResultSet rs, int index) throws Exception {
76                         String val = rs.getString(index);
77                         if (val == null) {
78                                 return(null);
79                         }
80                         String[] ret = val.split(",");
81                         for (int i = 0; i < ret.length; i++) {
82                                 ret[i] = funesc(ret[i]);
83                         }
84                         return(ret);
85                 }
86                 public void set(PreparedStatement ps, int index, Object x) throws Exception {
87                         String[] val = (String[])x;
88                         if (val == null) {
89                                 ps.setString(index, null);
90                                 return;
91                         }
92                         StringBuffer sb = new StringBuffer();
93                         String sep = "";
94                         for (String s: val) {
95                                 sb.append(sep).append(fesc(s));
96                                 sep = ",";
97                         }
98                         ps.setString(index, sb.toString());
99                 }
100         }
101         private static class    EnumSql implements SqlOp {
102                 private Class   enclass;
103                 public EnumSql(Class enclass) {
104                         this.enclass = enclass;
105                 }
106                 @SuppressWarnings("unchecked")
107                 public Object get(ResultSet rs, int index) throws Exception {
108                         String val = rs.getString(index);
109                         if (val == null) {
110                                 return(null);
111                         } else {
112                                 return(Enum.valueOf(enclass, val));
113                         }
114                 }
115                 public void set(PreparedStatement ps, int index, Object value) throws Exception {
116                         if (value == null) {
117                                 ps.setString(index, null);
118                         } else {
119                                 ps.setString(index, value.toString());
120                         }
121                 }
122         }
123         private static class    SqlDate implements SqlOp {
124                 public Object get(ResultSet rs, int index) throws Exception {
125                         return(rs.getTimestamp(index));
126                 }
127                 public void set(PreparedStatement ps, int index, Object val) throws Exception {
128                         if (val instanceof java.util.Date && !(val instanceof java.sql.Timestamp)) {
129                                 val = new java.sql.Timestamp(((java.util.Date)val).getTime());
130                         }
131                         ps.setTimestamp(index, (java.sql.Timestamp)val);
132                 }
133         }
134         private static class    SqlType implements SqlOp {
135                 private Method   sqlget;
136                 private Method   sqlset;
137                 private SqlType(String tag) throws Exception {
138                         sqlget = ResultSet.class.getMethod("get" + tag, Integer.TYPE);
139                         sqlset = PreparedStatement.class.getMethod("set" + tag, Integer.TYPE, sqlget.getReturnType());
140                         sqltypes.put(sqlget.getReturnType().getName(), this);
141                 }
142                 public Object get(ResultSet rs, int index) throws Exception {
143                         return(sqlget.invoke(rs, index));
144                 }
145                 public void set(PreparedStatement ps, int index, Object val) throws Exception {
146                         try {
147                                 sqlset.invoke(ps, index, val);
148                         } catch (Exception e) {
149                                 errorLogger.error(DmaapbcLogMessageEnum.DB_FIELD_INIT_ERROR,  Integer.toString(index), val.toString(), ps.toString());
150                                 throw e;
151                         }
152                 }
153         }
154         private static Map<String, SqlOp> sqltypes;
155         static {
156                 sqltypes = new HashMap<>();
157                 sqltypes.put("[Ljava.lang.String;", new AofString());
158                 sqltypes.put("java.util.Date", new SqlDate());
159                 try {
160                         new SqlType("Boolean");
161                         new SqlType("Timestamp");
162                         new SqlType("Double");
163                         new SqlType("Float");
164                         new SqlType("Int");
165                         new SqlType("Long");
166                         new SqlType("Short");
167                         new SqlType("String");
168                 } catch (Exception e) {
169                         errorLogger.error("Error", e);
170                         errorLogger.error(DmaapbcLogMessageEnum.DB_ACCESS_INIT_ERROR,  e.getMessage() );
171                 }
172         }
173         private Method  objget;
174         private Method  objset;
175         private SqlOp   sqlop;
176         private int     fieldnum;
177         public void copy(Object from, Object to) throws Exception {
178                 objset.invoke(to, objget.invoke(from));
179         }
180         public void setKey(Object o, String key) throws Exception {
181                 objset.invoke(o, key);
182         }
183         public String getKey(Object o) throws Exception {
184                 return((String)objget.invoke(o));
185         }
186         public void toSQL(Object o, PreparedStatement ps) throws Exception {
187                 sqlop.set(ps, fieldnum, objget.invoke(o));
188         }
189         public void fromSQL(ResultSet r, Object o) throws Exception {
190                 objset.invoke(o, sqlop.get(r, fieldnum));
191         }
192         public static String fesc(String s) {
193                 if (s == null) {
194                         return(s);
195                 }
196                 return(s.replaceAll("@", "@a").replaceAll(";", "@s").replaceAll(",", "@c"));
197         }
198         public static String funesc(String s) {
199                 if (s == null) {
200                         return(s);
201                 }
202                 return(s.replaceAll("@c", ",").replaceAll("@s", ";").replaceAll("@a", "@"));
203         }
204 }