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
implements ICdmIO
<STATE
> {
40 private static final Logger logger
= Logger
.getLogger(CdmIoBase
.class);
42 private Set
<IIoObserver
> observers
= new HashSet
<IIoObserver
>();
43 protected String ioName
= null;
51 this.ioName
= this.getClass().getSimpleName();
54 //******************** Observers *********************************************************
57 * @see eu.etaxonomy.cdm.io.common.ICdmIO#addObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
59 public void addObserver(IIoObserver observer
){
60 observers
.add(observer
);
64 * @see eu.etaxonomy.cdm.io.common.ICdmIO#countObservers()
66 public int countObservers(){
67 return observers
.size();
71 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
73 public void deleteObserver(IIoObserver observer
){
74 observers
.remove(observer
);
78 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObservers()
80 public void deleteObservers(){
81 observers
.removeAll(observers
);
85 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.IIoEvent)
87 public void fire(IIoEvent event
){
88 for (IIoObserver observer
: observers
){
89 observer
.handleEvent(event
);
93 //******************** End Observers *********************************************************
97 public int countSteps(){
103 * @see eu.etaxonomy.cdm.io.common.ICdmExport#invoke(eu.etaxonomy.cdm.io.common.ExportStateBase)
105 public boolean invoke(STATE state
) {
106 if (isIgnore( state
)){
107 logger
.warn("No invoke for " + ioName
+ " (ignored)");
110 updateProgress(state
, "Invoking " + ioName
);
112 return state
.isSuccess();
117 * invoke method to be implemented by implementing classes
121 protected abstract void doInvoke(STATE state
);
125 SessionFactory sessionFactory
;
128 * flush the current session
130 public void flush() {
131 sessionFactory
.getCurrentSession().flush();
135 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction()
137 public TransactionStatus
startTransaction() {
138 return startTransaction(false);
142 * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#startTransaction(java.lang.Boolean)
144 public TransactionStatus
startTransaction(Boolean readOnly
) {
146 DefaultTransactionDefinition defaultTxDef
= new DefaultTransactionDefinition();
147 defaultTxDef
.setReadOnly(readOnly
);
148 TransactionDefinition txDef
= defaultTxDef
;
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.
162 TransactionStatus txStatus
= super.getTransactionManager().getTransaction(txDef
);
166 public void commitTransaction(TransactionStatus txStatus
){
167 PlatformTransactionManager txManager
= super.getTransactionManager();
168 txManager
.commit(txStatus
);
174 * @see eu.etaxonomy.cdm.io.common.ICdmIO#check(eu.etaxonomy.cdm.io.common.IIoConfigurator)
176 public boolean check(STATE state
) {
177 if (isIgnore(state
)){
178 logger
.warn("No check for " + ioName
+ " (ignored)");
181 return doCheck(state
);
185 protected abstract boolean doCheck(STATE state
);
189 * @see eu.etaxonomy.cdm.io.common.ICdmIO#invoke(eu.etaxonomy.cdm.io.common.IIoConfigurator, java.util.Map)
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)");
197 // return doInvoke(config, stores);
201 // protected abstract boolean doInvoke(T config,
202 // Map<String, MapWrapper<? extends CdmBase>> stores);
206 * Returns true if this (IO-)class should be ignored during the import/export process.
207 * This information is usually stored in the configuration
211 protected abstract boolean isIgnore(STATE state
);
213 protected <T
extends CdmBase
> T
getInstance(Class
<?
extends T
> clazz
){
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 = " );
222 } catch (IllegalAccessException e
) {
223 logger
.error("Constructor of class "+clazz
.getSimpleName()+" could not be accessed." );
225 } catch (SecurityException e
) {
227 } catch (NoSuchMethodException e
) {
228 logger
.error("SecurityException for Constructor of class "+clazz
.getSimpleName()+"." );
230 } catch (IllegalArgumentException e
) {
231 logger
.error("Empty Constructor does not exist for class "+clazz
.getSimpleName()+"." );
233 } catch (InvocationTargetException e
) {
234 logger
.error("Empty Constructor could not be invoked for class "+clazz
.getSimpleName()+"." );
241 protected String
getSuccessString(boolean success
){
243 return "with success";
245 return "with errors";
250 public void updateProgress(STATE state
, String message
) {
251 updateProgress(state
, message
, 1);
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
);
264 public void warnProgress(STATE state
, String message
, Throwable e
) {
265 if(state
.getConfig().getProgressMonitor() != null){
266 IProgressMonitor monitor
= state
.getConfig().getProgressMonitor();
268 monitor
.warning(message
);
270 monitor
.warning(message
, e
);
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();
285 protected void fireWarningEvent(String message
, String dataLocation
, Integer severity
) {
286 fireWarningEvent(message
, dataLocation
, severity
, 1);
289 protected void fireWarningEvent(String message
, String dataLocation
, Integer severity
, int stackDepth
) {
291 StackTraceElement
[] stackTrace
= new Exception().getStackTrace();
292 int lineNumber
= stackTrace
[stackDepth
].getLineNumber();
293 String methodName
= stackTrace
[stackDepth
].getMethodName();
295 IoProblemEvent event
= IoProblemEvent
.NewInstance(this.getClass(), message
, dataLocation
,
296 lineNumber
, severity
, methodName
);
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();
306 protected boolean isBlank(String str
){
307 return StringUtils
.isBlank(str
);
310 protected boolean isNotBlank(String str
){
311 return StringUtils
.isNotBlank(str
);
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)
323 // public static StackTraceElement getCallingStackTraceElement(final Class aclass) {
324 // final Throwable t = new Throwable();
325 // final StackTraceElement[] ste = t.getStackTrace();
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;
334 // StackTraceElement resst = null;
335 // while(index < limit) {
336 // if(shouldExamine(className, aclass) == true) {
337 // if(resst == null) {
340 // if(aclassfound == true) {
341 // final StackTraceElement ast = onClassFound(aclass, className, st);
349 // if(aclass != null && aclass.getName().equals(className) == true) {
350 // aclassfound = true;
354 // index = index + 1;
356 // className = st.getClassName();
358 // if(resst == null) {
359 // throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
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)));
370 // static private StackTraceElement onClassFound(Class aclass, String className, StackTraceElement st) {
371 // StackTraceElement resst = null;
372 // if(aclass != null && aclass.getName().equals(className) == false)
376 // if(aclass == null)