View Javadoc

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 }