Object change mapper for PESI and empty epithet bugfix and empty hybrid formula bugfix
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / common / CdmIoBase.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.io.common;
11
12 import java.lang.reflect.Constructor;
13 import java.lang.reflect.InvocationTargetException;
14 import java.util.HashSet;
15 import java.util.Set;
16
17 import org.apache.commons.lang.StringUtils;
18 import org.apache.log4j.Logger;
19 import org.hibernate.SessionFactory;
20 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.transaction.PlatformTransactionManager;
22 import org.springframework.transaction.TransactionDefinition;
23 import org.springframework.transaction.TransactionStatus;
24 import org.springframework.transaction.support.DefaultTransactionDefinition;
25
26 import eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration;
27 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
28 import eu.etaxonomy.cdm.io.common.events.IIoEvent;
29 import eu.etaxonomy.cdm.io.common.events.IIoObserver;
30 import eu.etaxonomy.cdm.io.common.events.IoProblemEvent;
31 import eu.etaxonomy.cdm.io.common.events.IoProgressEvent;
32 import eu.etaxonomy.cdm.model.common.CdmBase;
33
34 /**
35 * @author a.mueller
36 * @created 01.07.2008
37 * @version 1.0
38 */
39 public abstract class CdmIoBase<STATE extends IoStateBase> extends CdmApplicationDefaultConfiguration implements ICdmIO<STATE> {
40 private static final Logger logger = Logger.getLogger(CdmIoBase.class);
41
42 private Set<IIoObserver> observers = new HashSet<IIoObserver>();
43 protected String ioName = null;
44
45
46 /**
47 *
48 */
49 public CdmIoBase() {
50 super();
51 this.ioName = this.getClass().getSimpleName();
52 }
53
54 //******************** Observers *********************************************************
55
56 /* (non-Javadoc)
57 * @see eu.etaxonomy.cdm.io.common.ICdmIO#addObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
58 */
59 public void addObserver(IIoObserver observer){
60 observers.add(observer);
61 }
62
63 /* (non-Javadoc)
64 * @see eu.etaxonomy.cdm.io.common.ICdmIO#countObservers()
65 */
66 public int countObservers(){
67 return observers.size();
68 }
69
70 /* (non-Javadoc)
71 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
72 */
73 public void deleteObserver(IIoObserver observer){
74 observers.remove(observer);
75 }
76
77 /* (non-Javadoc)
78 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObservers()
79 */
80 public void deleteObservers(){
81 observers.removeAll(observers);
82 }
83
84 /* (non-Javadoc)
85 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.IIoEvent)
86 */
87 public void fire(IIoEvent event){
88 for (IIoObserver observer: observers){
89 observer.handleEvent(event);
90 }
91 }
92
93 //******************** End Observers *********************************************************
94
95
96
97 public int countSteps(){
98 return 1;
99 }
100
101
102 /* (non-Javadoc)
103 * @see eu.etaxonomy.cdm.io.common.ICdmExport#invoke(eu.etaxonomy.cdm.io.common.ExportStateBase)
104 */
105 public boolean invoke(STATE state) {
106 if (isIgnore( state)){
107 logger.warn("No invoke for " + ioName + " (ignored)");
108 return true;
109 }else{
110 updateProgress(state, "Invoking " + ioName);
111 doInvoke(state);
112 return state.isSuccess();
113 }
114 }
115
116 /**
117 * invoke method to be implemented by implementing classes
118 * @param state
119 * @return
120 */
121 protected abstract void doInvoke(STATE state);
122
123
124 @Autowired
125 SessionFactory sessionFactory;
126
127 /**
128 * flush the current session
129 */
130 public void flush() {
131 sessionFactory.getCurrentSession().flush();
132 }
133
134 /* (non-Javadoc)
135 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction()
136 */
137 public TransactionStatus startTransaction() {
138 return startTransaction(false);
139 }
140
141 /* (non-Javadoc)
142 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction(java.lang.Boolean)
143 */
144 public TransactionStatus startTransaction(Boolean readOnly) {
145
146 DefaultTransactionDefinition defaultTxDef = new DefaultTransactionDefinition();
147 defaultTxDef.setReadOnly(readOnly);
148 TransactionDefinition txDef = defaultTxDef;
149
150 // Log some transaction-related debug information.
151 if (logger.isDebugEnabled()) {
152 logger.debug("Transaction name = " + txDef.getName());
153 logger.debug("Transaction facets:");
154 logger.debug("Propagation behavior = " + txDef.getPropagationBehavior());
155 logger.debug("Isolation level = " + txDef.getIsolationLevel());
156 logger.debug("Timeout = " + txDef.getTimeout());
157 logger.debug("Read Only = " + txDef.isReadOnly());
158 // org.springframework.orm.hibernate3.HibernateTransactionManager
159 // provides more transaction/session-related debug information.
160 }
161
162 TransactionStatus txStatus = super.getTransactionManager().getTransaction(txDef);
163 return txStatus;
164 }
165
166 public void commitTransaction(TransactionStatus txStatus){
167 PlatformTransactionManager txManager = super.getTransactionManager();
168 txManager.commit(txStatus);
169 return;
170 }
171
172
173 /* (non-Javadoc)
174 * @see eu.etaxonomy.cdm.io.common.ICdmIO#check(eu.etaxonomy.cdm.io.common.IIoConfigurator)
175 */
176 public boolean check(STATE state) {
177 if (isIgnore(state)){
178 logger.warn("No check for " + ioName + " (ignored)");
179 return true;
180 }else{
181 return doCheck(state);
182 }
183 }
184
185 protected abstract boolean doCheck(STATE state);
186
187
188 /* (non-Javadoc)
189 * @see eu.etaxonomy.cdm.io.common.ICdmIO#invoke(eu.etaxonomy.cdm.io.common.IIoConfigurator, java.util.Map)
190 */
191 // public boolean invoke(T config,
192 // Map<String, MapWrapper<? extends CdmBase>> stores) {
193 // if (isIgnore(config)){
194 // logger.warn("No invoke for " + ioName + " (ignored)");
195 // return true;
196 // }else{
197 // return doInvoke(config, stores);
198 // }
199 // }
200
201 // protected abstract boolean doInvoke(T config,
202 // Map<String, MapWrapper<? extends CdmBase>> stores);
203
204
205 /**
206 * Returns true if this (IO-)class should be ignored during the import/export process.
207 * This information is usually stored in the configuration
208 * @param config
209 * @return
210 */
211 protected abstract boolean isIgnore(STATE state);
212
213 protected <T extends CdmBase> T getInstance(Class<? extends T> clazz){
214 T result = null;
215 try {
216 Constructor<? extends T> constructor = clazz.getDeclaredConstructor();
217 constructor.setAccessible(true);
218 result = constructor.newInstance();
219 } catch (InstantiationException e) {
220 logger.error("Class " + clazz.getSimpleName()+" could not be instantiated. Class = " );
221 e.printStackTrace();
222 } catch (IllegalAccessException e) {
223 logger.error("Constructor of class "+clazz.getSimpleName()+" could not be accessed." );
224 e.printStackTrace();
225 } catch (SecurityException e) {
226 e.printStackTrace();
227 } catch (NoSuchMethodException e) {
228 logger.error("SecurityException for Constructor of class "+clazz.getSimpleName()+"." );
229 e.printStackTrace();
230 } catch (IllegalArgumentException e) {
231 logger.error("Empty Constructor does not exist for class "+clazz.getSimpleName()+"." );
232 e.printStackTrace();
233 } catch (InvocationTargetException e) {
234 logger.error("Empty Constructor could not be invoked for class "+clazz.getSimpleName()+"." );
235 e.printStackTrace();
236 }
237 return result;
238 }
239
240
241 protected String getSuccessString(boolean success){
242 if (success){
243 return "with success";
244 }else{
245 return "with errors";
246 }
247 }
248
249 @Override
250 public void updateProgress(STATE state, String message) {
251 updateProgress(state, message, 1);
252 };
253
254 @Override
255 public void updateProgress(STATE state, String message, int worked) {
256 IProgressMonitor progressMonitor = state.getConfig().getProgressMonitor();
257 if(progressMonitor != null){
258 progressMonitor.worked(worked);
259 progressMonitor.subTask(message);
260 }
261 }
262
263 @Override
264 public void warnProgress(STATE state, String message, Throwable e) {
265 if(state.getConfig().getProgressMonitor() != null){
266 IProgressMonitor monitor = state.getConfig().getProgressMonitor();
267 if (e == null) {
268 monitor.warning(message);
269 }else{
270 monitor.warning(message, e);
271 }
272 }
273 }
274
275 protected void fireProgressEvent(String message, String location) {
276 IoProgressEvent event = new IoProgressEvent();
277 event.setThrowingClass(this.getClass());
278 event.setMessage(message);
279 event.setLocation(location);
280 // int linenumber = new Exception().getStackTrace()[0].getLineNumber();
281 fire(event);
282 }
283
284
285 protected void fireWarningEvent(String message, String dataLocation, Integer severity) {
286 fireWarningEvent(message, dataLocation, severity, 1);
287 }
288
289 protected void fireWarningEvent(String message, String dataLocation, Integer severity, int stackDepth) {
290 stackDepth++;
291 StackTraceElement[] stackTrace = new Exception().getStackTrace();
292 int lineNumber = stackTrace[stackDepth].getLineNumber();
293 String methodName = stackTrace[stackDepth].getMethodName();
294
295 IoProblemEvent event = IoProblemEvent.NewInstance(this.getClass(), message, dataLocation,
296 lineNumber, severity, methodName);
297
298 //for performance improvement one may read:
299 //http://stackoverflow.com/questions/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection
300 // Object o = new SecurityManager().getSecurityContext();
301
302
303 fire(event);
304 }
305
306 protected boolean isBlank(String str){
307 return StringUtils.isBlank(str);
308 }
309
310 protected boolean isNotBlank(String str){
311 return StringUtils.isNotBlank(str);
312 }
313
314
315 // /**
316 // * Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
317 // * Stored in array of the callstack. <br />
318 // * Allows to get past a certain class.
319 // * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
320 // * @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
321 // * @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
322 // */
323 // public static StackTraceElement getCallingStackTraceElement(final Class aclass) {
324 // final Throwable t = new Throwable();
325 // final StackTraceElement[] ste = t.getStackTrace();
326 // int index = 1;
327 // final int limit = ste.length;
328 // StackTraceElement st = ste[index];
329 // String className = st.getClassName();
330 // boolean aclassfound = false;
331 // if(aclass == null) {
332 // aclassfound = true;
333 // }
334 // StackTraceElement resst = null;
335 // while(index < limit) {
336 // if(shouldExamine(className, aclass) == true) {
337 // if(resst == null) {
338 // resst = st;
339 // }
340 // if(aclassfound == true) {
341 // final StackTraceElement ast = onClassFound(aclass, className, st);
342 // if(ast != null) {
343 // resst = ast;
344 // break;
345 // }
346 // }
347 // else
348 // {
349 // if(aclass != null && aclass.getName().equals(className) == true) {
350 // aclassfound = true;
351 // }
352 // }
353 // }
354 // index = index + 1;
355 // st = ste[index];
356 // className = st.getClassName();
357 // }
358 // if(resst == null) {
359 // throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
360 // }
361 // return resst;
362 // }
363 //
364 // static private boolean shouldExamine(String className, Class aclass) {
365 // final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith(LOG_UTILS
366 // ) == false || (aclass !=null && aclass.getName().endsWith(LOG_UTILS)));
367 // return res;
368 // }
369 //
370 // static private StackTraceElement onClassFound(Class aclass, String className, StackTraceElement st) {
371 // StackTraceElement resst = null;
372 // if(aclass != null && aclass.getName().equals(className) == false)
373 // {
374 // resst = st;
375 // }
376 // if(aclass == null)
377 // {
378 // resst = st;
379 // }
380 // return resst;
381 // }
382
383
384 }