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 / DefaultFeatureIndexes.java @ 47784

History | View | Annotate | Download (8.84 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40559 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
 *
11
 * 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
 *
16
 * 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
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21 40559 jjdelcerro
 * 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
25
package org.gvsig.fmap.dal.feature.impl;
26
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Map;
32 47556 fdiaz
import org.apache.commons.lang3.ArrayUtils;
33 40435 jjdelcerro
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.feature.FeatureIndex;
39
import org.gvsig.fmap.dal.feature.FeatureIndexes;
40
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
42
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
43
import org.gvsig.tools.evaluator.Evaluator;
44
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
45
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch;
46
import org.gvsig.tools.evaluator.EvaluatorFieldValueNearest;
47
import org.gvsig.tools.evaluator.EvaluatorFieldValueRange;
48
49
/**
50
 * This class provides access to a FeatureStore local indexes and also decides
51
 * which index to use given an evaluator containing the filter expression.
52
 *
53
 * @author jyarza
54
 */
55
public class DefaultFeatureIndexes implements FeatureIndexes {
56
57
    private static final Logger LOG = LoggerFactory
58
        .getLogger(DefaultFeatureIndexes.class);
59
    // Access by index name
60
    private Map names;
61
    // Store to which this belongs
62
    private DefaultFeatureStore store;
63
64
    /**
65
     * Creates an empty DataIndexes for the given FeatureStore
66
     *
67
     * @param store
68
     *            FeatureStore to whom this belongs
69
     * @throws DataException
70
     */
71
    public DefaultFeatureIndexes(DefaultFeatureStore store)
72
        throws DataException {
73
        names = new HashMap();
74
        this.store = store;
75
    }
76
77
    /*
78
     * (non-Javadoc)
79
     *
80
     * @see org.gvsig.fmap.dal.index.DataIndexes#getDataIndex(java.lang.String)
81
     */
82
    public FeatureIndex getFeatureIndex(String name) {
83
        return (FeatureIndex) names.get(name);
84
    }
85
86
    /*
87
     * (non-Javadoc)
88
     *
89
     * @see
90
     * org.gvsig.fmap.dal.index.DataIndexes#addIndex(org.gvsig.fmap.dal.feature
91
     * .FeatureType,
92
     * java.lang.String, org.gvsig.fmap.dal.feature.DataIndex)
93
     */
94
    public void addIndex(FeatureIndexProviderServices index) {
95
        // By name
96
        names.put(index.getName(), index);
97
    }
98
99
    public Iterator iterator() {
100
        return names.values().iterator();
101
    }
102
103
    /**
104
     * Using the given evaluator attributes, choose and use an appropriate index
105
     * to obtain a FeatureSet. If no index can be applied, then this method
106
     * returns null
107
     *
108
     * @param evaluator
109
     * @return FeatureSet or null if could not find any appropriate index.
110
     * @throws FeatureIndexException
111
     *
112
     */
113
    public FeatureSet getFeatureSet(Evaluator evaluator)
114
        throws FeatureIndexException {
115
116
        class ApplyIndex {
117
118
            DefaultFeatureIndex index;
119
            EvaluatorFieldValue[] data;
120
121
            ApplyIndex(DefaultFeatureIndex index, EvaluatorFieldValue[] data) {
122
                this.index = index;
123
                this.data = data;
124
            }
125
126
            /**
127
             * Checks whether the index supports the evaluator request
128
             *
129
             * @return
130
             */
131
            boolean isSupported() {
132
                switch (data[0].getType()) {
133
                case EvaluatorFieldValue.MATCH:
134
                    return index.getFeatureIndexProvider().isMatchSupported();
135
                case EvaluatorFieldValue.NEAREST:
136
                    return index.getFeatureIndexProvider().isNearestSupported();
137
                case EvaluatorFieldValue.RANGE:
138
                    return index.getFeatureIndexProvider().isRangeSupported();
139
                default:
140
                    return false;
141
                }
142
            }
143
144
            /**
145
             * Applies the index using the evaluator fields
146
             *
147
             * @return FeatureSet with the result
148
             * @throws FeatureIndexException
149
             */
150
            IndexFeatureSet apply() throws FeatureIndexException {
151
152
                EvaluatorFieldValueRange rangeField;
153
                EvaluatorFieldValueNearest nearestField;
154
                // Trick: we know DefaultIndexProvider returns an
155
                // IndexFeatureSet,
156
                // which implements both FeatureSetProvider and FeatureSet.
157
                switch (data[0].getType()) {
158
                case EvaluatorFieldValue.MATCH:
159
                    return (IndexFeatureSet) index
160
                        .getMatchFeatureSet(((EvaluatorFieldValueMatch) data[0])
161
                            .getValue());
162
                case EvaluatorFieldValue.RANGE:
163
                    rangeField = (EvaluatorFieldValueRange) data[0];
164
                    return (IndexFeatureSet) index.getRangeFeatureSet(
165
                        rangeField.getValue1(), rangeField.getValue2());
166
                case EvaluatorFieldValue.NEAREST:
167
                    nearestField = (EvaluatorFieldValueNearest) data[0];
168
                    if ((nearestField.getTolerance() == null)
169
                        || (!isSupported())) {
170
                        return (IndexFeatureSet) index.getNearestFeatureSet(
171
                            nearestField.getCount(), nearestField.getValue());
172
                    } else {
173
                        return (IndexFeatureSet) index.getNearestFeatureSet(
174
                            nearestField.getCount(), nearestField.getValue(),
175
                            nearestField.getTolerance());
176
                    }
177
                }
178
                return null;
179
            }
180
        }
181
182
        // Select applicable indexes
183
        List applyIndexes = new ArrayList();
184
        Iterator indexes = this.iterator();
185
        while (indexes.hasNext()) {
186
            DefaultFeatureIndex index = (DefaultFeatureIndex) indexes.next();
187
            if (index.isValid()) {
188
                String[] attrs =
189
                    (String[]) index.getAttributeNames().toArray(new String[0]);
190
                for (int i = 0; i < attrs.length; i++) {
191
                    String attrname = attrs[i];
192
                    EvaluatorFieldValue[] values = null;
193
                    if (evaluator.getFieldsInfo() != null) {
194
                        values =
195
                            evaluator.getFieldsInfo().getFieldValues(attrname);
196
                    }
197 47556 fdiaz
                    if (ArrayUtils.isNotEmpty(values)) {
198 40435 jjdelcerro
                        applyIndexes.add(new ApplyIndex(index, values));
199
                        break;
200
                    }
201
                }
202
            }
203
        }
204
205
        // If there's not any applicable index, return null
206
        if (applyIndexes.size() == 0) {
207
            return null;
208
        }
209
210
        // Lookup an index with support for the requested function
211
        Iterator it = applyIndexes.iterator();
212
        ApplyIndex index = (ApplyIndex) it.next();
213
        while (it.hasNext() && (!index.isSupported())) {
214
            index = (ApplyIndex) it.next();
215
        }
216
217
        // If there is not any any index supporting the function, use the
218
        // first one
219
        if (!index.isSupported()) {
220
            LOG.info("No index support for the evaluator values. Using default index.");
221
            index = (ApplyIndex) applyIndexes.get(0);
222
        }
223
224
        // Apply index
225
        return index.apply();
226
227
    }
228
229
    public boolean areValid() {
230
        Iterator indexes = this.iterator();
231
        while (indexes.hasNext()) {
232
            FeatureIndex index = (FeatureIndex) indexes.next();
233
            if (!index.isValid()) {
234
                return false;
235
            }
236
        }
237
        return true;
238
    }
239
240
    public String toString() {
241
        StringBuffer text = new StringBuffer(super.toString());
242
        text.append(": [");
243
        Iterator indexes = this.iterator();
244
        while (indexes.hasNext()) {
245
            FeatureIndex index = (FeatureIndex) indexes.next();
246
            text.append(index);
247
            text.append("]");
248
            if (indexes.hasNext()) {
249
                text.append(", ");
250
            }
251
        }
252
        return text.toString();
253
    }
254
}