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 @ 44154

History | View | Annotate | Download (9.97 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 40435 jjdelcerro
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 43020 jjdelcerro
import java.util.NoSuchElementException;
30 43987 jjdelcerro
import org.apache.commons.lang3.StringUtils;
31 40435 jjdelcerro
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 43026 jjdelcerro
public class FeatureQueryOrder implements Persistent, Cloneable {
42 40435 jjdelcerro
43 43026 jjdelcerro
    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 43020 jjdelcerro
    private List members = new ArrayList();
103 40435 jjdelcerro
104 43026 jjdelcerro
    public FeatureQueryOrder() {
105
    }
106
107 43987 jjdelcerro
    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 43020 jjdelcerro
    public Object add(String attributeName, boolean ascending) {
129 40435 jjdelcerro
        FeatureQueryOrderMember member = new FeatureQueryOrderMember(
130
                attributeName, ascending);
131 43020 jjdelcerro
        if (members.add(member)) {
132
            return member;
133
        }
134
        return null;
135
    }
136 40435 jjdelcerro
137 43020 jjdelcerro
    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 40435 jjdelcerro
147 43026 jjdelcerro
    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 43020 jjdelcerro
    public Iterator<FeatureQueryOrderMember> iterator() {
165 43026 jjdelcerro
        if (members == null) {
166 43020 jjdelcerro
            return new Iterator<FeatureQueryOrderMember>() {
167
                @Override
168
                public boolean hasNext() {
169
                    return false;
170
                }
171 40435 jjdelcerro
172 43020 jjdelcerro
                @Override
173
                public FeatureQueryOrderMember next() {
174
                    throw new NoSuchElementException();
175
                }
176 40435 jjdelcerro
177 43020 jjdelcerro
                @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 40435 jjdelcerro
186 43020 jjdelcerro
    public boolean remove(FeatureQueryOrderMember member) {
187
        return members.remove(member);
188
    }
189 40435 jjdelcerro
190 43020 jjdelcerro
    public void remove(int index) {
191
        members.remove(index);
192
    }
193 40435 jjdelcerro
194 43020 jjdelcerro
    public void clear() {
195
        members.clear();
196
    }
197 40435 jjdelcerro
198 43020 jjdelcerro
    public int size() {
199
        return this.members.size();
200
    }
201 40435 jjdelcerro
202 43020 jjdelcerro
    public Comparator getFeatureComparator() {
203
        return new DefaultFeatureComparator(this);
204
    }
205 40435 jjdelcerro
206 43020 jjdelcerro
    public Object clone() throws CloneNotSupportedException {
207
        FeatureQueryOrder clone = (FeatureQueryOrder) super.clone();
208 40435 jjdelcerro
209 43020 jjdelcerro
        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 40435 jjdelcerro
216 43020 jjdelcerro
        return clone;
217
    }
218 40435 jjdelcerro
219 43020 jjdelcerro
    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 40435 jjdelcerro
234 43020 jjdelcerro
    public void loadFromState(PersistentState state)
235
            throws PersistenceException {
236
        this.members = (List) state.get("menbers");
237
    }
238 40435 jjdelcerro
239 43020 jjdelcerro
    public void saveToState(PersistentState state) throws PersistenceException {
240
        state.set("menbers", members);
241
    }
242 40435 jjdelcerro
243 43020 jjdelcerro
    private class DefaultFeatureComparator implements Comparator {
244 40435 jjdelcerro
245 43020 jjdelcerro
        private FeatureQueryOrder order;
246 40435 jjdelcerro
247 43020 jjdelcerro
        public DefaultFeatureComparator(FeatureQueryOrder order) {
248
            this.order = order;
249
            // TODO optimizar en un array???
250 40435 jjdelcerro
251 43020 jjdelcerro
        }
252 40435 jjdelcerro
253 43020 jjdelcerro
        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 40435 jjdelcerro
273 43020 jjdelcerro
            if (arg0.equals(arg1)) {
274
                return 0;
275
            } else {
276
                return -1;
277
            }
278 40435 jjdelcerro
279 43020 jjdelcerro
        }
280 40435 jjdelcerro
281 43020 jjdelcerro
        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 40435 jjdelcerro
308 43020 jjdelcerro
            return returnValue;
309
        }
310 40435 jjdelcerro
311 43020 jjdelcerro
    }
312
313
}