Merge branch 'release/4.11.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / io / ExportManager.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.taxeditor.io;
11
12 import java.io.BufferedWriter;
13 import java.io.File;
14 import java.io.FileOutputStream;
15 import java.io.OutputStreamWriter;
16 import java.io.Writer;
17 import java.text.SimpleDateFormat;
18 import java.util.ArrayList;
19 import java.util.Calendar;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.UUID;
24 import java.util.zip.ZipEntry;
25 import java.util.zip.ZipOutputStream;
26
27 import org.apache.log4j.Logger;
28 import org.eclipse.core.runtime.Assert;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.core.runtime.jobs.Job;
33 import org.eclipse.swt.widgets.Display;
34
35 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
36 import eu.etaxonomy.cdm.api.application.ICdmRepository;
37 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
38 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
39 import eu.etaxonomy.cdm.io.cdmLight.CdmLightExportConfigurator;
40 import eu.etaxonomy.cdm.io.common.CdmDefaultExport;
41 import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
42 import eu.etaxonomy.cdm.io.common.ExportResult;
43 import eu.etaxonomy.cdm.io.common.ExportResultType;
44 import eu.etaxonomy.cdm.io.common.IExportConfigurator;
45 import eu.etaxonomy.cdm.io.common.IIoConfigurator;
46 import eu.etaxonomy.cdm.io.dwca.out.DwcaTaxExportConfigurator;
47 import eu.etaxonomy.cdm.io.jaxb.JaxbExportConfigurator;
48 import eu.etaxonomy.cdm.io.sdd.out.SDDExportConfigurator;
49 import eu.etaxonomy.cdm.io.service.IIOService;
50 import eu.etaxonomy.taxeditor.event.EventUtility;
51 import eu.etaxonomy.taxeditor.model.AbstractUtility;
52 import eu.etaxonomy.taxeditor.model.CdmProgressMonitorAdapter;
53 import eu.etaxonomy.taxeditor.model.MessagingUtils;
54 import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
55 import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
56 import eu.etaxonomy.taxeditor.store.CdmStore;
57 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
58
59 /**
60 * <p>
61 * ExportHandler class.
62 * </p>
63 *
64 * @author n.hoffmann
65 * @created Sep 11, 2009
66 * @version 1.0
67 */
68 public class ExportManager extends AbstractIOManager<IExportConfigurator> implements IPostMoniteredOperationEnabled {
69
70 private final String successMessage = "The export was successfull";
71
72 private static final Logger logger = Logger.getLogger(ExportManager.class);
73 /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
74 public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
75 /**
76 *
77 * @param applicationConfiguration
78 */
79 private ExportManager(ICdmRepository applicationConfiguration) {
80 super(applicationConfiguration);
81 }
82
83 /**
84 * <p>
85 * NewInstance
86 * </p>
87 *
88 * @param applicationConfiguration
89 * a
90 * {@link eu.etaxonomy.cdm.api.application.CdmApplicationController}
91 * object.
92 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
93 */
94 public static ExportManager NewInstance(
95 ICdmRepository applicationConfiguration) {
96 return new ExportManager(applicationConfiguration);
97 }
98
99 /**
100 * <p>
101 * createIOJob
102 * </p>
103 *
104 * @param configurator
105 * a {@link eu.etaxonomy.cdm.io.common.IExportConfigurator}
106 * object.
107 * @return a {@link org.eclipse.core.runtime.jobs.Job} object.
108 */
109 @Override
110 protected Job createIOJob(final IExportConfigurator configurator) {
111
112 Assert.isNotNull(configurator, "Configuration may not be null");
113
114 final Display display = Display.getCurrent();
115
116 Job job = new Job("Export: " + configurator.getClass().getSimpleName()) {
117 @Override
118 protected IStatus run(IProgressMonitor monitor) {
119 monitor.beginTask(
120 "Exporting database. This will take some time.", 100);
121 monitor.worked(10);
122
123 /** see ticket # 4456 and */
124 // display.asyncExec(new Runnable() {
125 //
126 // @Override
127 // public void run() {
128 //
129 // // terminate any open transactions
130 // IConversationEnabled activePart = (IConversationEnabled) StoreUtil
131 // .getActivePage().getActivePart();
132 // activePart.getConversationHolder().commit(false);
133 // }
134 // });
135
136 // monitor.worked(10);
137
138 CdmDefaultExport<IExportConfigurator> exporter = new CdmDefaultExport<IExportConfigurator>();
139 configurator.setProgressMonitor(CdmProgressMonitorAdapter
140 .CreateSubMonitor(monitor, 80));
141 exporter.setCdmAppController(applicationConfiguration);
142 monitor.worked(10);
143
144 try {
145 exporter.invoke(configurator);
146 monitor.worked(60);
147 } catch (RuntimeException e) {
148 MessagingUtils.messageDialog("Error exporting data", this,
149 "An error occured while"
150 + "exporting to destination '"
151 + configurator.getDestinationNameString()
152 + "'.\n"
153 + "Please check error log for details.", e);
154 }
155
156 display.asyncExec(new Runnable() {
157
158 @Override
159 public void run() {
160 Object activePart = EventUtility.getActivePart();
161 if (activePart instanceof IConversationEnabled) {
162 // terminate any open transactions
163 IConversationEnabled conversationEnabled = (IConversationEnabled) activePart;
164 // restarting transaction and committing it to
165 // trigger
166 // change listener
167 // TODO verify correct behaviour
168
169 try{
170 conversationEnabled.getConversationHolder()
171 .startTransaction();
172
173 conversationEnabled.getConversationHolder()
174 .commit();
175 }catch(RuntimeException e){
176 MessagingUtils.messageDialog("Error starting conversation handling", this, "" +
177 "Conversation Error: "+ e);
178 }
179 }
180 }
181 });
182 monitor.worked(10);
183
184 return Status.OK_STATUS;
185 }
186 };
187
188 return job;
189 }
190
191 public Job createIOServiceJob(final IExportConfigurator configurator, final File exportFile) {
192 Assert.isNotNull(configurator, "Configuration may not be null");
193
194 final Display display = Display.getCurrent();
195
196 Job job = new Job("Export: " + configurator.getClass().getSimpleName()) { //$NON-NLS-1$
197 @Override
198 protected IStatus run(IProgressMonitor monitor) {
199 monitor.beginTask("Exporting database. This will take some time.", IProgressMonitor.UNKNOWN);
200 try {
201 IIOService ioService = CdmApplicationState.getIOService();
202 UUID uuid = ioService.monitExportData(configurator);
203 IRemotingProgressMonitor remotingMonitor;
204 List<IFeedbackGenerator> feedBackGeneratorList = new ArrayList<IFeedbackGenerator>();
205 try {
206 remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor("Export Data",
207 uuid,
208 1000,
209 ExportManager.this,
210 feedBackGeneratorList,
211 monitor);
212
213 } catch (Exception ex) {
214 return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
215 }
216
217 ExportResult result = (ExportResult)remotingMonitor.getResult();
218 ExportDataWrapper data = result.getExportData();
219 try{
220 if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
221 byte[] exportData = (byte[])data.getExportData();
222 if(exportData != null){
223 FileOutputStream stream = new FileOutputStream(exportFile);
224 stream.write(exportData);
225 stream.close();
226 }
227 } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
228 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
229 Set<String> keySet = resultMap.keySet();
230 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
231 Calendar cal = Calendar.getInstance();
232 String fileEnding = ".zip";
233 if (configurator instanceof DwcaTaxExportConfigurator){
234 DwcaTaxExportConfigurator dwcaConfig = (DwcaTaxExportConfigurator)configurator;
235
236 File file = new File(dwcaConfig.getDestination().toURI());
237 FileOutputStream stream = new FileOutputStream(file);
238 ZipOutputStream zos = new ZipOutputStream(stream);
239 for (String key: keySet){
240 byte[] fileData = resultMap.get(key);
241 ZipEntry entry = new ZipEntry( key + fileEnding);
242 zos.putNextEntry(entry);
243 zos.write(fileData);
244 zos.closeEntry();
245 }
246 zos.close();
247 }
248 } else{
249 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
250 }
251
252 } catch(Exception e){
253 logger.error(e.getStackTrace());
254 }
255
256 showResult(configurator.getClass().getSimpleName(), display, result, successMessage);
257
258
259 } catch (Exception e) {
260 MessagingUtils.errorDialog("Error exporting data",
261 this,
262 e.getMessage(),
263 TaxeditorStorePlugin.PLUGIN_ID,
264 e,
265 true);
266 }
267 return Status.OK_STATUS;
268 }
269 };
270 return job;
271 }
272 /**
273 * @param jaxb
274 * @return
275 */
276 private IIoConfigurator getConfigurator(TYPE type) {
277 Assert.isNotNull(type, "Type should not be null");
278
279 switch (type) {
280 case Jaxb:
281 return JaxbExportConfigurator.NewInstance(null, null);
282 case Sdd:
283 return SDDExportConfigurator.NewInstance(null, null, null);
284 default:
285 MessagingUtils.notImplementedMessage(this);
286 throw new IllegalArgumentException("Export not supported yet");
287 }
288 }
289
290 /**
291 * <p>
292 * JaxbConfigurator
293 * </p>
294 *
295 * @return a {@link eu.etaxonomy.cdm.io.jaxb.JaxbExportConfigurator} object.
296 */
297 public final JaxbExportConfigurator JaxbConfigurator() {
298 return (JaxbExportConfigurator) getConfigurator(TYPE.Jaxb);
299 }
300
301 /**
302 * <p>
303 * SddConfigurator
304 * </p>
305 *
306 * @return a {@link eu.etaxonomy.cdm.io.sdd.out.SDDExportConfigurator}
307 * object.
308 */
309 public final SDDExportConfigurator SddConfigurator() {
310 return (SDDExportConfigurator) getConfigurator(TYPE.Sdd);
311 }
312
313 /**
314 * @param configurator
315 * @param urlString
316 * @return
317 */
318 public Job createIOServiceJob(CdmLightExportConfigurator configurator, String urlString) {
319 Assert.isNotNull(configurator, "Configuration may not be null");
320 final Display display = Display.getDefault();
321
322 Job job = new Job("Export: " + configurator.getClass().getSimpleName()) { //$NON-NLS-1$
323 @Override
324 protected IStatus run(IProgressMonitor monitor) {
325 monitor.beginTask("Exporting database. This will take some time.", IProgressMonitor.UNKNOWN);
326 try {
327 IIOService ioService = CdmApplicationState.getIOService();
328
329 ExportResult result = ioService.export(configurator);
330 ExportDataWrapper data = result.getExportData();
331 try{
332 if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
333 byte[] exportData = (byte[])data.getExportData();
334 if(exportData != null){
335 File file = new File(urlString);
336 FileOutputStream stream = new FileOutputStream(file);
337 Writer out = new BufferedWriter(new OutputStreamWriter(
338 stream, "UTF8"));
339
340 stream.write(exportData);
341 out.flush();
342 stream.close();
343 }
344 } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
345 Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
346 Set<String> keySet = resultMap.keySet();
347 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
348 Calendar cal = Calendar.getInstance();
349 String fileEnding = ".csv";
350
351 if (configurator.isCreateZipFile()){
352 File file = new File(urlString+File.separator + "csv_light_" + sdf.format(cal.getTime())+ ".zip");
353 FileOutputStream stream = new FileOutputStream(file);
354 ZipOutputStream zos = new ZipOutputStream(stream);
355 for (String key: keySet){
356 byte[] fileData = resultMap.get(key);
357 ZipEntry entry = new ZipEntry( key + fileEnding);
358 zos.putNextEntry(entry);
359 zos.write(fileData);
360 zos.closeEntry();
361 }
362 zos.close();
363 }else{
364 for (String key: keySet){
365 byte[] fileData = resultMap.get(key);
366 File file = new File(urlString+File.separator + key + fileEnding);
367 FileOutputStream stream = new FileOutputStream(file);
368 Writer out = new BufferedWriter(new OutputStreamWriter(
369 stream, "UTF8"));
370 stream.write(fileData);
371 stream.close();
372 }
373 }
374 }else{
375 logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
376 }
377 } catch(Exception e){
378 logger.error(e.getStackTrace());
379 }
380 showResult(configurator.getClass().getSimpleName(), display, result, successMessage);
381
382
383 } catch (Exception e) {
384 MessagingUtils.errorDialog("Error exporting data",
385 this,
386 e.getMessage(),
387 TaxeditorStorePlugin.PLUGIN_ID,
388 e,
389 true);
390 }
391
392 return Status.OK_STATUS;
393 }
394 };
395 return job;
396 }
397
398 public void runMoniteredOperation(final IExportConfigurator configurator, String urlString) {
399 IIOService ioService = CdmApplicationState.getIOService();
400 final UUID uuid = ioService.monitExportData(configurator);
401
402 Display.getDefault().asyncExec(new Runnable() {
403 @Override
404 public void run() {
405 boolean isZip = false;
406 if (configurator instanceof CdmLightExportConfigurator){
407 isZip = ((CdmLightExportConfigurator)configurator).isCreateZipFile();
408 }
409 AbstractUtility.executeMoniteredExport("Export: " + configurator.getClass().getSimpleName(),
410 uuid,
411 1000,
412 true,
413 ExportManager.this,
414 null,
415 urlString,
416 isZip);
417 }
418 });
419
420 }
421
422 @Override
423 public void postOperation(IRemotingProgressMonitor monitor) {
424 Display.getDefault().asyncExec(new Runnable() {
425
426 @Override
427 public void run() {
428 CdmStore.getContextManager().notifyContextRefresh();
429 }
430 });
431
432 }
433
434 }