2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.common
;
12 import java
.lang
.reflect
.Constructor
;
13 import java
.lang
.reflect
.InvocationTargetException
;
14 import java
.util
.HashSet
;
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
;
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
;
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);
43 private Set
<IIoObserver
> observers
= new HashSet
<IIoObserver
>();
44 protected String ioName
= null;
52 this.ioName
= this.getClass().getSimpleName();
55 //******************** Observers *********************************************************
58 public boolean addObserver(IIoObserver observer
){
59 return observers
.add(observer
);
63 * @see eu.etaxonomy.cdm.io.common.IIoObservable#getObservers()
66 public Set
<IIoObserver
> getObservers() {
71 * @see eu.etaxonomy.cdm.io.common.IIoObservable#addObservers(java.util.Set)
74 public void addObservers(Set
<IIoObserver
> newObservers
) {
75 for (IIoObserver observer
: newObservers
){
76 this.observers
.add(observer
);
82 * @see eu.etaxonomy.cdm.io.common.IIoObservable#countObservers()
85 public int countObservers(){
86 return observers
.size();
91 * @see eu.etaxonomy.cdm.io.common.IIoObservable#removeObserver(eu.etaxonomy.cdm.io.common.events.IIoObserver)
93 public boolean removeObserver(IIoObserver observer
){
94 return observers
.remove(observer
);
98 * @see eu.etaxonomy.cdm.io.common.IIoObservable#removeObservers()
100 public void removeObservers(){
101 observers
.removeAll(observers
);
106 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.events.IIoEvent)
108 public void fire(IIoEvent event
){
109 for (IIoObserver observer
: observers
){
110 observer
.handleEvent(event
);
114 //******************** End Observers *********************************************************
118 public int countSteps(){
124 * @see eu.etaxonomy.cdm.io.common.ICdmExport#invoke(eu.etaxonomy.cdm.io.common.ExportStateBase)
126 public boolean invoke(STATE state
) {
127 if (isIgnore( state
)){
128 logger
.info("No invoke for " + ioName
+ " (ignored)");
131 updateProgress(state
, "Invoking " + ioName
);
133 return state
.isSuccess();
138 * invoke method to be implemented by implementing classes
142 protected abstract void doInvoke(STATE state
);
146 SessionFactory sessionFactory
;
149 * flush the current session
151 public void flush() {
152 sessionFactory
.getCurrentSession().flush();
156 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction()
158 public TransactionStatus
startTransaction() {
159 return startTransaction(false);
163 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction(java.lang.Boolean)
165 public TransactionStatus
startTransaction(Boolean readOnly
) {
167 DefaultTransactionDefinition defaultTxDef
= new DefaultTransactionDefinition();
168 defaultTxDef
.setReadOnly(readOnly
);
169 TransactionDefinition txDef
= defaultTxDef
;
171 // Log some transaction-related debug information.
172 if (logger
.isDebugEnabled()) {
173 logger
.debug("Transaction name = " + txDef
.getName());
174 logger
.debug("Transaction facets:");
175 logger
.debug("Propagation behavior = " + txDef
.getPropagationBehavior());
176 logger
.debug("Isolation level = " + txDef
.getIsolationLevel());
177 logger
.debug("Timeout = " + txDef
.getTimeout());
178 logger
.debug("Read Only = " + txDef
.isReadOnly());
179 // org.springframework.orm.hibernate3.HibernateTransactionManager
180 // provides more transaction/session-related debug information.
183 TransactionStatus txStatus
= super.getTransactionManager().getTransaction(txDef
);
187 public void commitTransaction(TransactionStatus txStatus
){
188 PlatformTransactionManager txManager
= super.getTransactionManager();
189 txManager
.commit(txStatus
);
193 public void rollbackTransaction(TransactionStatus txStatus
){
194 PlatformTransactionManager txManager
= super.getTransactionManager();
195 txManager
.rollback(txStatus
);
200 * @see eu.etaxonomy.cdm.io.common.ICdmIO#check(eu.etaxonomy.cdm.io.common.IIoConfigurator)
202 public boolean check(STATE state
) {
203 if (isIgnore(state
)){
204 logger
.info("No check for " + ioName
+ " (ignored)");
207 return doCheck(state
);
211 protected abstract boolean doCheck(STATE state
);
215 * @see eu.etaxonomy.cdm.io.common.ICdmIO#invoke(eu.etaxonomy.cdm.io.common.IIoConfigurator, java.util.Map)
217 // public boolean invoke(T config,
218 // Map<String, MapWrapper<? extends CdmBase>> stores) {
219 // if (isIgnore(config)){
220 // logger.warn("No invoke for " + ioName + " (ignored)");
223 // return doInvoke(config, stores);
227 // protected abstract boolean doInvoke(T config,
228 // Map<String, MapWrapper<? extends CdmBase>> stores);
232 * Returns true if this (IO-)class should be ignored during the import/export process.
233 * This information is usually stored in the configuration
237 protected abstract boolean isIgnore(STATE state
);
239 protected <T
extends CdmBase
> T
getInstance(Class
<?
extends T
> clazz
){
242 Constructor
<?
extends T
> constructor
= clazz
.getDeclaredConstructor();
243 constructor
.setAccessible(true);
244 result
= constructor
.newInstance();
245 } catch (InstantiationException e
) {
246 logger
.error("Class " + clazz
.getSimpleName()+" could not be instantiated. Class = " );
248 } catch (IllegalAccessException e
) {
249 logger
.error("Constructor of class "+clazz
.getSimpleName()+" could not be accessed." );
251 } catch (SecurityException e
) {
253 } catch (NoSuchMethodException e
) {
254 logger
.error("SecurityException for Constructor of class "+clazz
.getSimpleName()+"." );
256 } catch (IllegalArgumentException e
) {
257 logger
.error("Empty Constructor does not exist for class "+clazz
.getSimpleName()+"." );
259 } catch (InvocationTargetException e
) {
260 logger
.error("Empty Constructor could not be invoked for class "+clazz
.getSimpleName()+"." );
267 protected String
getSuccessString(boolean success
){
269 return "with success";
271 return "with errors";
276 public void updateProgress(STATE state
, String message
) {
277 updateProgress(state
, message
, 1);
281 public void updateProgress(STATE state
, String message
, int worked
) {
282 IProgressMonitor progressMonitor
= state
.getConfig().getProgressMonitor();
283 if(progressMonitor
!= null){
284 progressMonitor
.worked(worked
);
285 progressMonitor
.subTask(message
);
290 public void warnProgress(STATE state
, String message
, Throwable e
) {
291 if(state
.getConfig().getProgressMonitor() != null){
292 IProgressMonitor monitor
= state
.getConfig().getProgressMonitor();
294 monitor
.warning(message
);
296 monitor
.warning(message
, e
);
301 protected void fireProgressEvent(String message
, String location
) {
302 IoProgressEvent event
= new IoProgressEvent();
303 event
.setThrowingClass(this.getClass());
304 event
.setMessage(message
);
305 event
.setLocation(location
);
306 // int linenumber = new Exception().getStackTrace()[0].getLineNumber();
311 protected void fireWarningEvent(String message
, String dataLocation
, Integer severity
) {
312 fireWarningEvent(message
, dataLocation
, severity
, 1);
315 protected void fireWarningEvent(String message
, String dataLocation
, Integer severity
, int stackDepth
) {
317 StackTraceElement
[] stackTrace
= new Exception().getStackTrace();
318 int lineNumber
= stackTrace
[stackDepth
].getLineNumber();
319 String methodName
= stackTrace
[stackDepth
].getMethodName();
321 IoProblemEvent event
= IoProblemEvent
.NewInstance(this.getClass(), message
, dataLocation
,
322 lineNumber
, severity
, methodName
);
324 //for performance improvement one may read:
325 //http://stackoverflow.com/questions/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection
326 // Object o = new SecurityManager().getSecurityContext();
332 protected boolean isBlank(String str
){
333 return StringUtils
.isBlank(str
);
336 protected boolean isNotBlank(String str
){
337 return StringUtils
.isNotBlank(str
);
342 // * Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
343 // * Stored in array of the callstack. <br />
344 // * Allows to get past a certain class.
345 // * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
346 // * @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
347 // * @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
349 // public static StackTraceElement getCallingStackTraceElement(final Class aclass) {
350 // final Throwable t = new Throwable();
351 // final StackTraceElement[] ste = t.getStackTrace();
353 // final int limit = ste.length;
354 // StackTraceElement st = ste[index];
355 // String className = st.getClassName();
356 // boolean aclassfound = false;
357 // if(aclass == null) {
358 // aclassfound = true;
360 // StackTraceElement resst = null;
361 // while(index < limit) {
362 // if(shouldExamine(className, aclass) == true) {
363 // if(resst == null) {
366 // if(aclassfound == true) {
367 // final StackTraceElement ast = onClassFound(aclass, className, st);
375 // if(aclass != null && aclass.getName().equals(className) == true) {
376 // aclassfound = true;
380 // index = index + 1;
382 // className = st.getClassName();
384 // if(resst == null) {
385 // throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
390 // static private boolean shouldExamine(String className, Class aclass) {
391 // final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith(LOG_UTILS
392 // ) == false || (aclass !=null && aclass.getName().endsWith(LOG_UTILS)));
396 // static private StackTraceElement onClassFound(Class aclass, String className, StackTraceElement st) {
397 // StackTraceElement resst = null;
398 // if(aclass != null && aclass.getName().equals(className) == false)
402 // if(aclass == null)