OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 21 | Rev 28 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
18 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.erp.generationDoc;
15
 
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
17
import org.openconcerto.erp.core.common.ui.FastPrintAskFrame;
18
import org.openconcerto.erp.core.common.ui.PreviewFrame;
21 ilm 19
import org.openconcerto.erp.generationDoc.element.TypeModeleSQLElement;
25 ilm 20
import org.openconcerto.erp.storage.StorageEngine;
21
import org.openconcerto.erp.storage.StorageEngines;
19 ilm 22
import org.openconcerto.openoffice.OOUtils;
18 ilm 23
import org.jopendocument.link.Component;
24
import org.openconcerto.sql.Configuration;
25
import org.openconcerto.sql.element.SQLElement;
26
import org.openconcerto.sql.model.SQLBase;
27
import org.openconcerto.sql.model.SQLRow;
28
import org.openconcerto.utils.ExceptionHandler;
29
 
25 ilm 30
import java.io.BufferedInputStream;
18 ilm 31
import java.io.File;
25 ilm 32
import java.io.FileInputStream;
19 ilm 33
import java.io.IOException;
18 ilm 34
import java.lang.Thread.UncaughtExceptionHandler;
35
import java.util.HashMap;
25 ilm 36
import java.util.List;
18 ilm 37
import java.util.Map;
25 ilm 38
import java.util.concurrent.Callable;
39
import java.util.concurrent.ExecutionException;
18 ilm 40
import java.util.concurrent.ExecutorService;
41
import java.util.concurrent.Future;
42
import java.util.concurrent.LinkedBlockingQueue;
43
import java.util.concurrent.ThreadPoolExecutor;
44
import java.util.concurrent.TimeUnit;
45
 
46
import javax.print.PrintService;
47
import javax.print.PrintServiceLookup;
48
 
49
import org.jopendocument.model.OpenDocument;
50
import org.jopendocument.print.DefaultDocumentPrinter;
51
 
52
public abstract class SheetXml {
53
 
25 ilm 54
    // return null to keep default value
55
    public interface StorageDirs {
56
        public File getDocumentOutputDirectory(SheetXml sheet);
57
 
58
        public File getPDFOutputDirectory(SheetXml sheet);
59
 
60
        public String getStoragePath(SheetXml sheet);
61
    }
62
 
63
    private static StorageDirs STORAGE_DIRS;
64
 
65
    // allow to redirect all documents
66
    public static void setStorageDirs(StorageDirs d) {
67
        STORAGE_DIRS = d;
68
    }
69
 
70
    public static final String DEFAULT_PROPERTY_NAME = "Default";
18 ilm 71
    protected SQLElement elt;
72
 
73
    // nom de l'imprimante à utiliser
74
    protected String printer;
75
 
76
    // id
77
    protected SQLRow row;
78
 
19 ilm 79
    // Language du document
80
    protected SQLRow rowLanguage;
81
 
18 ilm 82
    protected static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
83
 
84
    // single threaded and kill its thread after 3 seconds (to allow the program to exit)
85
    protected static final ExecutorService runnableQueue = new ThreadPoolExecutor(0, 1, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
86
 
87
    protected static UncaughtExceptionHandler DEFAULT_HANDLER = new UncaughtExceptionHandler() {
88
        @Override
89
        public void uncaughtException(Thread t, Throwable e) {
19 ilm 90
            ExceptionHandler.handle("Erreur de generation", e);
18 ilm 91
        }
92
    };
93
 
25 ilm 94
    public final SQLElement getElement() {
95
        return this.elt;
18 ilm 96
    }
97
 
25 ilm 98
    /**
99
     * Show, print and export the document to PDF. This method is asynchronous, but is executed in a
100
     * single threaded queue shared with createDocument
101
     * */
102
    public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
103
        final Callable<SheetXml> c = new Callable<SheetXml>() {
104
            @Override
105
            public SheetXml call() throws Exception {
106
                showPrintAndExport(showDocument, printDocument, exportToPDF);
107
                return SheetXml.this;
108
            }
109
        };
110
        return runnableQueue.submit(c);
18 ilm 111
 
25 ilm 112
    }
113
 
114
    /**
115
     * Show, print and export the document to PDF. This method is synchronous
116
     * */
117
    public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
118
 
119
        final File generatedFile = getGeneratedFile();
120
        final File pdfFile = getGeneratedPDFFile();
121
        if (generatedFile == null || !generatedFile.exists()) {
122
            ExceptionHandler.handle("Fichier généré manquant: " + generatedFile);
18 ilm 123
            return;
124
        }
125
 
126
        try {
127
            if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
25 ilm 128
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(generatedFile, !showDocument);
18 ilm 129
 
25 ilm 130
                if (printDocument) {
18 ilm 131
                    Map<String, Object> map = new HashMap<String, Object>();
132
                    map.put("Name", this.printer);
133
                    doc.printDocument(map);
134
                }
25 ilm 135
                if (exportToPDF) {
136
                    doc.saveToPDF(pdfFile).get();
137
                }
18 ilm 138
                doc.close();
139
            } else {
25 ilm 140
                final OpenDocument doc = new OpenDocument(generatedFile);
18 ilm 141
 
25 ilm 142
                if (showDocument) {
18 ilm 143
                    showPreviewDocument();
144
                }
25 ilm 145
                if (printDocument) {
18 ilm 146
                    // Print !
147
                    DefaultDocumentPrinter printer = new DefaultDocumentPrinter();
148
                    printer.print(doc);
149
 
150
                }
25 ilm 151
                if (exportToPDF) {
18 ilm 152
 
25 ilm 153
                    try {
154
                        SheetUtils.convert2PDF(doc, pdfFile);
155
 
156
                    } catch (Throwable e) {
157
                        ExceptionHandler.handle("Impossible de créer le PDF");
158
                    }
159
 
160
                    Thread t = new Thread(new Runnable() {
161
 
162
                        @Override
163
                        public void run() {
164
                            List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
165
                            for (StorageEngine storageEngine : engines) {
166
                                if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
167
                                    try {
168
                                        storageEngine.connect();
169
                                        final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(pdfFile));
170
                                        final String path = getStoragePath();
171
                                        storageEngine.store(inStream, path, pdfFile.getName(), true);
172
                                        inStream.close();
173
                                        storageEngine.disconnect();
174
                                    } catch (IOException e) {
175
                                        ExceptionHandler.handle("Impossible de sauvegarder le PDF");
176
                                    }
177
                                }
178
                            }
179
 
180
                        }
181
                    });
182
                    t.start();
183
 
184
                }
18 ilm 185
            }
186
 
187
        } catch (Exception e) {
188
            e.printStackTrace();
189
            ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
190
        }
191
    }
192
 
25 ilm 193
    public abstract String getDefaultTemplateId();
21 ilm 194
 
25 ilm 195
    /**
196
     * Path of the directory used for storage. Ex: Devis/2010
197
     * */
198
    public final String getStoragePath() {
199
        final String res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getStoragePath(this);
200
        if (res != null)
201
            return res;
202
        else
203
            return this.getStoragePathP();
204
    }
205
 
206
    public final File getDocumentOutputDirectory() {
207
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getDocumentOutputDirectory(this);
208
        if (res != null)
209
            return res;
210
        else
211
            return this.getDocumentOutputDirectoryP();
212
    }
213
 
214
    public final File getPDFOutputDirectory() {
215
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getPDFOutputDirectory(this);
216
        if (res != null)
217
            return res;
218
        else
219
            return this.getPDFOutputDirectoryP();
220
    }
221
 
222
    protected abstract String getStoragePathP();
223
 
224
    protected abstract File getDocumentOutputDirectoryP();
225
 
226
    protected abstract File getPDFOutputDirectoryP();
227
 
228
    /**
229
     * Name of the generated document (without extension), do not rely on this name.
230
     *
231
     * Use getGeneratedFile().getName() to get the generated file name.
232
     * */
233
    public abstract String getName();
234
 
235
    /**
236
     * @return the template id for this template (ex: "sales.quote")
237
     * */
238
    public String getTemplateId() {
239
        if (this.row != null && this.row.getTable().getFieldsName().contains("ID_MODELE")) {
21 ilm 240
            SQLRow rowModele = this.row.getForeignRow("ID_MODELE");
241
            if (rowModele.isUndefined()) {
242
                TypeModeleSQLElement typeModele = Configuration.getInstance().getDirectory().getElement(TypeModeleSQLElement.class);
25 ilm 243
                String modele = typeModele.getTemplateMapping().get(this.row.getTable().getName());
21 ilm 244
                if (modele == null) {
245
                    System.err.println("No default modele in table TYPE_MODELE for table " + this.row.getTable().getName());
246
                    Thread.dumpStack();
25 ilm 247
                    return getDefaultTemplateId();
21 ilm 248
                } else {
249
                    return modele;
250
                }
251
            } else {
252
                return rowModele.getString("NOM");
253
            }
254
        }
25 ilm 255
        return getDefaultTemplateId();
21 ilm 256
    }
257
 
25 ilm 258
    public abstract Future<SheetXml> createDocumentAsynchronous();
18 ilm 259
 
25 ilm 260
    public void createDocument() throws InterruptedException, ExecutionException {
261
        createDocumentAsynchronous().get();
18 ilm 262
    }
263
 
25 ilm 264
    /**
265
     * get the File that is, or must be generated.
266
     *
267
     * @return a file (not null)
268
     * */
269
    public abstract File getGeneratedFile();
18 ilm 270
 
25 ilm 271
    public File getGeneratedPDFFile() {
272
        return SheetUtils.getFileWithExtension(getGeneratedFile(), ".pdf");
18 ilm 273
    }
274
 
19 ilm 275
    public SQLRow getRowLanguage() {
276
        return this.rowLanguage;
277
    }
278
 
279
    public String getReference() {
280
        return "";
281
    }
282
 
18 ilm 283
    /**
25 ilm 284
     * Creates the document if needed and returns the generated file (OpenDocument)
285
     * */
286
    public File getOrCreateDocumentFile() throws Exception {
287
        File f = getGeneratedFile();
288
        if (!f.exists()) {
289
            return createDocumentAsynchronous().get().getGeneratedFile();
18 ilm 290
        } else {
25 ilm 291
            return f;
18 ilm 292
        }
293
    }
294
 
25 ilm 295
    /**
296
     * Open the document with the native application
297
     *
298
     * @param synchronous
299
     * */
300
    public void openDocument(boolean synchronous) {
301
        Runnable r = new Runnable() {
302
 
303
            @Override
304
            public void run() {
305
                File f;
306
                try {
307
                    f = getOrCreateDocumentFile();
308
                    OOUtils.open(f);
309
                } catch (Exception e) {
310
                    ExceptionHandler.handle("Impossible d'ouvrir le document.", e);
311
                }
18 ilm 312
            }
25 ilm 313
        };
314
        if (synchronous) {
315
            r.run();
18 ilm 316
        } else {
25 ilm 317
            Thread thread = new Thread(r, "openDocument: " + getGeneratedFile().getAbsolutePath());
318
            thread.setDaemon(true);
319
            thread.start();
18 ilm 320
        }
321
 
322
    }
323
 
25 ilm 324
    public void showPreviewDocument() throws Exception {
325
        File f = null;
326
        f = getOrCreateDocumentFile();
18 ilm 327
        PreviewFrame.show(f);
328
    }
329
 
330
    public void fastPrintDocument() {
331
        FastPrintAskFrame f = new FastPrintAskFrame(this);
332
        f.display();
333
    }
334
 
335
    public void fastPrintDocument(short copies) {
336
 
337
        try {
25 ilm 338
            final File f = getOrCreateDocumentFile();
339
 
18 ilm 340
            if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
341
 
342
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, true);
343
 
344
                Map<String, Object> map = new HashMap<String, Object>();
345
                if (this.printer == null || this.printer.trim().length() == 0) {
346
                    PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
347
                    this.printer = printer.getName();
348
                }
349
                map.put("Name", this.printer);
350
                Map<String, Object> map2 = new HashMap<String, Object>();
351
                map2.put("CopyCount", copies);
352
 
353
                // http://www.openoffice.org/issues/show_bug.cgi?id=99606
354
                // fix bug if collate = false then print squared number of copies
355
                map2.put("Collate", Boolean.TRUE);
356
                doc.printDocument(map, map2);
357
                doc.close();
358
 
359
            } else {
360
                // Load the spreadsheet.
361
                final OpenDocument doc = new OpenDocument(f);
362
 
363
                // Print !
364
                DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter(this.printer, copies);
365
                printer.print(doc);
366
            }
367
        } catch (Exception e) {
368
 
369
            ExceptionHandler.handle("Impossible de charger le document OpentOffice", e);
370
            e.printStackTrace();
371
        }
372
    }
373
 
374
    public void printDocument() {
375
 
376
        try {
25 ilm 377
            final File f = getOrCreateDocumentFile();
18 ilm 378
 
379
            if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
380
 
381
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, true);
382
                doc.printDocument();
383
                doc.close();
384
            } else {
385
                // Load the spreadsheet.
386
                final OpenDocument doc = new OpenDocument(f);
387
 
388
                // Print !
389
                DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
390
                printer.print(doc);
391
            }
392
 
393
        } catch (Exception e) {
394
 
395
            ExceptionHandler.handle("Impossible de charger le document OpentOffice", e);
396
            e.printStackTrace();
397
        }
398
    }
399
 
400
    public SQLRow getSQLRow() {
401
        return this.row;
402
    }
403
 
404
    /**
405
     * Remplace tous les caracteres non alphanumeriques (seul le _ est autorisé) par un -. Cela
406
     * permet d'avoir toujours un nom de fichier valide.
407
     *
408
     * @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
409
     * @return un nom fichier valide ex:FACTURE_2007-03-001
410
     */
25 ilm 411
    static String getValidFileName(String fileName) {
412
        final StringBuffer result = new StringBuffer(fileName.length());
18 ilm 413
        for (int i = 0; i < fileName.length(); i++) {
25 ilm 414
            char ch = fileName.charAt(i);
18 ilm 415
 
416
            // Si c'est un caractere alphanumerique
25 ilm 417
            if (Character.isLetterOrDigit(ch) || (ch == '_') || (ch == ' ')) {
418
                result.append(ch);
18 ilm 419
            } else {
420
                result.append('-');
421
            }
422
        }
423
        return result.toString();
424
    }
425
 
426
    public String getPrinter() {
427
        return this.printer;
428
    }
429
 
430
}