Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / DefaultFeatureQueryOrder.java @ 47248

History | View | Annotate | Download (17.3 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 43020 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 40559 jjdelcerro
 *
11 43020 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 40559 jjdelcerro
 *
16 43020 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 40559 jjdelcerro
 *
20 43020 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 40559 jjdelcerro
 */
23 45308 fdiaz
package org.gvsig.fmap.dal.feature.impl;
24 40435 jjdelcerro
25
import java.util.ArrayList;
26 44644 jjdelcerro
import java.util.Collections;
27 40435 jjdelcerro
import java.util.Comparator;
28
import java.util.Iterator;
29
import java.util.List;
30 43020 jjdelcerro
import java.util.NoSuchElementException;
31 46970 jjdelcerro
import javax.json.JsonArray;
32
import javax.json.JsonObject;
33
import javax.json.JsonValue;
34 43987 jjdelcerro
import org.apache.commons.lang3.StringUtils;
35 47198 jjdelcerro
import org.apache.commons.lang3.builder.ToStringBuilder;
36 44829 omartinez
import org.gvsig.expressionevaluator.Expression;
37 45366 omartinez
import org.gvsig.expressionevaluator.ExpressionEvaluator;
38 40435 jjdelcerro
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
39 45308 fdiaz
import org.gvsig.fmap.dal.feature.Feature;
40
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
41 45366 omartinez
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator;
42 46970 jjdelcerro
import org.gvsig.json.Json;
43
import org.gvsig.json.JsonObjectBuilder;
44 44829 omartinez
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dynobject.DynStruct;
46 40435 jjdelcerro
import org.gvsig.tools.evaluator.Evaluator;
47
import org.gvsig.tools.evaluator.EvaluatorData;
48
import org.gvsig.tools.evaluator.EvaluatorException;
49
import org.gvsig.tools.persistence.PersistentState;
50
import org.gvsig.tools.persistence.exception.PersistenceException;
51 44829 omartinez
import org.slf4j.LoggerFactory;
52 40435 jjdelcerro
53 45308 fdiaz
public class DefaultFeatureQueryOrder implements FeatureQueryOrder {
54 40435 jjdelcerro
55 45308 fdiaz
    public static class FeatureQueryOrderMemberImpl implements FeatureQueryOrderMember {
56 43026 jjdelcerro
57
        String attributeName = null;
58
        Evaluator evaluator = null;
59 45308 fdiaz
//        Expression expression = null;
60 43026 jjdelcerro
        boolean ascending;
61
62 44829 omartinez
        private final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FeatureQueryOrderMember.class);
63
64 45308 fdiaz
        public FeatureQueryOrderMemberImpl() {
65 44829 omartinez
66
        }
67
68 45308 fdiaz
        FeatureQueryOrderMemberImpl(String attributeName, boolean ascending) {
69 43026 jjdelcerro
            this.attributeName = attributeName;
70
            this.ascending = ascending;
71
        }
72
73 45308 fdiaz
        FeatureQueryOrderMemberImpl(Evaluator evaluator, boolean ascending) {
74 43026 jjdelcerro
            this.evaluator = evaluator;
75 44829 omartinez
            LOGGER.warn("Creating evaluator that will not be able to persist");
76 43026 jjdelcerro
            this.ascending = ascending;
77
        }
78
79 46540 fdiaz
        FeatureQueryOrderMemberImpl(ExpressionEvaluator evaluator, boolean ascending) {
80
            this.evaluator = evaluator;
81
            this.ascending = ascending;
82
        }
83
84 44712 jjdelcerro
        @Override
85
        public String toString() {
86 47198 jjdelcerro
            try {
87
                ToStringBuilder builder = new ToStringBuilder(this);
88
                if( evaluator==null ) {
89
                    builder.append("attributeName", this.attributeName);
90
                } else {
91
                    builder.append("evaluator", this.evaluator.getSQL());
92
                }
93
                builder.append("ascending", this.ascending ? "ASC" : "DESC");
94
                return builder.toString();
95
            } catch (Exception e) {
96
                return super.toString();
97 44829 omartinez
            }
98 47198 jjdelcerro
        }
99
100 44712 jjdelcerro
101 43026 jjdelcerro
        public boolean hasEvaluator() {
102
            return this.evaluator != null;
103
        }
104
105
        public Evaluator getEvaluator() {
106
            return this.evaluator;
107
        }
108
109
        public boolean getAscending() {
110
            return this.ascending;
111
        }
112
113
        public String getAttributeName() {
114
            return this.attributeName;
115
        }
116
117
        @Override
118
        public void loadFromState(PersistentState state)
119
                throws PersistenceException {
120
            this.attributeName = state.getString("attributeName");
121
            this.ascending = state.getBoolean("ascending");
122 45308 fdiaz
            this.evaluator = (Evaluator) state.get("evaluator");
123 43026 jjdelcerro
        }
124
125
        @Override
126
        public void saveToState(PersistentState state)
127
                throws PersistenceException {
128
            state.set("attributeName", this.attributeName);
129
            state.set("ascending", this.ascending);
130 45366 omartinez
            if(evaluator instanceof ExpressionEvaluator){
131 45308 fdiaz
                state.set("evaluator", evaluator);
132
            } else {
133
                state.setNull("evaluator");
134
            }
135 43026 jjdelcerro
        }
136
137
        @Override
138
        public FeatureQueryOrderMember clone() throws CloneNotSupportedException {
139
            // Nothing more to clone
140
            return (FeatureQueryOrderMember) super.clone();
141
        }
142
143 44644 jjdelcerro
        public void setAscending(boolean ascending) {
144
            this.ascending = ascending;
145
        }
146
147 46970 jjdelcerro
        @Override
148
        public void fromJson(JsonObject json) {
149
            this.attributeName = json.getString("attributeName", null);
150
            this.ascending = json.getBoolean("ascending", true);
151
            this.evaluator = (Evaluator) Json.toObject(json, "evaluator");
152
        }
153
154
        @Override
155
        public JsonObjectBuilder toJsonBuilder() {
156
            JsonObjectBuilder state = Json.createObjectBuilder();
157
            state.add("attributeName", this.attributeName);
158
            state.add("ascending", this.ascending);
159
            if(evaluator instanceof ExpressionEvaluator){
160
                state.add("evaluator", evaluator);
161
            } else {
162
                state.addNull("evaluator");
163
            }
164
            return state;
165
        }
166
167 43026 jjdelcerro
    }
168
169 44644 jjdelcerro
    private List<FeatureQueryOrderMember> members = new ArrayList();
170 45308 fdiaz
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureQueryOrder.class);
171 40435 jjdelcerro
172 45308 fdiaz
    public DefaultFeatureQueryOrder() {
173 43026 jjdelcerro
    }
174 44829 omartinez
175 44712 jjdelcerro
    public void copyFrom(FeatureQueryOrder other) {
176 44829 omartinez
        List<FeatureQueryOrderMember> theMembers = new ArrayList<>();
177 45308 fdiaz
        for (FeatureQueryOrderMember member : other) {
178 44829 omartinez
            FeatureQueryOrderMember m;
179
            try {
180
                m = member.clone();
181
            } catch (CloneNotSupportedException ex) {
182
                throw new RuntimeException("Can't copy member (" + member.toString() + ").", ex);
183
            }
184
            theMembers.add(m);
185 44712 jjdelcerro
        }
186 44829 omartinez
        this.members = theMembers;
187 44712 jjdelcerro
    }
188 44829 omartinez
189 43987 jjdelcerro
    public Object add(String order) {
190 44829 omartinez
        if (StringUtils.isEmpty(order)) {
191 43987 jjdelcerro
            return null;
192
        }
193
        Object r = null;
194
        String[] attributes = StringUtils.split(order, ',');
195
        for (String attribute : attributes) {
196
            boolean ascending = true;
197 44829 omartinez
            if (attribute.startsWith("+")) {
198 43987 jjdelcerro
                ascending = true;
199
                attribute = attribute.substring(1);
200 44829 omartinez
            } else if (attribute.startsWith("-")) {
201 43987 jjdelcerro
                ascending = false;
202
                attribute = attribute.substring(1);
203
            }
204
            attribute = attribute.trim();
205 44829 omartinez
            r = this.add(attribute, ascending);
206 43987 jjdelcerro
        }
207
        return r;
208
    }
209 44829 omartinez
210 43020 jjdelcerro
    public Object add(String attributeName, boolean ascending) {
211 45308 fdiaz
        FeatureQueryOrderMember member = new FeatureQueryOrderMemberImpl(
212 40435 jjdelcerro
                attributeName, ascending);
213 43020 jjdelcerro
        if (members.add(member)) {
214
            return member;
215
        }
216
        return null;
217
    }
218 40435 jjdelcerro
219 45308 fdiaz
    public Object add(Expression expr, boolean ascending) {
220
221 45366 omartinez
        Evaluator evaluator = new DefaultFeatureExpressionEvaluator(expr);
222 45308 fdiaz
        FeatureQueryOrderMember member = new FeatureQueryOrderMemberImpl(
223
                evaluator,
224
                ascending);
225
        if (members.add(member)) {
226
            return member;
227
        }
228
        return null;
229
230
    }
231
232 43026 jjdelcerro
    public Iterable<FeatureQueryOrderMember> members() {
233
        //    Me hubiese gustado que FeatureQueryOrder fuese Iterable, pero no se deja por
234
        //    que FeatureQueryOrderMember es una clase interna y no esta definida en el
235
        //    momento de poner el :
236
        //            implements Iterable<FeatureQueryOrderMember>
237
        //    Y si saco a una clase independiente FeatureQueryOrderMember se pierde
238
        //    compatibilidad binaria con quien la esta usando.
239
        //    Para rodearlo, he creado el metodo members.
240 44829 omartinez
        return new Iterable<FeatureQueryOrderMember>() {
241 43026 jjdelcerro
242
            @Override
243
            public Iterator<FeatureQueryOrderMember> iterator() {
244 45308 fdiaz
                return DefaultFeatureQueryOrder.this.iterator();
245 43026 jjdelcerro
            }
246
        };
247
    }
248 44829 omartinez
249 43020 jjdelcerro
    public Iterator<FeatureQueryOrderMember> iterator() {
250 43026 jjdelcerro
        if (members == null) {
251 43020 jjdelcerro
            return new Iterator<FeatureQueryOrderMember>() {
252
                @Override
253
                public boolean hasNext() {
254
                    return false;
255
                }
256 40435 jjdelcerro
257 43020 jjdelcerro
                @Override
258
                public FeatureQueryOrderMember next() {
259
                    throw new NoSuchElementException();
260
                }
261 40435 jjdelcerro
262 43020 jjdelcerro
                @Override
263
                public void remove() {
264
                    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
265
                }
266
            };
267
        }
268
        return members.iterator();
269
    }
270 40435 jjdelcerro
271 43020 jjdelcerro
    public boolean remove(FeatureQueryOrderMember member) {
272
        return members.remove(member);
273
    }
274 40435 jjdelcerro
275 43020 jjdelcerro
    public void remove(int index) {
276
        members.remove(index);
277
    }
278 40435 jjdelcerro
279 43020 jjdelcerro
    public void clear() {
280
        members.clear();
281
    }
282 40435 jjdelcerro
283 43020 jjdelcerro
    public int size() {
284
        return this.members.size();
285
    }
286 44829 omartinez
287 44644 jjdelcerro
    public int getIndex(String attributeName) {
288
        int n = 0;
289
        for (FeatureQueryOrderMember member : members) {
290 44829 omartinez
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
291 44644 jjdelcerro
                return n;
292
            }
293
            n++;
294
        }
295
        return -1;
296
    }
297 44829 omartinez
298 44644 jjdelcerro
    public void movePrevious(String name) {
299
        int n = this.getIndex(name);
300 44829 omartinez
        if (n < 1) {
301 44644 jjdelcerro
            return;
302
        }
303 44829 omartinez
        Collections.swap(members, n, n - 1);
304 44644 jjdelcerro
    }
305 40435 jjdelcerro
306 44644 jjdelcerro
    public void moveNext(String name) {
307
        int n = this.getIndex(name);
308 44829 omartinez
        if (n >= this.members.size() - 1) {
309 44644 jjdelcerro
            return;
310
        }
311 44829 omartinez
        Collections.swap(members, n, n + 1);
312 44644 jjdelcerro
    }
313
314
    public boolean isEmpty() {
315 44829 omartinez
        return this.members == null || this.members.isEmpty();
316 44644 jjdelcerro
    }
317 44829 omartinez
318 44644 jjdelcerro
    public FeatureQueryOrderMember get(String attributeName) {
319
        for (FeatureQueryOrderMember member : members) {
320 44829 omartinez
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
321 44644 jjdelcerro
                return member;
322
            }
323
        }
324
        return null;
325
    }
326 44829 omartinez
327 44644 jjdelcerro
    public boolean contains(String attributeName) {
328
        for (FeatureQueryOrderMember member : members) {
329 44829 omartinez
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
330 44644 jjdelcerro
                return true;
331
            }
332
        }
333
        return false;
334
    }
335 44829 omartinez
336 44644 jjdelcerro
    public Comparator<Feature> getFeatureComparator() {
337 43020 jjdelcerro
        return new DefaultFeatureComparator(this);
338
    }
339 40435 jjdelcerro
340 44644 jjdelcerro
    @Override
341 45308 fdiaz
    public DefaultFeatureQueryOrder clone() throws CloneNotSupportedException {
342
        DefaultFeatureQueryOrder clone = (DefaultFeatureQueryOrder) super.clone();
343 40435 jjdelcerro
344 43020 jjdelcerro
        if (members != null) {
345
            clone.members = new ArrayList(members.size());
346
            for (int i = 0; i < members.size(); i++) {
347 44644 jjdelcerro
                clone.members.add((members.get(i)).clone());
348 43020 jjdelcerro
            }
349
        }
350 40435 jjdelcerro
351 43020 jjdelcerro
        return clone;
352
    }
353 40435 jjdelcerro
354 45308 fdiaz
    public DefaultFeatureQueryOrder getCopy() {
355
        DefaultFeatureQueryOrder aCopy = new DefaultFeatureQueryOrder();
356 43020 jjdelcerro
        Iterator iter = this.members.iterator();
357
        FeatureQueryOrderMember member;
358
        while (iter.hasNext()) {
359
            member = (FeatureQueryOrderMember) iter.next();
360
            if (member.hasEvaluator()) {
361 44829 omartinez
//                aCopy.add(member.getEvaluator(), member.getAscending());
362
                LOGGER.warn("Evaluator is not being added to the filter in a class copy");
363 43020 jjdelcerro
            } else {
364
                aCopy.add(member.getAttributeName(), member.getAscending());
365
            }
366
        }
367
        return aCopy;
368
    }
369 40435 jjdelcerro
370 46970 jjdelcerro
    public static void selfRegister() {
371
        registerPersistent();
372
        Json.registerSerializer(DefaultFeatureQueryOrder.class);
373
        Json.registerSerializer(FeatureQueryOrderMemberImpl.class);
374
    }
375
376 44829 omartinez
    /**
377
     * Register the class on PersistenceManager
378
     *
379
     */
380 46970 jjdelcerro
    private static void registerPersistent() {
381 44829 omartinez
        DynStruct definitionMember
382
                = ToolsLocator.getPersistenceManager()
383 45366 omartinez
                        .addDefinition(FeatureQueryOrderMemberImpl.class,
384 44829 omartinez
                                "FeatureQueryOrderMember",
385
                                "FeatureQueryOrderMember Persistent definition",
386
                                null,
387
                                null);
388
389
        definitionMember.addDynFieldString("attributeName").setClassOfValue(String.class).setMandatory(false);
390 45366 omartinez
        definitionMember.addDynFieldObject("evaluator").setClassOfValue(ExpressionEvaluator.class).setMandatory(false);
391 44829 omartinez
        definitionMember.addDynFieldBoolean("ascending").setMandatory(false);
392
393
        DynStruct definition
394
                = ToolsLocator.getPersistenceManager()
395 45308 fdiaz
                        .addDefinition(DefaultFeatureQueryOrder.class,
396 44829 omartinez
                                "FeatureQueryOrder",
397
                                "FeatureQueryOrder Persistent definition",
398
                                null,
399
                                null);
400
401 45366 omartinez
        definition.addDynFieldList("members").setClassOfItems(FeatureQueryOrderMemberImpl.class);
402 44829 omartinez
403
    }
404
405 44644 jjdelcerro
    @Override
406 43020 jjdelcerro
    public void loadFromState(PersistentState state)
407
            throws PersistenceException {
408 44829 omartinez
        List<FeatureQueryOrderMember> stateMembers = (List) state.get("members");
409
        this.members = new ArrayList<>();
410
        for (FeatureQueryOrderMember stateMember : stateMembers) {
411
            this.members.add(stateMember);
412
        }
413 43020 jjdelcerro
    }
414 40435 jjdelcerro
415 44644 jjdelcerro
    @Override
416 43020 jjdelcerro
    public void saveToState(PersistentState state) throws PersistenceException {
417 44829 omartinez
        state.set("members", members);
418
419 43020 jjdelcerro
    }
420 40435 jjdelcerro
421 44644 jjdelcerro
    private class DefaultFeatureComparator implements Comparator<Feature> {
422 40435 jjdelcerro
423 45308 fdiaz
        private final DefaultFeatureQueryOrder order;
424 40435 jjdelcerro
425 45308 fdiaz
        public DefaultFeatureComparator(DefaultFeatureQueryOrder order) {
426 43020 jjdelcerro
            this.order = order;
427
            // TODO optimizar en un array???
428 40435 jjdelcerro
429 43020 jjdelcerro
        }
430 40435 jjdelcerro
431 43020 jjdelcerro
        private int myCompare(Object arg0, Object arg1) {
432
            if (arg0 == null) {
433
                if (arg1 == null) {
434
                    return 0;
435
                } else {
436
                    return 1;
437
                }
438
            } else if (arg1 == null) {
439
                if (arg0 == null) {
440
                    return 0;
441
                } else {
442
                    return 1;
443
                }
444
            }
445
            if (arg0 instanceof Comparable) {
446
                return ((Comparable) arg0).compareTo(arg1);
447
            } else if (arg1 instanceof Comparable) {
448
                return ((Comparable) arg1).compareTo(arg0) * -1;
449
            }
450 40435 jjdelcerro
451 43020 jjdelcerro
            if (arg0.equals(arg1)) {
452
                return 0;
453
            } else {
454
                return -1;
455
            }
456 40435 jjdelcerro
457 43020 jjdelcerro
        }
458 40435 jjdelcerro
459 44644 jjdelcerro
        @Override
460
        public int compare(Feature f0, Feature f1) {
461 43020 jjdelcerro
            Iterator iter = this.order.iterator();
462
            int returnValue = 0;
463 44644 jjdelcerro
//            Feature f0 = (Feature) arg0;
464
//            Feature f1 = (Feature) arg1;
465 43020 jjdelcerro
            Object item;
466
            String attrName;
467
            Evaluator evaluator;
468
            while (returnValue == 0 && iter.hasNext()) {
469
                item = iter.next();
470
                if (item instanceof String) {
471
                    attrName = (String) item;
472
                    returnValue = this
473
                            .myCompare(f0.get(attrName), f1
474
                                    .get(attrName));
475
                } else {
476
                    evaluator = (Evaluator) item;
477
                    try {
478
                        returnValue = this.myCompare(evaluator
479
                                .evaluate((EvaluatorData) f0), evaluator
480
                                .evaluate((EvaluatorData) f1));
481
                    } catch (EvaluatorException e) {
482
                        throw new DataEvaluatorRuntimeException(e);
483
                    }
484
                }
485
            }
486 40435 jjdelcerro
487 43020 jjdelcerro
            return returnValue;
488
        }
489 40435 jjdelcerro
490 43020 jjdelcerro
    }
491
492 46970 jjdelcerro
    @Override
493
    public void fromJson(JsonObject json) {
494
        JsonArray stateMembers = json.getJsonArray("members");
495
        this.members = new ArrayList<>();
496
        for (JsonValue stateMember : stateMembers) {
497
            this.members.add((FeatureQueryOrderMember) Json.toObject(stateMember));
498
        }
499
    }
500
501
    @Override
502
    public JsonObjectBuilder toJsonBuilder() {
503
        JsonObjectBuilder state = Json.createObjectBuilder();
504
        state.add("members", members);
505
        return state;
506
    }
507 47198 jjdelcerro
508
    @Override
509
    public String toString() {
510
        try {
511
            ToStringBuilder builder = new ToStringBuilder(this);
512
            builder.append("members", this.members, true);
513
            return builder.toString();
514
        } catch (Exception e) {
515
            return super.toString();
516
        }
517
    }
518 43020 jjdelcerro
}