Revision 45308 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.api/src/main/java/org/gvsig/fmap/dal/feature/FeatureQueryOrder.java

View differences:

FeatureQueryOrder.java
22 22
 */
23 23
package org.gvsig.fmap.dal.feature;
24 24

  
25
import java.util.ArrayList;
26
import java.util.Collections;
27
import java.util.Comparator;
28 25
import java.util.Iterator;
29
import java.util.List;
30
import java.util.NoSuchElementException;
31
import org.apache.commons.lang3.StringUtils;
32 26
import org.gvsig.expressionevaluator.Expression;
33

  
34
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dynobject.DynStruct;
27
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
37 28
import org.gvsig.tools.evaluator.Evaluator;
38
import org.gvsig.tools.evaluator.EvaluatorData;
39
import org.gvsig.tools.evaluator.EvaluatorException;
40 29
import org.gvsig.tools.lang.Cloneable;
41 30
import org.gvsig.tools.persistence.Persistent;
42
import org.gvsig.tools.persistence.PersistentState;
43
import org.gvsig.tools.persistence.exception.PersistenceException;
44
import org.slf4j.LoggerFactory;
45 31

  
46
public class FeatureQueryOrder implements Persistent, Cloneable {
32
/**
33
 *
34
 * @author fdiaz
35
 */
36
public interface FeatureQueryOrder extends Cloneable, Iterable<FeatureQueryOrderMember>, Persistent {
47 37

  
48
    public static class FeatureQueryOrderMember implements Persistent, org.gvsig.tools.lang.Cloneable {
38
    public interface FeatureQueryOrderMember extends Persistent, Cloneable {
49 39

  
50
        String attributeName = null;
51
        Evaluator evaluator = null;
52
        Expression expression = null;
53
        boolean ascending;
40
        FeatureQueryOrderMember clone() throws CloneNotSupportedException;
54 41

  
55
        private final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FeatureQueryOrderMember.class);
42
        boolean getAscending();
56 43

  
57
        public FeatureQueryOrderMember() {
44
        String getAttributeName();
58 45

  
59
        }
60
        
61
        FeatureQueryOrderMember(String attributeName, boolean ascending) {
62
            this.attributeName = attributeName;
63
            this.ascending = ascending;
64
        }
46
        Evaluator getEvaluator();
65 47

  
66
        FeatureQueryOrderMember(Evaluator evaluator, boolean ascending) {
67
            this.evaluator = evaluator;
68
            LOGGER.warn("Creating evaluator that will not be able to persist");
69
            this.ascending = ascending;
70
        }
48
        boolean hasEvaluator();
71 49

  
72
        @Override
73
        public String toString() {
74
            if (this.evaluator != null) {
75
                return this.evaluator.getSQL() + " " + (this.ascending ? "ASC" : "DESC");
76
            }
77
            return (this.ascending ? "+" : "-") + this.attributeName;
78
        }
50
        void setAscending(boolean ascending);
79 51

  
80
        public boolean hasEvaluator() {
81
            return this.evaluator != null;
82
        }
83

  
84
        public Evaluator getEvaluator() {
85
            return this.evaluator;
86
        }
87

  
88
        public boolean getAscending() {
89
            return this.ascending;
90
        }
91

  
92
        public String getAttributeName() {
93
            return this.attributeName;
94
        }
95

  
96
        @Override
97
        public void loadFromState(PersistentState state)
98
                throws PersistenceException {
99
            this.attributeName = state.getString("attributeName");
100
            this.ascending = state.getBoolean("ascending");
101
            // Note: evaluator dont persist
102
//            this.evaluator = (Evaluator) state.get("evaluator");
103
//            this.expression = (Expression) state.get("expression");
104
        }
105

  
106
        @Override
107
        public void saveToState(PersistentState state)
108
                throws PersistenceException {
109
            state.set("attributeName", this.attributeName);
110
            state.set("ascending", this.ascending);
111
//            if (this.evaluator != null) {
112
//                state.set("evaluator", evaluator);
113
//            }
114
//            state.set("expression", this.expression);
115

  
116
        }
117

  
118
        @Override
119
        public FeatureQueryOrderMember clone() throws CloneNotSupportedException {
120
            // Nothing more to clone
121
            return (FeatureQueryOrderMember) super.clone();
122
        }
123

  
124
        public void setAscending(boolean ascending) {
125
            this.ascending = ascending;
126
        }
127

  
128 52
    }
129 53

  
130
    private List<FeatureQueryOrderMember> members = new ArrayList();
131
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FeatureQueryOrder.class);
54
    Object add(String order);
132 55

  
133
    public FeatureQueryOrder() {
134
    }
56
    Object add(String attributeName, boolean ascending);
135 57

  
136
    public void copyFrom(FeatureQueryOrder other) {
137
        List<FeatureQueryOrderMember> theMembers = new ArrayList<>();
138
        for (FeatureQueryOrderMember member : other.members) {
139
            FeatureQueryOrderMember m;
140
            try {
141
                m = member.clone();
142
            } catch (CloneNotSupportedException ex) {
143
                throw new RuntimeException("Can't copy member (" + member.toString() + ").", ex);
144
            }
145
            theMembers.add(m);
146
        }
147
        this.members = theMembers;
148
    }
58
    Object add(Expression expr, boolean ascending);
149 59

  
150
    @Override
151
    public String toString() {
152
        StringBuilder builder = new StringBuilder();
153
        boolean needComma = false;
154
        for (FeatureQueryOrderMember member : members) {
155
            if (member != null && !StringUtils.isBlank(member.getAttributeName())) {
156
                if (needComma) {
157
                    builder.append(",");
158
                }
159
                builder.append(member.toString());
160
                needComma = true;
161
            }
162
        }
163
        String s = builder.toString();
164
        if (StringUtils.isBlank(s)) {
165
            return null;
166
        }
167
        return s;
168
    }
60
    void clear();
169 61

  
170
    public Object add(String order) {
171
        if (StringUtils.isEmpty(order)) {
172
            return null;
173
        }
174
        Object r = null;
175
        String[] attributes = StringUtils.split(order, ',');
176
        for (String attribute : attributes) {
177
            boolean ascending = true;
178
            if (attribute.startsWith("+")) {
179
                ascending = true;
180
                attribute = attribute.substring(1);
181
            } else if (attribute.startsWith("-")) {
182
                ascending = false;
183
                attribute = attribute.substring(1);
184
            }
185
            attribute = attribute.trim();
186
            r = this.add(attribute, ascending);
187
        }
188
        return r;
189
    }
62
    FeatureQueryOrder clone() throws CloneNotSupportedException;
190 63

  
191
    public Object add(String attributeName, boolean ascending) {
192
        FeatureQueryOrderMember member = new FeatureQueryOrderMember(
193
                attributeName, ascending);
194
        if (members.add(member)) {
195
            return member;
196
        }
197
        return null;
198
    }
64
    boolean contains(String attributeName);
199 65

  
200
//    TODO: Nota: hay que a?adir add de un Expression
201
//    public Object add(Evaluator evaluator, boolean ascending) {
202
//        FeatureQueryOrderMember member = new FeatureQueryOrderMember(
203
//                evaluator,
204
//                ascending);
205
//        if (members.add(member)) {
206
//            return member;
207
//        }
208
//        return null;
209
//    }
210
    public Iterable<FeatureQueryOrderMember> members() {
211
        //    Me hubiese gustado que FeatureQueryOrder fuese Iterable, pero no se deja por 
212
        //    que FeatureQueryOrderMember es una clase interna y no esta definida en el 
213
        //    momento de poner el :
214
        //            implements Iterable<FeatureQueryOrderMember>
215
        //    Y si saco a una clase independiente FeatureQueryOrderMember se pierde 
216
        //    compatibilidad binaria con quien la esta usando.
217
        //    Para rodearlo, he creado el metodo members.
218
        return new Iterable<FeatureQueryOrderMember>() {
66
    void copyFrom(FeatureQueryOrder other);
219 67

  
220
            @Override
221
            public Iterator<FeatureQueryOrderMember> iterator() {
222
                return FeatureQueryOrder.this.iterator();
223
            }
224
        };
225
    }
68
    FeatureQueryOrderMember get(String attributeName);
226 69

  
227
    public Iterator<FeatureQueryOrderMember> iterator() {
228
        if (members == null) {
229
            return new Iterator<FeatureQueryOrderMember>() {
230
                @Override
231
                public boolean hasNext() {
232
                    return false;
233
                }
70
    FeatureQueryOrder getCopy();
234 71

  
235
                @Override
236
                public FeatureQueryOrderMember next() {
237
                    throw new NoSuchElementException();
238
                }
72
    int getIndex(String attributeName);
239 73

  
240
                @Override
241
                public void remove() {
242
                    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
243
                }
244
            };
245
        }
246
        return members.iterator();
247
    }
74
    boolean isEmpty();
248 75

  
249
    public boolean remove(FeatureQueryOrderMember member) {
250
        return members.remove(member);
251
    }
76
    Iterator<FeatureQueryOrderMember> iterator();
252 77

  
253
    public void remove(int index) {
254
        members.remove(index);
255
    }
78
    Iterable<FeatureQueryOrderMember> members();
256 79

  
257
    public void clear() {
258
        members.clear();
259
    }
80
    void moveNext(String name);
260 81

  
261
    public int size() {
262
        return this.members.size();
263
    }
82
    void movePrevious(String name);
264 83

  
265
    public int getIndex(String attributeName) {
266
        int n = 0;
267
        for (FeatureQueryOrderMember member : members) {
268
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
269
                return n;
270
            }
271
            n++;
272
        }
273
        return -1;
274
    }
84
    boolean remove(FeatureQueryOrderMember member);
275 85

  
276
    public void movePrevious(String name) {
277
        int n = this.getIndex(name);
278
        if (n < 1) {
279
            return;
280
        }
281
        Collections.swap(members, n, n - 1);
282
    }
86
    void remove(int index);
283 87

  
284
    public void moveNext(String name) {
285
        int n = this.getIndex(name);
286
        if (n >= this.members.size() - 1) {
287
            return;
288
        }
289
        Collections.swap(members, n, n + 1);
290
    }
88
    int size();
291 89

  
292
    public boolean isEmpty() {
293
        return this.members == null || this.members.isEmpty();
294
    }
295

  
296
    public FeatureQueryOrderMember get(String attributeName) {
297
        for (FeatureQueryOrderMember member : members) {
298
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
299
                return member;
300
            }
301
        }
302
        return null;
303
    }
304

  
305
    public boolean contains(String attributeName) {
306
        for (FeatureQueryOrderMember member : members) {
307
            if (member != null && StringUtils.equalsIgnoreCase(attributeName, member.getAttributeName())) {
308
                return true;
309
            }
310
        }
311
        return false;
312
    }
313

  
314
    public Comparator<Feature> getFeatureComparator() {
315
        return new DefaultFeatureComparator(this);
316
    }
317

  
318
    @Override
319
    public FeatureQueryOrder clone() throws CloneNotSupportedException {
320
        FeatureQueryOrder clone = (FeatureQueryOrder) super.clone();
321

  
322
        if (members != null) {
323
            clone.members = new ArrayList(members.size());
324
            for (int i = 0; i < members.size(); i++) {
325
                clone.members.add((members.get(i)).clone());
326
            }
327
        }
328

  
329
        return clone;
330
    }
331

  
332
    public FeatureQueryOrder getCopy() {
333
        FeatureQueryOrder aCopy = new FeatureQueryOrder();
334
        Iterator iter = this.members.iterator();
335
        FeatureQueryOrderMember member;
336
        while (iter.hasNext()) {
337
            member = (FeatureQueryOrderMember) iter.next();
338
            if (member.hasEvaluator()) {
339
//                aCopy.add(member.getEvaluator(), member.getAscending());
340
                LOGGER.warn("Evaluator is not being added to the filter in a class copy");
341
            } else {
342
                aCopy.add(member.getAttributeName(), member.getAscending());
343
            }
344
        }
345
        return aCopy;
346
    }
347

  
348
    /**
349
     * Register the class on PersistenceManager
350
     *
351
     */
352
    public static void registerPersistent() {
353
        DynStruct definitionMember
354
                = ToolsLocator.getPersistenceManager()
355
                        .addDefinition(FeatureQueryOrderMember.class,
356
                                "FeatureQueryOrderMember",
357
                                "FeatureQueryOrderMember Persistent definition",
358
                                null,
359
                                null);
360

  
361
        definitionMember.addDynFieldString("attributeName").setClassOfValue(String.class).setMandatory(false);
362
        definitionMember.addDynFieldObject("expression").setClassOfValue(Expression.class).setMandatory(false);
363
        definitionMember.addDynFieldBoolean("ascending").setMandatory(false);
364

  
365
        DynStruct definition
366
                = ToolsLocator.getPersistenceManager()
367
                        .addDefinition(FeatureQueryOrder.class,
368
                                "FeatureQueryOrder",
369
                                "FeatureQueryOrder Persistent definition",
370
                                null,
371
                                null);
372

  
373
        definition.addDynFieldList("members").setClassOfItems(FeatureQueryOrderMember.class);
374

  
375
    }
376

  
377
    @Override
378
    public void loadFromState(PersistentState state)
379
            throws PersistenceException {
380
        List<FeatureQueryOrderMember> stateMembers = (List) state.get("members");
381
        this.members = new ArrayList<>();
382
        for (FeatureQueryOrderMember stateMember : stateMembers) {
383
            this.members.add(stateMember);
384
        }
385
    }
386

  
387
    @Override
388
    public void saveToState(PersistentState state) throws PersistenceException {
389
        state.set("members", members);
390

  
391
    }
392

  
393
    private class DefaultFeatureComparator implements Comparator<Feature> {
394

  
395
        private final FeatureQueryOrder order;
396

  
397
        public DefaultFeatureComparator(FeatureQueryOrder order) {
398
            this.order = order;
399
            // TODO optimizar en un array???
400

  
401
        }
402

  
403
        private int myCompare(Object arg0, Object arg1) {
404
            if (arg0 == null) {
405
                if (arg1 == null) {
406
                    return 0;
407
                } else {
408
                    return 1;
409
                }
410
            } else if (arg1 == null) {
411
                if (arg0 == null) {
412
                    return 0;
413
                } else {
414
                    return 1;
415
                }
416
            }
417
            if (arg0 instanceof Comparable) {
418
                return ((Comparable) arg0).compareTo(arg1);
419
            } else if (arg1 instanceof Comparable) {
420
                return ((Comparable) arg1).compareTo(arg0) * -1;
421
            }
422

  
423
            if (arg0.equals(arg1)) {
424
                return 0;
425
            } else {
426
                return -1;
427
            }
428

  
429
        }
430

  
431
        @Override
432
        public int compare(Feature f0, Feature f1) {
433
            Iterator iter = this.order.iterator();
434
            int returnValue = 0;
435
//            Feature f0 = (Feature) arg0;
436
//            Feature f1 = (Feature) arg1;
437
            Object item;
438
            String attrName;
439
            Evaluator evaluator;
440
            while (returnValue == 0 && iter.hasNext()) {
441
                item = iter.next();
442
                if (item instanceof String) {
443
                    attrName = (String) item;
444
                    returnValue = this
445
                            .myCompare(f0.get(attrName), f1
446
                                    .get(attrName));
447
                } else {
448
                    evaluator = (Evaluator) item;
449
                    try {
450
                        returnValue = this.myCompare(evaluator
451
                                .evaluate((EvaluatorData) f0), evaluator
452
                                .evaluate((EvaluatorData) f1));
453
                    } catch (EvaluatorException e) {
454
                        throw new DataEvaluatorRuntimeException(e);
455
                    }
456
                }
457
            }
458

  
459
            return returnValue;
460
        }
461

  
462
    }
463

  
464 90
}

Also available in: Unified diff