add transaction management to marker mapper
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / common / mapping / DbSingleAttributeImportMapperBase.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.io.common.mapping;
12
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
15 import java.sql.ResultSet;
16 import java.sql.SQLException;
17
18 import javax.mail.MethodNotSupportedException;
19
20 import org.apache.log4j.Logger;
21
22 import eu.etaxonomy.cdm.io.common.DbImportStateBase;
23 import eu.etaxonomy.cdm.io.common.ImportHelper;
24 import eu.etaxonomy.cdm.io.common.Source;
25 import eu.etaxonomy.cdm.model.common.CdmBase;
26
27 /**
28 * @author a.mueller
29 * @created 12.05.2009
30 * @version 1.0
31 */
32 public abstract class DbSingleAttributeImportMapperBase<STATE extends DbImportStateBase<?,?>, CDM_BASE extends CdmBase> extends CdmSingleAttributeMapperBase implements IDbImportMapper<STATE, CDM_BASE> {
33 private static final Logger logger = Logger.getLogger(DbSingleAttributeImportMapperBase.class);
34
35 protected DbImportMapperBase<STATE> importMapperHelper = new DbImportMapperBase<STATE>();
36 // private Integer precision = null;
37 protected boolean obligatory = true;
38 protected boolean ignore = false;;
39
40 protected Method destinationMethod = null;
41 protected Class<?> targetClass;
42
43 /**
44 * @param dbAttributString
45 * @param cdmAttributeString
46 */
47 protected DbSingleAttributeImportMapperBase(String dbAttributString, String cdmAttributeString) {
48 super(dbAttributString, cdmAttributeString);
49 }
50
51
52 /**
53 * @param dbAttributString
54 * @param cdmAttributeString
55 */
56 protected DbSingleAttributeImportMapperBase(String dbAttributString, String cdmAttributeString, Object defaultValue) {
57 super(dbAttributString, cdmAttributeString, defaultValue);
58 }
59
60 /**
61 * @param dbAttributString
62 * @param cdmAttributeString
63 */
64 protected DbSingleAttributeImportMapperBase(String dbAttributeString, String cdmAttributeString, Object defaultValue, boolean obligatory) {
65 super(dbAttributeString, cdmAttributeString, defaultValue);
66 this.obligatory = obligatory;
67 }
68
69 /* (non-Javadoc)
70 * @see eu.etaxonomy.cdm.io.common.mapping.IDbImportMapper#initialize(eu.etaxonomy.cdm.io.common.DbImportStateBase, java.lang.String)
71 */
72 public void initialize(STATE state, Class<? extends CdmBase> destinationClass) {
73 importMapperHelper.initialize(state, destinationClass);
74 try {
75 targetClass = getTargetClass(destinationClass);
76 Class<?> parameterType = getTypeClass();
77 String methodName = getMethodName(parameterType);
78 destinationMethod = targetClass.getMethod(methodName, parameterType);
79 } catch (SecurityException e) {
80 throw new RuntimeException(e);
81 } catch (NoSuchMethodException e) {
82 throw new RuntimeException(e);
83 }
84 }
85
86
87 /**
88 * @param destinationClass
89 * @return
90 * @throws NoSuchMethodException
91 * @throws SecurityException
92 * @throws NoSuchMethodException
93 */
94 protected Class getTargetClass(Class<?> destinationClass) throws SecurityException, NoSuchMethodException{
95 Class result = destinationClass;
96 String destinationAttribute = getDestinationAttribute();
97 if (destinationAttribute == null){
98 return null;
99 }
100 String[] splits = destinationAttribute.split("\\.");
101 //for all prefixes
102 for (int i = 0; i < splits.length - 1; i++){
103 String split = splits[i];
104 String castedResultClass = getCastedResultClass(split);
105 split = removeCast(split);
106 String methodName = ImportHelper.getGetterMethodName(split, false);
107 Method getterMethod;
108 try {
109 getterMethod = result.getMethod(methodName, null);
110 } catch (NoSuchMethodException e1) {
111 throw e1;
112 }
113 result = getterMethod.getReturnType();
114 if (castedResultClass != null){
115 try {
116 //casting works only if the subclass is in the same package
117 String packageName = result.getPackage().getName();
118 castedResultClass = packageName + "." + castedResultClass;
119 result = Class.forName(castedResultClass);
120 } catch (ClassNotFoundException e) {
121 e.printStackTrace();
122 //result = null;
123 }
124 }
125 }
126 return result;
127 }
128
129
130 /**
131 * @param split
132 * @return
133 */
134 private String removeCast(String split) {
135 int index = split.lastIndexOf(")");
136 if (split.length() > index){
137 split = split.substring(index + 1);
138 }else{
139 split = "";
140 }
141 return split;
142 }
143
144
145 /**
146 * @param split
147 * @return
148 */
149 private String getCastedResultClass(String split) {
150 String castString = null;
151 split = split.trim();
152 int index = split.lastIndexOf(")");
153 if (split.startsWith("(") && index > -1 ){
154 castString = split.substring(1, index);
155 castString = castString.trim();
156 }
157 return castString;
158 }
159
160
161 /**
162 * @param clazz
163 * @return
164 */
165 private String getMethodName(Class clazz) {
166 String cdmAttributeName = getTargetClassAttribute(getDestinationAttribute());
167 String result = ImportHelper.getSetterMethodName(clazz, cdmAttributeName);
168 return result;
169 }
170
171
172 /**
173 * @param destinationAttribute
174 * @return
175 */
176 private String getTargetClassAttribute(String destinationAttribute) {
177 if (destinationAttribute == null){
178 return null;
179 }
180 String[] splitted = destinationAttribute.split("\\.");
181 String result = splitted[splitted.length - 1]; //get last attribute
182 return result;
183 }
184
185
186 /* (non-Javadoc)
187 * @see eu.etaxonomy.cdm.io.berlinModel.out.mapper.IDbExportMapper#invoke(eu.etaxonomy.cdm.model.common.CdmBase)
188 */
189 public CDM_BASE invoke(ResultSet rs, CDM_BASE cdmBase) throws SQLException {
190 if (ignore){
191 return cdmBase;
192 }
193 Object dbValue = getValue(rs);
194
195 // String dbValue = rs.getString(getSourceAttribute());
196 return doInvoke(cdmBase, dbValue);
197 }
198
199 protected CDM_BASE doInvoke(CDM_BASE cdmBase, Object value) throws SQLException {
200 Method method = getMethod();
201 try {
202 Object objectToInvoke = getObjectToInvoke(cdmBase);
203 if (objectToInvoke == null){
204 logger.warn("No object defined for invoke. Method will not be invoked");
205 }else{
206 method.invoke(objectToInvoke, value);
207 }
208 return cdmBase;
209 } catch (IllegalArgumentException e) {
210 e.printStackTrace();
211 } catch (IllegalAccessException e) {
212 e.printStackTrace();
213 } catch (InvocationTargetException e) {
214 e.printStackTrace();
215 } catch (SecurityException e) {
216 e.printStackTrace();
217 } catch (NoSuchMethodException e) {
218 e.printStackTrace();
219 }
220 throw new RuntimeException("Problems when invoking target method");
221 }
222
223 /**
224 * @param cdmBase
225 * @return
226 * @throws NoSuchMethodException
227 * @throws SecurityException
228 * @throws InvocationTargetException
229 * @throws IllegalAccessException
230 * @throws IllegalArgumentException
231 */
232 private Object getObjectToInvoke(CDM_BASE cdmBase) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
233 Object objectToInvoke = cdmBase;
234 String destinationAttribute = getDestinationAttribute();
235 String[] splits = destinationAttribute.split("\\.");
236 for (int i = 0; i < splits.length - 1; i++){
237 String split = splits[i];
238 split = removeCast(split);
239 String methodName = ImportHelper.getGetterMethodName(split, false);
240 Method method = objectToInvoke.getClass().getMethod(methodName, null);
241 objectToInvoke = method.invoke(cdmBase, null);
242 }
243 return objectToInvoke;
244 }
245
246
247 /**
248 * @return
249 */
250 private Method getMethod() {
251 if (destinationMethod != null){
252 return destinationMethod;
253 }else{
254 throw new RuntimeException("Missing destinationMethod not yet implemented");
255 }
256 }
257
258
259 protected Object getValue(ResultSet rs) throws SQLException{
260 return getDbValue(rs);
261 }
262
263 /**
264 * Returns the database value for the attribute
265 * @param rs
266 * @return
267 * @throws SQLException
268 */
269 protected Object getDbValue(ResultSet rs) throws SQLException{
270 String columnLabel = getSourceAttribute();
271 Object value = rs.getObject(columnLabel);
272 return value;
273 }
274
275
276 // /**
277 // * @return the index
278 // */
279 // public int getIndex() {
280 // return exportMapperHelper.getIndex();
281 // }
282
283 /**
284 * @return the state
285 */
286 protected STATE getState() {
287 return importMapperHelper.getState();
288 }
289
290
291 /**
292 * @return the state
293 */
294 protected String getTableName() {
295 return importMapperHelper.getTableName();
296 }
297
298 protected boolean checkDbColumnExists() throws MethodNotSupportedException{
299 // //TODO remove cast
300 // Source source = (Source)getState().getConfig().getSource();
301 // String tableName = getTableName();
302 // String attributeName = getSourceAttribute();
303 // return source.checkColumnExists(tableName, attributeName);
304 //TODO not possible as long as tableName is not initialized
305 return true;
306 }
307
308 // protected int getPrecision(){
309 // return this.precision;
310 // }
311
312 protected int getDbColumnIntegerInfo(String selectPart){
313 //TODO remove cast
314 Source source = (Source)getState().getConfig().getSource();
315 String strQuery = "SELECT " + selectPart + " as result" +
316 " FROM sysobjects AS t " +
317 " INNER JOIN syscolumns AS c ON t.id = c.id " +
318 " WHERE (t.xtype = 'U') AND " +
319 " (t.name = '" + getTableName() + "') AND " +
320 " (c.name = '" + getSourceAttribute() + "')";
321 ResultSet rs = source.getResultSet(strQuery) ;
322 int n;
323 try {
324 rs.next();
325 n = rs.getInt("result");
326 return n;
327 } catch (SQLException e) {
328 e.printStackTrace();
329 return -1;
330 }
331
332 }
333
334
335 /**
336 * @param rs
337 * @return
338 * @throws SQLException
339 */
340 protected String getStringDbValue(ResultSet rs, String attribute) throws SQLException {
341 Object oId = rs.getObject(attribute);
342 String id = String.valueOf(oId);
343 return id;
344 }
345 // public String toString(){
346 // String sourceAtt = CdmUtils.Nz(getSourceAttribute());
347 // String destAtt = CdmUtils.Nz(getDestinationAttribute());
348 // return this.getClass().getSimpleName() +"[" + sourceAtt + "->" + destAtt + "]";
349 // }
350
351 }