Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app.document.table.app / org.gvsig.app.document.table.app.mainplugin / src / main / java / org / gvsig / app / extension / TableFieldOperations.java @ 45739

History | View | Annotate | Download (9.99 KB)

1 40558 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40558 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 40435 jjdelcerro
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40558 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * of the License, or (at your option) any later version.
10 40558 jjdelcerro
 *
11 40435 jjdelcerro
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15 40558 jjdelcerro
 *
16 40435 jjdelcerro
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18 40558 jjdelcerro
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 40435 jjdelcerro
 * MA  02110-1301, USA.
20 40558 jjdelcerro
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.app.extension;
25
26 40870 jldominguez
import java.util.HashSet;
27
import java.util.Iterator;
28
import java.util.Set;
29
import javax.swing.JOptionPane;
30 40435 jjdelcerro
import org.gvsig.andami.IconThemeHelper;
31
import org.gvsig.andami.PluginServices;
32
import org.gvsig.andami.plugins.Extension;
33
import org.gvsig.andami.ui.mdiManager.IWindow;
34 40870 jldominguez
import org.gvsig.app.ApplicationLocator;
35 40435 jjdelcerro
import org.gvsig.app.project.documents.table.gui.FeatureTableDocumentPanel;
36 45426 fdiaz
import org.gvsig.fmap.dal.DALLocator;
37 40435 jjdelcerro
import org.gvsig.fmap.dal.exception.DataException;
38 40870 jldominguez
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureQuery;
40
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
41
import org.gvsig.fmap.dal.feature.FeatureSelection;
42
import org.gvsig.fmap.dal.feature.FeatureSet;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.mapcontrol.dal.feature.swing.FeatureTable;
45 40435 jjdelcerro
import org.gvsig.fmap.mapcontrol.dal.feature.swing.table.ConfigurableFeatureTableModel;
46 40870 jldominguez
import org.gvsig.i18n.Messages;
47
import org.gvsig.tools.dispose.DisposableIterator;
48 40435 jjdelcerro
import org.gvsig.tools.exception.BaseException;
49 45308 fdiaz
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51 40435 jjdelcerro
52
/**
53 40870 jldominguez
 * Operations regarding order and duplicated values.
54 40435 jjdelcerro
 *
55
 * @author Vicente Caballero Navarro
56
 */
57
public class TableFieldOperations extends Extension {
58
59 40870 jldominguez
    private static Logger logger =
60
        LoggerFactory.getLogger(TableFieldOperations.class);
61 40435 jjdelcerro
    private FeatureTableDocumentPanel table = null;
62
63
    /**
64
     * @see org.gvsig.andami.plugins.IExtension#initialize()
65
     */
66
    public void initialize() {
67
        IconThemeHelper.registerIcon("action", "table-order-desc", this);
68
        IconThemeHelper.registerIcon("action", "table-order-asc", this);
69 40870 jldominguez
        IconThemeHelper.registerIcon("action", "selection-duplicates", this);
70 40435 jjdelcerro
    }
71
72
    /**
73
     * @see org.gvsig.andami.plugins.IExtension#execute(java.lang.String)
74
     */
75
    public void execute(String actionCommand) {
76
        doExecute(actionCommand, table);
77
    }
78
79
    /**
80
     * "execute" method acction
81
     *
82
     * @param actionCommand
83
     *            The acction command that executes this method
84
     * @param table
85
     *            Table to operate
86
     */
87
    protected void doExecute(String actionCommand,
88
        FeatureTableDocumentPanel table) {
89
        // FIXME
90
        ConfigurableFeatureTableModel cftm =
91
            table.getTablePanel().getTableModel();
92
        try {
93
            if ("table-order-asc".equals(actionCommand)) {
94
                cftm.orderByColumn(table.getTablePanel().getTable()
95
                    .getSelectedColumnsAttributeDescriptor()[0].getName(), true);
96 40870 jldominguez
97
                // Mark as modified:
98
                table.getModel().setModified(true);
99
100
            } else {
101 40435 jjdelcerro
                if ("table-order-desc".equals(actionCommand)) {
102
                    cftm.orderByColumn(table.getTablePanel().getTable()
103
                        .getSelectedColumnsAttributeDescriptor()[0].getName(),
104
                        false);
105 40870 jldominguez
106
                    // Mark as modified:
107
                    table.getModel().setModified(true);
108
109
                } else {
110
                    if ("selection-duplicates".equals(actionCommand)) {
111
112
                        // Find and select duplicates in selected column
113
                        long[] valCases = findSelectDuplicates(table);
114
                        /*
115
                         * Show info dialog
116
                         */
117
                        String msg = "";
118
                        if (valCases[0] == 0) {
119
                            // No repetitions
120
                            msg = Messages.getText("_No_repetitions_found");
121
                        } else {
122
                            String[] args = new String[2];
123
                            args[0] = Long.toString(valCases[0]);
124
                            args[1] = Long.toString(valCases[1]);
125
                            msg = Messages.getText(
126
                                "_Found_N_diff_repeated_vals_in_total_N_cases", args);
127
                        }
128
                        JOptionPane.showMessageDialog(
129
                            ApplicationLocator.getManager().getRootComponent(),
130
                            msg,
131
                            Messages.getText("_Find_and_select_duplicates"),
132
                            JOptionPane.INFORMATION_MESSAGE);
133
                    }
134 40435 jjdelcerro
                }
135 40870 jldominguez
            }
136 40435 jjdelcerro
        } catch (BaseException e) {
137 40870 jldominguez
            logger.error("While applying field operation (" + actionCommand + ")", e);
138 40435 jjdelcerro
        }
139
    }
140
141 40870 jldominguez
142 40435 jjdelcerro
    /**
143 40870 jldominguez
     * Detects repeated values
144
     *
145
     * @param tpanel
146
     * @return Returns two values: numbers of values repeated and number of rows
147
     * with values which are repeated
148
     *
149
     * @throws DataException
150
     */
151
    private long[] findSelectDuplicates(FeatureTableDocumentPanel tpanel)
152
        throws DataException {
153
154
        long[] values_cases = {0, 0};
155
156
        ConfigurableFeatureTableModel cftm = tpanel.getTablePanel().getTableModel();
157
        FeatureTable ftable = tpanel.getTablePanel().getTable();
158
159
        // There is only one selected column
160
        String fieldName = ftable.getSelectedColumnsAttributeDescriptor()[0].getName();
161
        FeatureStore fstore = cftm.getFeatureStore();
162
163
164 45426 fdiaz
        Set<String> selFeats = DALLocator.getDataManager().createLargeSet();
165
166 40870 jldominguez
        FeatureQuery fquery = fstore.createFeatureQuery();
167
        /*
168
         * Create order based on selected column
169
         * (ascending but descending would be ok too)
170
         */
171 45308 fdiaz
        FeatureQueryOrder fqo = fquery.getOrder();
172 40870 jldominguez
        fqo.add(fieldName, true);
173
        fquery.setOrder(fqo);
174
        FeatureSet fset = fstore.getFeatureSet(fquery);
175
        DisposableIterator iter = fset.fastIterator();
176
        Feature currFeat = null;
177
        Feature prevFeat = null;
178
179
        Object curVal = null;
180
        Object preVal = null;
181
182
        /*
183
         * Get first feature and go next if there is next
184
         */
185
        if (iter.hasNext()) {
186
            currFeat = (Feature) iter.next();
187
            currFeat = currFeat.getCopy();
188
            curVal = currFeat.get(fieldName);
189
        } else {
190
            iter.dispose();
191
            return values_cases;
192
        }
193
194
        boolean equals = false;
195
        /*
196
         * Iterate and get copy of features with repeated value
197
         */
198
        while (iter.hasNext()) {
199
            prevFeat = currFeat;
200
            currFeat = (Feature) iter.next();
201
            currFeat = currFeat.getCopy();
202
203
            preVal = curVal;
204
            curVal = currFeat.get(fieldName);
205
206
            if (sameValue(preVal, curVal)) {
207
                if (!equals) {
208
                    // We are entering a new set of repetitions
209
                    values_cases[0]++;
210
                }
211
                equals = true;
212 45426 fdiaz
                selFeats.add(prevFeat.getReference().getCode());
213
214 40870 jldominguez
            } else {
215
                if (equals) {
216
                    // We have gone out of equal group
217 45426 fdiaz
                    selFeats.add(prevFeat.getReference().getCode());
218 40870 jldominguez
                }
219
                equals = false;
220
            }
221
        }
222
        iter.dispose();
223
        FeatureSelection fsele = (FeatureSelection) fstore.getSelection();
224
        fsele.beginComplexNotification();
225
        /*
226
         * Set selection inside complex notification to prevent
227
         * lots of notifications
228
         */
229
        // ============================
230
        fsele.deselectAll();
231
232
        values_cases[1] = selFeats.size();
233
        if (values_cases[1] > 0) {
234 45426 fdiaz
            Iterator<String> fiter = selFeats.iterator();
235 40870 jldominguez
            while (fiter.hasNext()) {
236 45426 fdiaz
                fsele.select(fstore.getFeatureReference(fiter.next()));
237 40870 jldominguez
            }
238
        }
239
        // ============================
240
        fsele.endComplexNotification();
241
        return values_cases;
242
    }
243
244
245
    private boolean sameValue(Object v1, Object v2) {
246
247
        if (v1 == null) {
248
            if (v2 == null) {
249
                // Both null, same value
250
                return true;
251
            } else {
252
                // Only one is null, not same value
253
                return false;
254
            }
255
        } else {
256
            if (v2 == null) {
257
                // Only one is null, not same value
258
                return false;
259
            } else {
260
                // Delegate in equals method
261
                return v1.equals(v2);
262
            }
263
        }
264
    }
265
266
    /**
267 40435 jjdelcerro
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
268
     */
269
    public boolean isEnabled() {
270
        try {
271
            return (table.getTablePanel().getTable().getSelectedColumnCount() == 1);
272
        } catch (DataException e) {
273 40870 jldominguez
            logger.error("While getting number of selected rows.", e);
274 40435 jjdelcerro
        }
275
        return false;
276
    }
277
278
    /**
279
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
280
     */
281
    public boolean isVisible() {
282
        IWindow v = PluginServices.getMDIManager().getActiveWindow();
283
        if (v != null && v instanceof FeatureTableDocumentPanel) {
284
            table = (FeatureTableDocumentPanel) v;
285
            return true;
286
        }
287
        return false;
288
    }
289
290
}