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