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