Statistics
| Revision:

gvsig-projects-pool / org.gvsig.online / trunk / org.gvsig.online / org.gvsig.online.swing / org.gvsig.online.swing.impl / src / main / java / org / gvsig / online / swing / impl / simplesearch / SimpleSearchImpl.java @ 9526

History | View | Annotate | Download (13.5 KB)

1
/*
2
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
3
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
4
 */
5
package org.gvsig.online.swing.impl.simplesearch;
6

    
7
import java.awt.event.ComponentAdapter;
8
import java.awt.event.ComponentEvent;
9
import java.util.Collections;
10
import java.util.Iterator;
11
import java.util.List;
12
import javax.swing.JComponent;
13
import javax.swing.JOptionPane;
14
import javax.swing.SwingUtilities;
15
import javax.swing.table.TableModel;
16
import org.apache.commons.lang3.mutable.MutableObject;
17
import org.cresques.cts.ICoordTrans;
18
import org.cresques.cts.IProjection;
19
import org.gvsig.expressionevaluator.Expression;
20
import org.gvsig.fmap.crs.CRSFactory;
21
import org.gvsig.fmap.dal.exception.DataException;
22
import org.gvsig.fmap.dal.feature.Feature;
23
import org.gvsig.fmap.dal.feature.FeatureSet;
24
import org.gvsig.fmap.dal.feature.FeatureStore;
25
import org.gvsig.fmap.dal.feature.FeatureType;
26
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
27
import org.gvsig.fmap.dal.swing.DALSwingLocator;
28
import org.gvsig.fmap.dal.swing.DataSwingManager;
29
import org.gvsig.fmap.geom.Geometry;
30
import org.gvsig.fmap.geom.GeometryLocator;
31
import org.gvsig.fmap.geom.primitive.Envelope;
32
import org.gvsig.online.lib.api.OnlineLocator;
33
import org.gvsig.online.lib.api.OnlineManager;
34
import static org.gvsig.online.lib.api.OnlineManager.ERR_EXCEPTION;
35
import static org.gvsig.online.lib.api.OnlineManager.ERR_OK;
36
import org.gvsig.online.lib.api.workingcopy.OnlineEntity;
37
import org.gvsig.online.lib.api.workingcopy.OnlineWorkingcopy;
38
import org.gvsig.online.swing.api.OnlineSwingLocator;
39
import org.gvsig.online.swing.api.OnlineSwingServices;
40
import org.gvsig.online.swing.impl.MessageStatus;
41
import org.gvsig.tools.ToolsLocator;
42
import org.gvsig.tools.dispose.DisposeUtils;
43
import org.gvsig.tools.i18n.I18nManager;
44
import org.gvsig.tools.swing.api.ToolsSwingLocator;
45
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
46
import org.gvsig.tools.task.SimpleTaskStatus;
47
import static org.gvsig.tools.task.SimpleTaskStatus.message;
48
import org.slf4j.LoggerFactory;
49

    
50
/**
51
 *
52
 * @author fdiaz
53
 */
54
public class SimpleSearchImpl {
55

    
56
    public static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SimpleSearchImpl.class);
57
    
58
    private final OnlineWorkingcopy wc;
59
    private OnlineEntity entity;
60
    private FeatureType featureType;
61
    private FeaturePagingHelper feats;
62
    private Envelope fullEnv;
63
    private final FeatureStore store;
64
    private Expression lastFilter;
65
    private boolean processing;
66

    
67
    public SimpleSearchImpl(FeatureStore store) {
68
        this(store, null);
69
    }
70
    
71
    public SimpleSearchImpl(FeatureStore store, JComponent panel) {
72
        OnlineManager manager = OnlineLocator.getOnlineManager();
73
        this.store = store;
74
        DisposeUtils.bind(this.store);
75
        this.wc = manager.getWorkingcopy(store);
76
        if (wc != null) {
77
            this.entity = wc.getEntity(store.getName());
78
            this.featureType = wc.getFeatureType(this.entity.getEntityName());
79
        }
80
        this.processing = false;
81

    
82
        if(panel != null) {
83
            panel.addComponentListener(new ComponentAdapter() {
84
                @Override
85
                public void componentHidden(ComponentEvent e) {
86
                    dispose();
87
                }
88
                
89
            });
90
        }
91
    }
92
    
93
    public void dispose() {
94
        DisposeUtils.disposeQuietly(store);
95
        DisposeUtils.disposeQuietly(wc);
96
        DisposeUtils.disposeQuietly(feats);
97
    }
98
    
99
    public long count(Expression filter) {
100
        return count(filter, null);
101
    }
102
    
103
    public long count(Expression filter, SimpleTaskStatus status) {
104
        if(status == null){
105
            status = SimpleTaskStatus.FAKE_STATUS;
106
        }
107
        long count = wc.simpleSearchCount(this.entity.getEntityName(), filter, status);
108
        return count;
109
    }
110
    
111
    public boolean areThereTooManyResults(Expression filter) {
112
        return areThereTooManyResults(filter, null);
113
    }
114
    
115
    public boolean areThereTooManyResults(Expression filter, SimpleTaskStatus status) {
116
        if(status == null){
117
            status = SimpleTaskStatus.FAKE_STATUS;
118
        }
119
        int minResultForAlert = wc.getMinResultForAlert();
120
        return (count(filter, status) > minResultForAlert);
121
    }
122
    
123
    public List<Feature> search(Expression filter) {
124
        return search(filter, null);
125
    }
126
    
127
    public List<Feature> search(Expression filter, SimpleTaskStatus status) {
128
        if (status == null) {
129
            status = SimpleTaskStatus.FAKE_STATUS;
130
        }
131
        this.fullEnv = null;
132
        this.lastFilter = null;
133
        if (this.feats != null) {
134
            DisposeUtils.disposeQuietly(feats);
135
            feats = null;
136
        }
137
        this.feats = wc.simpleSearch(this.entity.getEntityName(), filter, status);
138
        this.lastFilter = filter;
139
        return this.feats.asList();
140
    }
141
    
142
    protected boolean isSearched() {
143
        return this.lastFilter != null;
144
    }
145
    
146
    public int download() {
147
        return download(null);
148
    }
149
    
150
    public int download(SimpleTaskStatus status) {
151
        if(!isSearched()){
152
            return ERR_OK;
153
        }
154
        if(status == null){
155
            status = SimpleTaskStatus.FAKE_STATUS;
156
        }
157
        try {
158
            IProjection proj4326 = CRSFactory.getCRS("EPSG:4326");
159
            ICoordTrans ct = proj4326.getCT(this.entity.getCRSAsProjection());
160

    
161
            this.fullEnv = GeometryLocator.getGeometryManager().createEnvelope(Geometry.SUBTYPES.GEOM2D);
162
            Iterator<Feature> it = feats.iterator();
163
            Iterator<Geometry> geoms = new Iterator<Geometry>() {
164
                @Override
165
                public boolean hasNext() {
166
                    return it.hasNext();
167
                }
168
                
169
                @Override
170
                public Geometry next() {
171
                    Geometry geom = it.next().getDefaultGeometry();
172
                    geom.reProject(ct);
173
                    fullEnv.add(geom);
174
                    return geom;
175
                }
176
            };
177
            
178
            int n = wc.download(entity.getEntityName(), geoms, status);
179
            
180
            SwingUtilities.invokeLater(() -> {
181
                setSelection();
182
                OnlineSwingServices services = OnlineSwingLocator.getOnlineSwingManager().getDefaultServices();
183
                services.refreshDocument(getFeatureStore());
184
            });
185

    
186
            return n;
187
        } catch (Exception ex) {
188
            LOGGER.warn("Can't download.", ex);
189
            return ERR_EXCEPTION;
190
        }
191
    }
192
    
193
    public OnlineWorkingcopy getWorkingcopy() {
194
        return this.wc;
195
    }
196
    
197
    public Envelope getEnvelope(SimpleTaskStatus status) {
198
        if (fullEnv == null) {
199
            try {
200
                IProjection proj4326 = CRSFactory.getCRS("EPSG:4326");
201
                ICoordTrans ct = proj4326.getCT(this.entity.getCRSAsProjection());
202

    
203
                this.fullEnv = GeometryLocator.getGeometryManager().createEnvelope(Geometry.SUBTYPES.GEOM2D);
204
                Iterator<Feature> it = feats.iterator();
205
                Iterator<Geometry> geoms = new Iterator<Geometry>() {
206
                    @Override
207
                    public boolean hasNext() {
208
                        return it.hasNext();
209
                    }
210

    
211
                    @Override
212
                    public Geometry next() {
213
                        Geometry geom = it.next().getDefaultGeometry();
214
                        geom.reProject(ct);
215
                        fullEnv.add(geom);
216
                        return geom;
217
                    }
218
                };
219
                status.message("_Calculating_envelope");
220
                status.setRangeOfValues(0, feats.size64());
221
                while(geoms.hasNext()) {
222
                    status.incrementCurrentValue();
223
                    geoms.next();
224
                }
225
            } catch (Exception ex) {
226
                LOGGER.warn("Can't get envelope.", ex);
227
            }
228

    
229
        }
230
        return this.fullEnv;
231
    }
232
    
233
    public FeatureType getFeatureType() {
234
        return this.featureType;
235
    }
236
    
237
    public boolean isEmpty() {
238
        return this.featureType == null;
239
    }
240

    
241
    FeatureStore getFeatureStore() {
242
        return store;
243
    }
244
    
245
    public TableModel createEmptyTableModel() {
246
        DataSwingManager swingManager = DALSwingLocator.getDataSwingManager();
247
        return swingManager.createSimpleFeaturesTableModel(
248
            this.getFeatureType(),
249
            null,
250
            null
251
        );
252
    }
253
    
254
    public TableModel createTableModel() {
255
        if(feats == null) {
256
            return createEmptyTableModel();
257
        }
258
        DataSwingManager swingManager = DALSwingLocator.getDataSwingManager();
259
        return swingManager.createSimpleFeaturesTableModel(
260
            this.getFeatureType(),
261
            null,
262
            this.feats.asList()
263
        );
264
    }
265
  
266
    public void zoom() {
267
        this.zoom(SimpleTaskStatus.FAKE_STATUS);
268
    }
269
    
270
    public void zoom(SimpleTaskStatus status) {
271
        Envelope env = this.getEnvelope(status);
272
        if(env == null){
273
            return;
274
        }
275
        try {
276
            OnlineSwingServices services = OnlineSwingLocator.getOnlineSwingManager().getDefaultServices();
277
            if (!env.isEmpty()) {
278
                services.zoomActiveViewToGeometry(env.getGeometry().buffer(100));
279
            }
280
        } catch (Exception ex) {
281
            LOGGER.warn("Can't zoom to results.", ex);
282
        }
283

    
284
    }
285

    
286
    public void setSelection() {
287
        FeatureSet set = null;
288
        try {
289
            set = this.getFeatureStore().getFeatureSet(lastFilter);
290
            this.getFeatureStore().setSelection(set);
291
        } catch (DataException ex) {
292
            LOGGER.warn("Can't set selection", ex);
293
        }
294
    }
295
    
296
    public Thread runSearchTask(Expression filter, Runnable postProcessingAction, MessageStatus message) {
297
        SimpleTaskStatus status = message.createTaskStatus("_Search");
298
        message.setVisible(true);
299
        message.clear();
300
        I18nManager i18n = ToolsLocator.getI18nManager();
301
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
302
        Thread task = new Thread(() -> {
303
            this.processing = true;
304
            try {
305
                if (this.areThereTooManyResults(filter)) {
306
                    int n = dialogs.confirmDialog(
307
                        i18n.getTranslation("_Search_returns_too_many_results")
308
                        + "\n"
309
                        + i18n.getTranslation("_Do_you_want_to_continue_anyway"),
310
                        i18n.getTranslation("_Upload"),
311
                        JOptionPane.YES_NO_OPTION,
312
                        JOptionPane.QUESTION_MESSAGE
313
                    );
314
                    if (n != JOptionPane.YES_OPTION) {
315
                        return;
316
                    }
317

    
318
                }
319
                this.search(filter, status);
320
            } catch (Exception ex) {
321

    
322
            } finally {
323
                if (postProcessingAction != null) {
324
                    SwingUtilities.invokeLater(() -> {
325
                        postProcessingAction.run();
326
                    });
327
                }
328
                message.setVisible(false);
329
                processing = false;
330
            }
331
        }, "OnlineSimpleSearch");
332
        
333
        this.processing = true;
334
        task.start();
335

    
336
        return task;
337
        
338
    }
339

    
340
    public Thread runDownloadTask(Runnable postProcessingAction, MessageStatus message) {
341
        if(!isSearched()){
342
            return null;
343
        }
344
        SimpleTaskStatus status = message.createTaskStatus("_Download");
345
        message.setVisible(true);
346
        message.clear();
347
        Thread task = new Thread(() -> {
348
            this.processing = true;
349
            try {
350
                this.download(status);
351
            } catch (Exception ex) {
352
                //FIXME: 
353

    
354
            } finally {
355
                if (postProcessingAction != null) {
356
                    SwingUtilities.invokeLater(() -> {
357
                        postProcessingAction.run();
358
                    });
359
                }
360
                message.setVisible(false);
361
                processing = false;
362
            }
363
        }, "OnlineSimpleSearchDownload");
364
        
365
        this.processing = true;
366
        task.start();
367

    
368
        return task;
369
        
370
    }
371

    
372
    public Thread runCalculateEnvelopeTask(Runnable postProcessingAction, MessageStatus message) {
373
        if(!isSearched()){
374
            return null;
375
        }
376
        SimpleTaskStatus status = message.createTaskStatus("_Calculate_envelope");
377
        message.setVisible(true);
378
        message.clear();
379
        
380
        Thread task = new Thread(() -> {
381
            this.processing = true;
382
            try {
383
                this.getEnvelope(status);
384
            } catch (Exception ex) {
385
                //FIXME: 
386

    
387
            } finally {
388
                if (postProcessingAction != null) {
389
                    SwingUtilities.invokeLater(() -> {
390
                        postProcessingAction.run();
391
                    });
392
                }
393
                message.setVisible(false);
394
                processing = false;
395
            }
396
        }, "OnlineSimpleSearchCalculateEnvelope");
397
        
398
        this.processing = true;
399
        task.start();
400

    
401
        return task;
402
        
403
    }
404

    
405

    
406
    public boolean isProcessing() {
407
        return this.processing;
408
    }
409
    
410
    public boolean canDownload(MutableObject<String> message) {
411
        return this.getWorkingcopy().canDownload(
412
            message, 
413
            Collections.singletonList(this.entity.getEntityCode())
414
        );
415
    }
416
}