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 | } |