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