Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / SelectByAttributesExtension.java @ 43987

History | View | Annotate | Download (14.4 KB)

1 40558 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40558 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6 41248 jjdelcerro
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10 40435 jjdelcerro
 *
11 41248 jjdelcerro
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15 40435 jjdelcerro
 *
16 41248 jjdelcerro
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 40435 jjdelcerro
 *
20 41248 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40435 jjdelcerro
 */
23
package org.gvsig.app.extension;
24
25 43987 jjdelcerro
import java.awt.BorderLayout;
26
import java.awt.FlowLayout;
27
import java.awt.event.ActionEvent;
28 40435 jjdelcerro
import java.util.Iterator;
29 43987 jjdelcerro
import javax.swing.AbstractAction;
30
import javax.swing.JButton;
31 40435 jjdelcerro
32
import javax.swing.JOptionPane;
33 43987 jjdelcerro
import javax.swing.JPanel;
34 40435 jjdelcerro
35
import org.gvsig.andami.IconThemeHelper;
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.andami.messages.NotificationManager;
38
import org.gvsig.andami.plugins.Extension;
39 40955 jldominguez
import org.gvsig.app.ApplicationLocator;
40 41248 jjdelcerro
import org.gvsig.app.ApplicationManager;
41 40435 jjdelcerro
import org.gvsig.app.gui.filter.ExpressionListener;
42
import org.gvsig.app.gui.filter.FilterDialog;
43
import org.gvsig.app.project.documents.view.ViewDocument;
44 41264 jjdelcerro
import org.gvsig.app.project.documents.view.gui.IView;
45 43987 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
46
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingLocator;
47
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
48
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
49
import org.gvsig.expressionevaluator.swing.Element;
50 40435 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
51
import org.gvsig.fmap.dal.DataManager;
52
import org.gvsig.fmap.dal.exception.DataException;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureQuery;
55
import org.gvsig.fmap.dal.feature.FeatureSelection;
56
import org.gvsig.fmap.dal.feature.FeatureSet;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58 43987 jjdelcerro
import org.gvsig.fmap.dal.swing.DataSwingManager;
59 40435 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.FLayer;
60
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
61 40955 jldominguez
import org.gvsig.i18n.Messages;
62 43987 jjdelcerro
import org.gvsig.tools.ToolsLocator;
63
import org.gvsig.tools.i18n.I18nManager;
64
import org.gvsig.tools.swing.api.ToolsSwingLocator;
65
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
66 40435 jjdelcerro
import org.gvsig.utils.exceptionHandling.ExceptionListener;
67
68
/**
69
 * Extensi?n que abre un di?logo para poder hacer un filtro de una capa o tabla.
70 41248 jjdelcerro
 *
71 40435 jjdelcerro
 * @author Vicente Caballero Navarro
72
 */
73 43987 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
74 41641 jjdelcerro
public class SelectByAttributesExtension extends Extension implements ExpressionListener {
75 40435 jjdelcerro
76
    protected FeatureStore featureStore = null;
77
    private String filterTitle;
78
79 43987 jjdelcerro
    @Override
80 40435 jjdelcerro
    public void initialize() {
81 41641 jjdelcerro
        IconThemeHelper.registerIcon("action", "selection-by-attributes", this);
82 40435 jjdelcerro
    }
83
84 43987 jjdelcerro
    @Override
85 40435 jjdelcerro
    public void execute(String actionCommand) {
86 41264 jjdelcerro
        ApplicationManager application = ApplicationLocator.getManager();
87
88
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
89
        if (view == null) {
90
            return;
91
        }
92 43987 jjdelcerro
        if ("selection-by-attributes-layer2".equals(actionCommand)) {
93
            ViewDocument document = view.getViewDocument();
94
95 41248 jjdelcerro
            FLayer layer = document.getMapContext().getLayers().getActives()[0];
96 41744 jjdelcerro
            filterTitle = layer.getName();
97 41248 jjdelcerro
            featureStore = ((FLyrVect) layer).getFeatureStore();
98
            document.setModified(true);
99 43987 jjdelcerro
            doSelectByAttributes2(filterTitle, featureStore);
100
101
        } else if ("selection-by-attributes-layer".equals(actionCommand)) {
102
            ViewDocument document = view.getViewDocument();
103
104
            FLayer layer = document.getMapContext().getLayers().getActives()[0];
105
            filterTitle = layer.getName();
106
            featureStore = ((FLyrVect) layer).getFeatureStore();
107
            document.setModified(true);
108 40435 jjdelcerro
            doExecute();
109
        }
110
    }
111
112
    /**
113
     * "execute" method action.
114 41248 jjdelcerro
     *
115 40435 jjdelcerro
     */
116
    protected void doExecute() {
117
        FilterDialog dlg = new FilterDialog(filterTitle);
118
        dlg.addExpressionListener(this);
119
        dlg.addExceptionListener(new ExceptionListener() {
120
121 43987 jjdelcerro
            @Override
122 40435 jjdelcerro
            public void exceptionThrown(Throwable t) {
123
                NotificationManager.addError(t.getMessage(), t);
124
            }
125
        });
126
        dlg.setModel(featureStore);
127
        PluginServices.getMDIManager().addWindow(dlg);
128
    }
129
130 43987 jjdelcerro
    @Override
131 40435 jjdelcerro
    public boolean isEnabled() {
132 41248 jjdelcerro
        return true;
133 40435 jjdelcerro
    }
134
135 43987 jjdelcerro
    @Override
136 40435 jjdelcerro
    public boolean isVisible() {
137 41248 jjdelcerro
        ApplicationManager application = ApplicationLocator.getManager();
138 40435 jjdelcerro
139 41264 jjdelcerro
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
140
        if (view == null) {
141 40435 jjdelcerro
            return false;
142
        }
143 41264 jjdelcerro
        ViewDocument document = view.getViewDocument();
144 41248 jjdelcerro
        return document.getMapContext().hasActiveVectorLayers();
145 40435 jjdelcerro
    }
146
147
    // By Pablo: if no filter expression -> no element selected
148 43987 jjdelcerro
    @Override
149 40435 jjdelcerro
    public void newSet(String expression) throws DataException {
150
        if (!this.filterExpressionFromWhereIsEmpty(expression)) {
151
            FeatureSet set = null;
152
            try {
153
                set = doSet(expression);
154
155
                if (set == null) {
156
                    // throw new RuntimeException("Not a 'where' clause?");
157
                    return;
158
                }
159
                featureStore.setSelection(set);
160
161
            } catch (Exception e) {
162 41248 jjdelcerro
163 40955 jldominguez
                JOptionPane.showMessageDialog(
164 41248 jjdelcerro
                        ApplicationLocator.getManager().getRootComponent(),
165
                        Messages.getText("expresion_error") + ":\n"
166 40955 jldominguez
                        + getLastMessage(e),
167 41248 jjdelcerro
                        Messages.getText("expresion_error"),
168
                        JOptionPane.ERROR_MESSAGE);
169 40435 jjdelcerro
            } finally {
170
                if (set != null) {
171
                    set.dispose();
172
                }
173
            }
174
        } else {
175
            // By Pablo: if no expression -> no element selected
176
            featureStore.getFeatureSelection().deselectAll();
177
        }
178
    }
179
180
    private FeatureSet doSet(String expression) throws DataException {
181
        FeatureQuery query = featureStore.createFeatureQuery();
182
        DataManager manager = DALLocator.getDataManager();
183
        query.setFilter(manager.createExpresion(expression));
184
        return featureStore.getFeatureSet(query);
185
    }
186
187 43987 jjdelcerro
    @Override
188 40435 jjdelcerro
    public void addToSet(String expression) throws DataException {
189
        // By Pablo: if no filter expression -> don't add more elements to set
190
        if (!this.filterExpressionFromWhereIsEmpty(expression)) {
191
            FeatureSet set = null;
192
            try {
193
                set = doSet(expression);
194
195
                if (set == null) {
196
                    // throw new RuntimeException("Not a 'where' clause?");
197
                    return;
198
                }
199
                featureStore.getFeatureSelection().select(set);
200
            } finally {
201
                if (set != null) {
202
                    set.dispose();
203
                }
204
            }
205
        }
206
    }
207
208 43987 jjdelcerro
    @Override
209 40435 jjdelcerro
    public void fromSet(String expression) throws DataException {
210
        // By Pablo: if no filter expression -> no element selected
211
        try {
212
            if (!this.filterExpressionFromWhereIsEmpty(expression)) {
213
                // NotificationManager.showMessageInfo("Falta por implementar",
214
                // null);
215
216 43987 jjdelcerro
                FeatureSet set;
217 40435 jjdelcerro
                set = doSet(expression);
218
219
                if (set == null) {
220
                    throw new RuntimeException("Not a 'where' clause?");
221
                }
222
223 41248 jjdelcerro
                FeatureSelection oldSelection
224
                        = featureStore.getFeatureSelection();
225 40435 jjdelcerro
226 41248 jjdelcerro
                FeatureSelection newSelection
227
                        = featureStore.createFeatureSelection();
228 40435 jjdelcerro
                Iterator iterator = set.iterator();
229
                while (iterator.hasNext()) {
230
                    Feature feature = (Feature) iterator.next();
231
                    if (oldSelection.isSelected(feature)) {
232
                        newSelection.select(feature);
233
                    }
234
                }
235
                featureStore.setSelection(newSelection);
236
                set.dispose();
237
238
            } else {
239
                // By Pablo: if no expression -> no element selected
240
                featureStore.getFeatureSelection().deselectAll();
241
            }
242
        } catch (DataException e) {
243
            NotificationManager.addError(e);
244
        }
245
246
    }
247
248
    /**
249
     * Returns true if the WHERE subconsultation of the filterExpression is
250
     * empty ("")
251 41248 jjdelcerro
     *
252 40435 jjdelcerro
     * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
253 41248 jjdelcerro
     * @param expression An string
254 40435 jjdelcerro
     * @return A boolean value
255
     */
256
    private boolean filterExpressionFromWhereIsEmpty(String expression) {
257 41248 jjdelcerro
258 40435 jjdelcerro
        if (expression == null) {
259
            return true;
260
        }
261 41248 jjdelcerro
262 40435 jjdelcerro
        String subExpression = expression.trim();
263 41248 jjdelcerro
264 40435 jjdelcerro
        if (subExpression.length() == 0) {
265
            return true;
266
        }
267 41248 jjdelcerro
268 40435 jjdelcerro
        int pos;
269
270
        // Remove last ';' if exists
271
        if (subExpression.charAt(subExpression.length() - 1) == ';') {
272 41248 jjdelcerro
            subExpression
273
                    = subExpression.substring(0, subExpression.length() - 1).trim();
274 40435 jjdelcerro
        }
275
276
        // If there is no 'where' clause
277
        if ((pos = subExpression.indexOf("where")) == -1) {
278
            return false;
279
        }
280
281
        // If there is no subexpression in the WHERE clause -> true
282 41248 jjdelcerro
        // + 5 is the length of 'where'
283
        subExpression = subExpression.substring(pos + 5, subExpression.length()).trim();
284 40435 jjdelcerro
        if (subExpression.length() == 0) {
285
            return true;
286
        } else {
287
            return false;
288
        }
289
    }
290 41248 jjdelcerro
291 40955 jldominguez
    private String getLastMessage(Throwable ex) {
292 41248 jjdelcerro
293 40955 jldominguez
        Throwable p = ex;
294
        while (p.getCause() != null && p.getCause() != p) {
295
            p = p.getCause();
296
        }
297
        return p.getMessage();
298 41248 jjdelcerro
    }
299 43987 jjdelcerro
300
    private void doSelectByAttributes2(String title, final FeatureStore store) {
301
        I18nManager i18n = ToolsLocator.getI18nManager();
302
        WindowManager windowManager = ToolsSwingLocator.getWindowManager();
303
        ExpressionEvaluatorSwingManager swingManager = ExpressionEvaluatorSwingLocator.getManager();
304
305
        final JPanel panel = new JPanel();
306
        panel.setLayout(new BorderLayout());
307
308
        final JExpressionBuilder builder = swingManager.createJExpressionBuilder();
309
        builder.addSymbolTable(DataManager.FEATURE_SYMBOL_TABLE);
310
        Element element = swingManager.createElement(
311
                DataSwingManager.FEATURE_STORE_EXPRESSION_ELEMENT,
312
                builder,
313
                store
314
        );
315
        if (element != null) {
316
            builder.getElements().add(element);
317
        }
318
        panel.add(builder.asJComponent(), BorderLayout.CENTER);
319
        JPanel buttons = new JPanel();
320
        buttons.setLayout(new FlowLayout(FlowLayout.RIGHT, 4, 4));
321
        buttons.add(new JButton(new AbstractAction(i18n.getTranslation("_Set_selection")) {
322
            @Override
323
            public void actionPerformed(ActionEvent e) {
324
                doSetSelection(store, builder.getExpression());
325
            }
326
        }));
327
        buttons.add(new JButton(new AbstractAction(i18n.getTranslation("_Add_to_selection")) {
328
            @Override
329
            public void actionPerformed(ActionEvent e) {
330
                doAddToSelection(store, builder.getExpression());
331
            }
332
        }));
333
        buttons.add(new JButton(new AbstractAction(i18n.getTranslation("_Filter_selection")) {
334
            @Override
335
            public void actionPerformed(ActionEvent e) {
336
                doFilterSelection(store, builder.getExpression());
337
            }
338
        }));
339
        buttons.add(new JButton(new AbstractAction(i18n.getTranslation("_Close")) {
340
            @Override
341
            public void actionPerformed(ActionEvent e) {
342
                panel.setVisible(false);
343
            }
344
        }));
345
        panel.add(buttons, BorderLayout.SOUTH);
346
347
        windowManager.showWindow(
348
                panel,
349
                title,
350
                WindowManager.MODE.WINDOW
351
        );
352
353
    }
354
355
    private void doSetSelection(FeatureStore store, Expression expression) {
356
        try {
357
            DataManager manager = DALLocator.getDataManager();
358
359
            FeatureSelection currentSelection = store.getFeatureSelection();
360
            FeatureQuery query = store.createFeatureQuery();
361
            query.setFilter(manager.createExpresion(expression));
362
            FeatureSet selection = store.getFeatureSet(query);
363
            currentSelection.deselectAll();
364
            currentSelection.select(selection);
365
        } catch (Exception ex) {
366
            logger.warn("Can't build selecction from filter expression.", ex);
367
        }
368
    }
369
370
    private void doAddToSelection(FeatureStore store, Expression expression) {
371
        try {
372
            DataManager manager = DALLocator.getDataManager();
373
374
            FeatureSelection currentSelection = store.getFeatureSelection();
375
            FeatureQuery query = store.createFeatureQuery();
376
            query.setFilter(manager.createExpresion(expression));
377
            FeatureSet selection = store.getFeatureSet(query);
378
            currentSelection.select(selection);
379
        } catch (Exception ex) {
380
            logger.warn("Can't build selecction from filter expression.", ex);
381
        }
382
    }
383
384
    private void doFilterSelection(FeatureStore store, Expression expression) {
385
        try {
386
            DataManager manager = DALLocator.getDataManager();
387
388
            FeatureSelection currentSelection = store.getFeatureSelection();
389
            FeatureQuery query = store.createFeatureQuery();
390
            query.setFilter(manager.createExpresion(expression));
391
            FeatureSet set = store.getFeatureSet(query);
392
            FeatureSelection newSelection = store.createFeatureSelection();
393
            for (Feature feature : set) {
394
                if( currentSelection.isSelected(feature) ) {
395
                    newSelection.select(feature);
396
                }
397
            }
398
            store.setSelection(newSelection);
399
        } catch (Exception ex) {
400
            logger.warn("Can't build selecction from filter expression.", ex);
401
        }
402
    }
403
404 41248 jjdelcerro
}