Statistics
| Revision:

svn-gvsig-desktop / 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 @ 43987

History | View | Annotate | Download (9.97 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * 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
 *
11
 * 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
 *
16
 * 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
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.feature;
24

    
25
import java.util.ArrayList;
26
import java.util.Comparator;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.NoSuchElementException;
30
import org.apache.commons.lang3.StringUtils;
31

    
32
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
33
import org.gvsig.tools.evaluator.Evaluator;
34
import org.gvsig.tools.evaluator.EvaluatorData;
35
import org.gvsig.tools.evaluator.EvaluatorException;
36
import org.gvsig.tools.lang.Cloneable;
37
import org.gvsig.tools.persistence.Persistent;
38
import org.gvsig.tools.persistence.PersistentState;
39
import org.gvsig.tools.persistence.exception.PersistenceException;
40

    
41
public class FeatureQueryOrder implements Persistent, Cloneable {
42

    
43
    public class FeatureQueryOrderMember implements Persistent, org.gvsig.tools.lang.Cloneable {
44

    
45
        String attributeName = null;
46
        Evaluator evaluator = null;
47
        boolean ascending;
48

    
49
        FeatureQueryOrderMember(String attributeName, boolean ascending) {
50
            this.attributeName = attributeName;
51
            this.ascending = ascending;
52
        }
53

    
54
        FeatureQueryOrderMember(Evaluator evaluator, boolean ascending) {
55
            this.evaluator = evaluator;
56
            this.ascending = ascending;
57
        }
58

    
59
        public boolean hasEvaluator() {
60
            return this.evaluator != null;
61
        }
62

    
63
        public Evaluator getEvaluator() {
64
            return this.evaluator;
65
        }
66

    
67
        public boolean getAscending() {
68
            return this.ascending;
69
        }
70

    
71
        public String getAttributeName() {
72
            return this.attributeName;
73
        }
74

    
75
        @Override
76
        public void loadFromState(PersistentState state)
77
                throws PersistenceException {
78
            this.attributeName = state.getString("attributeName");
79
            this.ascending = state.getBoolean("ascending");
80
            this.evaluator = (Evaluator) state.get("evaluator");
81
        }
82

    
83
        @Override
84
        public void saveToState(PersistentState state)
85
                throws PersistenceException {
86
            state.set("attributeName", this.attributeName);
87
            state.set("ascending", this.ascending);
88
            if (this.evaluator != null) {
89
                state.set("evaluator", evaluator);
90
            }
91

    
92
        }
93

    
94
        @Override
95
        public FeatureQueryOrderMember clone() throws CloneNotSupportedException {
96
            // Nothing more to clone
97
            return (FeatureQueryOrderMember) super.clone();
98
        }
99

    
100
    }
101

    
102
    private List members = new ArrayList();
103

    
104
    public FeatureQueryOrder() {
105
    }
106
        
107
    public Object add(String order) {
108
        if( StringUtils.isEmpty(order) ) {
109
            return null;
110
        }
111
        Object r = null;
112
        String[] attributes = StringUtils.split(order, ',');
113
        for (String attribute : attributes) {
114
            boolean ascending = true;
115
            if( attribute.startsWith("+") ) {
116
                ascending = true;
117
                attribute = attribute.substring(1);
118
            } else if( attribute.startsWith("-") ) {
119
                ascending = false;
120
                attribute = attribute.substring(1);
121
            }
122
            attribute = attribute.trim();
123
            r = this.add(attribute,ascending);
124
        }
125
        return r;
126
    }
127
    
128
    public Object add(String attributeName, boolean ascending) {
129
        FeatureQueryOrderMember member = new FeatureQueryOrderMember(
130
                attributeName, ascending);
131
        if (members.add(member)) {
132
            return member;
133
        }
134
        return null;
135
    }
136

    
137
    public Object add(Evaluator evaluator, boolean ascending) {
138
        FeatureQueryOrderMember member = new FeatureQueryOrderMember(
139
                evaluator,
140
                ascending);
141
        if (members.add(member)) {
142
            return member;
143
        }
144
        return null;
145
    }
146

    
147
    public Iterable<FeatureQueryOrderMember> members() {
148
        //    Me hubiese gustado que FeatureQueryOrder fuese Iterable, pero no se deja por 
149
        //    que FeatureQueryOrderMember es una clase interna y no esta definida en el 
150
        //    momento de poner el :
151
        //            implements Iterable<FeatureQueryOrderMember>
152
        //    Y si saco a una clase independiente FeatureQueryOrderMember se pierde 
153
        //    compatibilidad binaria con quien la esta usando.
154
        //    Para rodearlo, he creado el metodo members.
155
        return new Iterable<FeatureQueryOrderMember> () {
156

    
157
            @Override
158
            public Iterator<FeatureQueryOrderMember> iterator() {
159
                return FeatureQueryOrder.this.iterator();
160
            }
161
        };
162
    }
163
    
164
    public Iterator<FeatureQueryOrderMember> iterator() {
165
        if (members == null) {
166
            return new Iterator<FeatureQueryOrderMember>() {
167
                @Override
168
                public boolean hasNext() {
169
                    return false;
170
                }
171

    
172
                @Override
173
                public FeatureQueryOrderMember next() {
174
                    throw new NoSuchElementException();
175
                }
176

    
177
                @Override
178
                public void remove() {
179
                    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
180
                }
181
            };
182
        }
183
        return members.iterator();
184
    }
185

    
186
    public boolean remove(FeatureQueryOrderMember member) {
187
        return members.remove(member);
188
    }
189

    
190
    public void remove(int index) {
191
        members.remove(index);
192
    }
193

    
194
    public void clear() {
195
        members.clear();
196
    }
197

    
198
    public int size() {
199
        return this.members.size();
200
    }
201

    
202
    public Comparator getFeatureComparator() {
203
        return new DefaultFeatureComparator(this);
204
    }
205

    
206
    public Object clone() throws CloneNotSupportedException {
207
        FeatureQueryOrder clone = (FeatureQueryOrder) super.clone();
208

    
209
        if (members != null) {
210
            clone.members = new ArrayList(members.size());
211
            for (int i = 0; i < members.size(); i++) {
212
                clone.members.add(((Cloneable) members.get(i)).clone());
213
            }
214
        }
215

    
216
        return clone;
217
    }
218

    
219
    public FeatureQueryOrder getCopy() {
220
        FeatureQueryOrder aCopy = new FeatureQueryOrder();
221
        Iterator iter = this.members.iterator();
222
        FeatureQueryOrderMember member;
223
        while (iter.hasNext()) {
224
            member = (FeatureQueryOrderMember) iter.next();
225
            if (member.hasEvaluator()) {
226
                aCopy.add(member.getEvaluator(), member.getAscending());
227
            } else {
228
                aCopy.add(member.getAttributeName(), member.getAscending());
229
            }
230
        }
231
        return aCopy;
232
    }
233

    
234
    public void loadFromState(PersistentState state)
235
            throws PersistenceException {
236
        this.members = (List) state.get("menbers");
237
    }
238

    
239
    public void saveToState(PersistentState state) throws PersistenceException {
240
        state.set("menbers", members);
241
    }
242

    
243
    private class DefaultFeatureComparator implements Comparator {
244

    
245
        private FeatureQueryOrder order;
246

    
247
        public DefaultFeatureComparator(FeatureQueryOrder order) {
248
            this.order = order;
249
            // TODO optimizar en un array???
250

    
251
        }
252

    
253
        private int myCompare(Object arg0, Object arg1) {
254
            if (arg0 == null) {
255
                if (arg1 == null) {
256
                    return 0;
257
                } else {
258
                    return 1;
259
                }
260
            } else if (arg1 == null) {
261
                if (arg0 == null) {
262
                    return 0;
263
                } else {
264
                    return 1;
265
                }
266
            }
267
            if (arg0 instanceof Comparable) {
268
                return ((Comparable) arg0).compareTo(arg1);
269
            } else if (arg1 instanceof Comparable) {
270
                return ((Comparable) arg1).compareTo(arg0) * -1;
271
            }
272

    
273
            if (arg0.equals(arg1)) {
274
                return 0;
275
            } else {
276
                return -1;
277
            }
278

    
279
        }
280

    
281
        public int compare(Object arg0, Object arg1) {
282
            Iterator iter = this.order.iterator();
283
            int returnValue = 0;
284
            Feature f0 = (Feature) arg0;
285
            Feature f1 = (Feature) arg1;
286
            Object item;
287
            String attrName;
288
            Evaluator evaluator;
289
            while (returnValue == 0 && iter.hasNext()) {
290
                item = iter.next();
291
                if (item instanceof String) {
292
                    attrName = (String) item;
293
                    returnValue = this
294
                            .myCompare(f0.get(attrName), f1
295
                                    .get(attrName));
296
                } else {
297
                    evaluator = (Evaluator) item;
298
                    try {
299
                        returnValue = this.myCompare(evaluator
300
                                .evaluate((EvaluatorData) f0), evaluator
301
                                .evaluate((EvaluatorData) f1));
302
                    } catch (EvaluatorException e) {
303
                        throw new DataEvaluatorRuntimeException(e);
304
                    }
305
                }
306
            }
307

    
308
            return returnValue;
309
        }
310

    
311
    }
312

    
313
}