Statistics
| Revision:

svn-document-layout / trunk / org.gvsig.app.document.layout2.app / org.gvsig.app.document.layout2.app.mainplugin / src / main / java / org / gvsig / app / extension / reportfromlayout / ConfigureReportFromLayout.java @ 1607

History | View | Annotate | Download (21.6 KB)

1 1594 fdiaz
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.app.extension.reportfromlayout;
7
8
import java.awt.Dimension;
9
import java.awt.event.ActionEvent;
10
import java.awt.event.ActionListener;
11 1601 fdiaz
import java.io.ByteArrayOutputStream;
12 1594 fdiaz
import java.io.InputStream;
13
import java.nio.charset.StandardCharsets;
14
import java.util.List;
15
import java.util.function.Predicate;
16
import javax.json.JsonObject;
17
import javax.swing.DefaultComboBoxModel;
18
import javax.swing.JComponent;
19
import javax.swing.JOptionPane;
20
import javax.swing.SwingUtilities;
21
import javax.swing.event.DocumentEvent;
22
import javax.swing.event.DocumentListener;
23
import javax.swing.event.TreeSelectionEvent;
24 1601 fdiaz
import org.apache.commons.codec.binary.Hex;
25 1594 fdiaz
import org.apache.commons.io.IOUtils;
26
import org.apache.commons.lang3.StringUtils;
27
import org.gvsig.app.ApplicationLocator;
28 1601 fdiaz
import org.gvsig.app.gui.styling.SymbolSelector;
29 1594 fdiaz
import org.gvsig.app.project.documents.Document;
30
import org.gvsig.app.project.documents.layout.LayoutDocument;
31
import org.gvsig.app.project.documents.layout.fframes.FFrameView;
32
import org.gvsig.app.project.documents.layout.fframes.IFFrame;
33
import org.gvsig.app.project.documents.layout.report.LayoutReportAction;
34
import org.gvsig.app.project.documents.layout.report.LayoutReportActionFactory;
35
import org.gvsig.app.project.documents.layout.report.LayoutReportActionImpl;
36 1601 fdiaz
import org.gvsig.app.project.documents.view.legend.gui.ISymbolSelector;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38 1594 fdiaz
import org.gvsig.fmap.dal.feature.FeatureStore;
39
import org.gvsig.fmap.dal.swing.DALSwingLocator;
40
import org.gvsig.fmap.dal.swing.DataSwingManager;
41
import org.gvsig.fmap.dal.swing.report.ReportAction;
42
import org.gvsig.fmap.dal.swing.storesrepository.StoresRepositoryController;
43 1601 fdiaz
import org.gvsig.fmap.mapcontext.MapContextLocator;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
45 1594 fdiaz
import org.gvsig.json.Json;
46
import org.gvsig.json.JsonObjectBuilder;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.dispose.DisposeUtils;
49
import org.gvsig.tools.i18n.I18nManager;
50
import org.gvsig.tools.persistence.PersistenceManager;
51
import org.gvsig.tools.persistence.PersistentState;
52
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
53
import org.gvsig.tools.swing.api.ListElement;
54
import org.gvsig.tools.swing.api.ToolsSwingLocator;
55
import org.gvsig.tools.swing.api.ToolsSwingManager;
56
import org.gvsig.tools.swing.api.ToolsSwingUtils;
57
import org.gvsig.tools.swing.api.documentfilters.PositiveDoubleDocumentFilter;
58
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
59
import org.gvsig.tools.swing.api.windowmanager.Dialog;
60 1601 fdiaz
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
61 1594 fdiaz
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
62
import org.gvsig.tools.util.LabeledValue;
63
import org.gvsig.tools.util.LabeledValueImpl;
64
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
66
67
/**
68
 *
69
 * @author fdiaz
70
 */
71
public class ConfigureReportFromLayout extends ConfigureReportFromLayoutPanelView {
72
73
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureReportFromLayout.class);
74
75
    private StoresRepositoryController treeSourceController;
76
    private FeatureStore source;
77
    private Dialog dialog;
78 1601 fdiaz
    private ISymbol highlightSymbol;
79 1594 fdiaz
80
    public ConfigureReportFromLayout() {
81
        this.initComponents();
82
83
    }
84
85
    private void initComponents() {
86
87
        DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
88
        translate();
89
90
        fillCboLayout();
91
92
        this.cboLayout.addActionListener(new ActionListener() {
93
            @Override
94
            public void actionPerformed(ActionEvent e) {
95
                doChangeLayout();
96
            }
97
        });
98
99
        this.treeSourceController = dataSwingManager.createStoresRepositoryController(this.treeSource);
100
        this.treeSource.addTreeSelectionListener((TreeSelectionEvent e) -> {
101
            doChangeSource();
102
            doUpdateComponents();
103
        });
104
105
        this.cboReport.addActionListener((ActionEvent e) -> {
106
            doChangeReport();
107
        });
108
109
        this.txtIdentifier.getDocument().addDocumentListener(new DocumentListener() {
110
            @Override
111
            public void insertUpdate(DocumentEvent e) {
112
                doUpdateComponents();
113
            }
114
115
            @Override
116
            public void removeUpdate(DocumentEvent e) {
117
                doUpdateComponents();
118
            }
119
120
            @Override
121
            public void changedUpdate(DocumentEvent e) {
122
               doUpdateComponents();
123
            }
124
        });
125
126 1601 fdiaz
        this.chkZoomToCurrentRow.addActionListener((ActionEvent e) -> {
127
            doUpdateComponents();
128 1594 fdiaz
        });
129
130 1601 fdiaz
        this.btnSelectSymbol.addActionListener((ActionEvent e) -> {
131
            doSelectSymbol();
132
        });
133
134
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
135
136 1594 fdiaz
        PositiveDoubleDocumentFilter.install(txtBufferSize);
137
138
        Dimension screensize = ApplicationLocator.getApplicationManager().getUIManager().getInternalSize();
139
        ToolsSwingUtils.ensureHeightWitdh(
140
                this,
141
                Math.max(3*(screensize.height/4), ToolsSwingUtils.rows2px(80)),
142
                Math.max(2*(screensize.width/4), ToolsSwingUtils.cols2px(35)),
143
                7*(screensize.height/8),
144
                3*(screensize.width/4)
145
        );
146
147
        SwingUtilities.invokeLater(this::doUpdateComponents);
148
149
    }
150
151
    private void doChangeSource() {
152
        FeatureStore theSource = this.treeSourceController.getSelectedFeatureStore();
153
        if( theSource==null ) {
154
            return;
155
        }
156
        if(this.source != null){
157
            DisposeUtils.disposeQuietly(this.source);
158
        }
159
        this.source = theSource;
160
        fillCboReport();
161
        doUpdateComponents();
162
    }
163
164
    private void doChangeLayout() {
165
        fillCboView();
166
        doUpdateComponents();
167
    }
168 1601 fdiaz
169
    private void doSelectSymbol() {
170 1594 fdiaz
171 1601 fdiaz
        if(this.source == null){
172
            return;
173
        }
174
        FeatureAttributeDescriptor geomAttr = this.source.getDefaultFeatureTypeQuietly().getDefaultGeometryAttribute();
175
        if(geomAttr == null){
176
            return;
177
        }
178
        int geomType = geomAttr.getGeomType().getType();
179
180
        if(this.highlightSymbol == null) {
181
            this.highlightSymbol = MapContextLocator.getMapContextManager().createSymbol(geomType);
182
        }
183
        ISymbolSelector symSel = SymbolSelector.createSymbolSelector(this.highlightSymbol, geomType);
184
185
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
186
        windowManager.showWindow((JComponent)symSel, "_Symbol", WindowManager.MODE.DIALOG);
187
        this.highlightSymbol = (ISymbol) symSel.getSelectedObject();
188
189
    }
190
191
192 1594 fdiaz
    private void doUpdateComponents() {
193
        this.treeSourceController.setEnabled(true);
194
195
        this.cboReport.setEnabled(this.source != null);
196
197
        this.txtBufferSize.setEnabled(this.chkZoomToCurrentRow.isSelected());
198
199
        if(this.dialog != null){
200
            boolean enabled = (this.source != null) && (this.getLayoutDocument() != null) && StringUtils.isNotBlank(this.txtIdentifier.getText());
201
            this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, enabled);
202
        }
203
    }
204
205
    private void fillCboReport() {
206
        DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
207
        DefaultComboBoxModel<LabeledValue<ReportAction>> model = new DefaultComboBoxModel();
208
        if(this.source == null) {
209
            this.cboReport.setModel(model);
210
            return;
211
        }
212
        List<ReportAction> reports = dataSwingManager.getReportActions(source, (Predicate<JsonObject>) (JsonObject t) -> LayoutReportActionFactory.isJsonApplicable(t));
213
214
        model.addElement(new LabeledValueImpl<>("", null));
215
        for (ReportAction report : reports) {
216
            model.addElement(new LabeledValueImpl<>(report.getReportLabel(), report));
217
        }
218
        cboReport.setModel(model);
219
220
    }
221
222
    List<Document> getLayouts() {
223
224
        List<Document> layouts = ApplicationLocator.getProjectManager().getCurrentProject().getDocuments(LayoutDocument.class);
225
226
        return layouts;
227
228
    }
229
230
231
232
    private void fillCboLayout() {
233
        DefaultComboBoxModel<LabeledValue<LayoutDocument>> model = new DefaultComboBoxModel();
234
        List<Document> layouts = getLayouts();
235
236
        for (Document layout : layouts) {
237
            if(layout instanceof LayoutDocument){
238
                model.addElement(new LabeledValueImpl<>(layout.getName(), (LayoutDocument)layout));
239
            }
240
        }
241
        cboLayout.setModel(model);
242
        fillCboView();
243
244
    }
245
246
    private void fillCboView() {
247
        LayoutDocument layout = getLayoutDocument();
248
        DefaultComboBoxModel<LabeledValue<String>> model = new DefaultComboBoxModel();
249
        if (layout != null) {
250
            int n = 1;
251
            for (IFFrame frame : layout.getLayoutContext().getAllFFrames()) {
252
                if (frame instanceof FFrameView) {
253
                    String tag = frame.getTag();
254
                    if(StringUtils.startsWith(tag, "#") && !StringUtils.equals(tag, "#"+n)){
255
                        model.addElement(new LabeledValueImpl<>(tag+" (invalid tag)",tag));
256
                    } else {
257
                        if(StringUtils.isBlank(tag)){
258
                            tag = "#"+n;
259
                        }
260
                        model.addElement(new LabeledValueImpl<>(tag,tag));
261
                    }
262
                    n++;
263
                }
264
            }
265
        }
266
        this.cboView.setModel(model);
267
    }
268
269
    private LayoutReportAction getReportAction(){
270
        LabeledValue<LayoutReportAction> selected = (LabeledValue<LayoutReportAction>)cboReport.getSelectedItem();
271
        if(selected == null){
272
            return null;
273
        }
274
        return selected.getValue();
275
    }
276
277
    private LayoutDocument getLayoutDocument(){
278
        LabeledValue<LayoutDocument> selected = (LabeledValue<LayoutDocument>)cboLayout.getSelectedItem();
279
        if(selected == null){
280
            return null;
281
        }
282
        return selected.getValue();
283
    }
284
285
    private String getViewTag(){
286
        LabeledValue<String> selected = (LabeledValue<String>)cboView.getSelectedItem();
287
        if(selected == null){
288
            return null;
289
        }
290
        return selected.getValue();
291
    }
292
293
    public void fetch(ConfigureReportFromLayoutParameters params){
294
        params.setLayout(this.getLayoutDocument());
295
        params.setSource(this.source);
296
        params.setIdentifier(this.txtIdentifier.getText());
297
        params.setLabel(this.txtLabel.getText());
298
299
        params.setCenterToCurrentRow(this.chkCenterToCurrentRow.isSelected());
300
        params.setZoomToCurrentRow(this.chkZoomToCurrentRow.isSelected());
301
        double bufferSize = PositiveDoubleDocumentFilter.getValue(this.txtBufferSize);
302
        params.setBufferSize(bufferSize);
303
        params.setViewTag(this.getViewTag());
304
        params.setUseIntervalPdfViewer(this.chkUseInternalPdfViewer.isSelected());
305 1601 fdiaz
        params.setHighlightRecord(this.chkHighlightRecord.isSelected());
306
        params.setHighlightSymbol(this.highlightSymbol);
307 1594 fdiaz
    }
308
309
    private void translate() {
310
        ToolsSwingManager manager = ToolsSwingLocator.getToolsSwingManager();
311
        manager.translate(lblLayout);
312
        manager.translate(lblSource);
313
        manager.translate(lblReport);
314
        manager.translate(lblIdentifier);
315
        manager.translate(lblLabel);
316 1600 fdiaz
        manager.translate(lblViewSeparator);
317
        manager.translate(lblView);
318 1594 fdiaz
        manager.translate(chkCenterToCurrentRow);
319
        manager.translate(chkZoomToCurrentRow);
320
        manager.translate(lblBufferSize);
321
        manager.translate(chkUseInternalPdfViewer);
322 1600 fdiaz
        manager.translate(txtBufferSize);
323 1601 fdiaz
        manager.translate(chkHighlightRecord);
324 1607 fdiaz
        manager.translate(btnSelectSymbol);
325 1594 fdiaz
    }
326
327
    public boolean doConfigureReportFromLayout(ConfigureReportFromLayoutParameters params) {
328
        LayoutDocument layout = params.getLayout();
329
        FeatureStore source = params.getSource();
330
        String identifier = params.getIdentifier();
331
        String label = params.getLabel();
332
333
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
334
        I18nManager i18n = ToolsLocator.getI18nManager();
335
336
        if(layout == null){
337
            dialogs.messageDialog(
338
                    i18n.getTranslation("_Layout_cant_be_null"),
339
                    null,
340
                    "_Configure_report_from_layout",
341
                    JOptionPane.WARNING_MESSAGE);
342
            return false;
343
        }
344
345
        if(source == null){
346
            dialogs.messageDialog(
347
                    i18n.getTranslation("_Source_cant_be_null"),
348
                    null,
349
                    "_Configure_report_from_layout",
350
                    JOptionPane.WARNING_MESSAGE);
351
            return false;
352
        }
353
354
        if(StringUtils.isBlank(identifier)){
355
            dialogs.messageDialog(
356
                    i18n.getTranslation("_Identifier_cant_be_null"),
357
                    null,
358
                    "_Configure_report_from_layout",
359
                    JOptionPane.WARNING_MESSAGE);
360
            return false;
361
        }
362
363
        boolean centerToCurrentRow = params.isCenterToCurrentRow();
364
        boolean zoomToCurrentRow = params.isZoomToCurrentRow();
365
        double bufferSize = params.getBufferSize();
366 1601 fdiaz
        boolean highlightRecord = params.isHighlightRecord();
367
        ISymbol highlightSymbol = params.getHighlightSymbol();
368 1594 fdiaz
        boolean useInternalPdfViewer = params.isUseIntervalPdfViewer();
369
        String viewTag = params.getViewTag();
370
371
        return doConfigureReportFromLayout(
372
                source,
373
                layout,
374
                identifier,
375
                label,
376
                centerToCurrentRow,
377
                zoomToCurrentRow,
378
                bufferSize,
379 1601 fdiaz
                highlightRecord,
380
                highlightSymbol,
381 1594 fdiaz
                viewTag,
382
                useInternalPdfViewer);
383
384
385
    }
386
387
    public boolean doConfigureReportFromLayout(
388
            FeatureStore store,
389
            LayoutDocument layout,
390
            String name,
391
            String label,
392
            boolean centerToCurrentRow,
393
            boolean zoomToCurrentRow,
394
            double bufferSize,
395 1601 fdiaz
            boolean highlightRecord,
396
            ISymbol highlightSymbol,
397 1594 fdiaz
            String viewTag,
398
            boolean useInternalPdfViewer
399
    ) {
400
        ResourcesStorage.Resource resource = null;
401
        ResourcesStorage.Resource resourceLayout = null;
402
        boolean selfContained = layout.isPersistIndependent();
403
        try {
404
            ResourcesStorage resources = store.getResourcesStorage();
405
406
            String resourceName = getResourceName(resources, name);
407
            if(resourceName == null){
408
                resourceName = getNextResourceName(resources, "report");
409
            }
410
411
            String templateName = LayoutReportActionFactory.LAYOUT_REPORT_ACTION_NAME;
412
            if(StringUtils.contains(resourceName, resources.getSeparator())){
413
                templateName = StringUtils.replaceIgnoreCase(resourceName, resources.getSeparator()+"report", resources.getSeparator()+LayoutReportActionFactory.LAYOUT_REPORT_ACTION_NAME);
414
            }
415
            JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
416
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_NAME, name);
417
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_TYPE, LayoutReportActionFactory.LAYOUT_REPORT_ACTION_NAME);
418
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_LABEL, label);
419
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_TEMPLATE_NAME, templateName);
420 1607 fdiaz
            if(highlightSymbol != null){
421
                jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_HIGHLIGHT_SYMBOL, this.toString(highlightSymbol));
422
            }
423 1594 fdiaz
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_CENTER_TO_CURRENT_ROW, centerToCurrentRow);
424
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_ZOOM_TO_CURRENT_ROW, zoomToCurrentRow);
425
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_BUFFER_SIZE, bufferSize);
426 1601 fdiaz
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_HIGHLIGHT_RECORD, highlightRecord);
427 1594 fdiaz
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_VIEW_TAG, viewTag);
428
            jsonBuilder.add(LayoutReportActionImpl.LAYOUT_REPORT_USE_INTERNAL_PDF_VIEWER, useInternalPdfViewer);
429
430
            resource = resources.getResource(resourceName);
431
            IOUtils.write(jsonBuilder.toString(), resource.asOutputStream(), StandardCharsets.UTF_8);
432
433
            resourceLayout = resources.getResource(templateName);
434
            PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
435
            layout.setPersistIndependent(true);
436
            PersistentState persistentState = persistenceManager.getState(layout.getMainWindow());
437
            persistenceManager.saveState(persistentState, resourceLayout.asOutputStream());
438
            ((JComponent)dialog).setVisible(false);
439
            return true;
440
        } catch (Exception ex) {
441
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
442
            I18nManager i18n = ToolsLocator.getI18nManager();
443
            dialogs.messageDialog(
444
                    i18n.getTranslation("_Cant_configure_report_from_layout"),
445
                    null,
446
                    "_Configure_report_from_layout",
447
                    JOptionPane.WARNING_MESSAGE);
448
            return false;
449
        } finally {
450
            layout.setPersistIndependent(selfContained);
451
            IOUtils.closeQuietly(resource);
452
            IOUtils.closeQuietly(resourceLayout);
453
        }
454
455
    }
456
457 1601 fdiaz
    private String toString(ISymbol symbol){
458
        try {
459 1607 fdiaz
            if(symbol == null){
460
                return null;
461
            }
462 1601 fdiaz
            PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
463
            PersistentState state = persistenceManager.getState(symbol);
464
            ByteArrayOutputStream out = new ByteArrayOutputStream();
465
            persistenceManager.saveState(state, out);
466
            return Hex.encodeHexString(out.toByteArray());
467
        } catch (Exception ex) {
468
            throw new RuntimeException("Can't persist symbol", ex);
469
        }
470
    }
471
472 1594 fdiaz
    private String getNextResourceName(ResourcesStorage resources, String resourceName){
473
        List<ResourcesStorage.Resource> reports = resources.getResources(resourceName);
474
        if(reports == null || reports.isEmpty()){
475
            return resourceName;
476
        }
477
        int n = -1;
478
        for (ResourcesStorage.Resource report : reports) {
479
            if(StringUtils.contains(report.getName(), resources.getSeparator())){
480
                String[] s = StringUtils.split(report.getName(), resources.getSeparator());
481
                n = Math.max(n, Integer.parseInt(s[0]));
482
            } else {
483
                n=0;
484
            }
485
        }
486
487
        if (n < 0) {
488
            return resourceName;
489
        }
490
491
        n++;
492
        return String.valueOf(n) + resources.getSeparator() + resourceName;
493
494
495
    }
496
497
    private String getResourceName(ResourcesStorage resources, String reportName) {
498
        try {
499
            if (resources != null) {
500
                List<ResourcesStorage.Resource> reportsResources = resources.getResources("report");
501
                if (reportsResources != null && !reportsResources.isEmpty()) {
502
                    for (ResourcesStorage.Resource resource : reportsResources) {
503
                        InputStream is = null;
504
                        try {
505
                            is = resource.asInputStream();
506
                            JsonObject json = javax.json.Json.createReader(is).readObject();
507
                            String name = json.getString(LayoutReportActionImpl.LAYOUT_REPORT_NAME, null);
508
                            if(StringUtils.equalsIgnoreCase(name, reportName)){
509
                                return resource.getName();
510
                            }
511
                        } catch (Exception ex) {
512
                            LOGGER.warn("Can't load report form resource (" + resource.getURL() + ")", ex);
513
                        } finally {
514
                            IOUtils.closeQuietly(is);
515
                        }
516
                        DisposeUtils.disposeQuietly(resource);
517
                    }
518
                }
519
            }
520
        } finally {
521
            DisposeUtils.disposeQuietly(resources);
522
        }
523
        return null;
524
    }
525
526
527
    private void doChangeReport() {
528
        LayoutReportAction report = getReportAction();
529
        if(report == null){
530
            this.txtIdentifier.setText("");
531
            this.txtLabel.setText("");
532
        } else {
533
            this.txtIdentifier.setText(report.getReportName());
534
            this.txtLabel.setText(report.getReportLabel());
535
            this.chkCenterToCurrentRow.setSelected(report.isCenterToCurrentRow());
536
            this.chkZoomToCurrentRow.setSelected(report.isZoomToCurrentRow());
537
            PositiveDoubleDocumentFilter.setValue(this.txtBufferSize,report.getBufferSize());
538 1601 fdiaz
            this.chkHighlightRecord.setSelected(report.isHighlightRecord());
539 1594 fdiaz
            ListElement.setSelected(this.cboView, report.getViewTag());
540
            this.chkUseInternalPdfViewer.setSelected(report.isUseInternalPdfViewer());
541
        }
542
        doUpdateComponents();
543
    }
544
545
    void setDialog(Dialog dialog) {
546
        this.dialog = dialog;
547
    }
548
549
550
551
}