Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / DefaultFeatureIndexes.java @ 36207

History | View | Annotate | Download (7.31 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
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
 * as published by the Free Software Foundation; either version 2
9
 * 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
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 {{Company}}   {{Task}}
26
 */
27

    
28
package org.gvsig.fmap.dal.feature.impl;
29

    
30
import java.util.ArrayList;
31
import java.util.HashMap;
32
import java.util.Iterator;
33
import java.util.List;
34
import java.util.Map;
35

    
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

    
39
import org.gvsig.fmap.dal.exception.DataException;
40
import org.gvsig.fmap.dal.feature.FeatureIndex;
41
import org.gvsig.fmap.dal.feature.FeatureIndexes;
42
import org.gvsig.fmap.dal.feature.FeatureSet;
43
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
44
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
45
import org.gvsig.tools.evaluator.Evaluator;
46
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
47
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch;
48
import org.gvsig.tools.evaluator.EvaluatorFieldValueNearest;
49
import org.gvsig.tools.evaluator.EvaluatorFieldValueRange;
50

    
51
/**
52
 * This class provides access to a FeatureStore local indexes and also decides
53
 * which index to use given an evaluator containing the filter expression.
54
 *
55
 * @author jyarza
56
 */
57
public class DefaultFeatureIndexes implements FeatureIndexes {
58
        private static final Logger logger = LoggerFactory
59
                        .getLogger(DefaultFeatureIndexes.class);
60
        // Access by index name
61
        private Map names;
62
    // Store to which this belongs
63
    private DefaultFeatureStore store;
64

    
65
        /**
66
         * Creates an empty DataIndexes for the given FeatureStore
67
         *
68
         * @param store
69
         *            FeatureStore to whom this belongs
70
         * @throws DataException
71
         */
72
        public DefaultFeatureIndexes(DefaultFeatureStore store)
73
                        throws DataException {
74
                names = new HashMap();
75
                this.store = store;
76
        }
77

    
78
        /*
79
         * (non-Javadoc)
80
         *
81
         * @see org.gvsig.fmap.dal.index.DataIndexes#getDataIndex(java.lang.String)
82
         */
83
        public FeatureIndex getFeatureIndex(String name) {
84
                return (FeatureIndex) names.get(name);
85
        }
86

    
87
        /*
88
         * (non-Javadoc)
89
         *
90
         * @see org.gvsig.fmap.dal.index.DataIndexes#addIndex(org.gvsig.fmap.dal.feature.FeatureType,
91
         *      java.lang.String, org.gvsig.fmap.dal.feature.DataIndex)
92
         */
93
        public void addIndex(FeatureIndexProviderServices index) {
94
                // By name
95
                names.put(index.getName(), index);
96
        }
97

    
98
        public Iterator iterator() {
99
                return names.values().iterator();
100
        }
101

    
102
        /**
103
         * Using the given evaluator attributes, choose and use an appropriate index
104
         * to obtain a FeatureSet. If no index can be applied, then this method
105
         * returns null
106
         *
107
         * @param evaluator
108
         * @return FeatureSet or null if could not find any appropriate index.
109
         * @throws FeatureIndexException
110
         *
111
         */
112
        public FeatureSet getFeatureSet(Evaluator evaluator)
113
                        throws FeatureIndexException {
114

    
115
                class ApplyIndex {
116
                        DefaultFeatureIndex index;
117
                        EvaluatorFieldValue[] data;
118

    
119
                        ApplyIndex(DefaultFeatureIndex index, EvaluatorFieldValue[] data) {
120
                                this.index = index;
121
                                this.data = data;
122
                        }
123

    
124
                        /**
125
                         * Checks whether the index supports the evaluator request
126
                         *
127
                         * @return
128
                         */
129
                        boolean isSupported() {
130
                                switch (data[0].getType()) {
131
                                case EvaluatorFieldValue.MATCH:
132
                                        return index.getFeatureIndexProvider().isMatchSupported();
133
                                case EvaluatorFieldValue.NEAREST:
134
                                        return index.getFeatureIndexProvider().isNearestSupported();
135
                                case EvaluatorFieldValue.RANGE:
136
                                        return index.getFeatureIndexProvider().isRangeSupported();
137
                                default:
138
                                        return false;
139
                                }
140
                        }
141

    
142
                        /**
143
                         * Applies the index using the evaluator fields
144
                         *
145
                         * @return FeatureSet with the result
146
                         * @throws FeatureIndexException
147
                         */
148
                        IndexFeatureSet apply() throws FeatureIndexException {
149

    
150
                                EvaluatorFieldValueRange rangeField;
151
                                EvaluatorFieldValueNearest nearestField;
152
                                // Trick: we know DefaultIndexProvider returns an IndexFeatureSet,
153
                                // which implements both FeatureSetProvider and FeatureSet.
154
                                switch (data[0].getType()) {
155
                                case EvaluatorFieldValue.MATCH:
156
                                        return (IndexFeatureSet) index.getMatchFeatureSet(
157
                                                        ((EvaluatorFieldValueMatch) data[0])
158
                                                                        .getValue());
159
                                case EvaluatorFieldValue.RANGE:
160
                                        rangeField = (EvaluatorFieldValueRange) data[0];
161
                                        return (IndexFeatureSet) index.getRangeFeatureSet(
162
                                                        rangeField.getValue1(), rangeField.getValue2());
163
                                case EvaluatorFieldValue.NEAREST:
164
                                        nearestField = (EvaluatorFieldValueNearest) data[0];
165
                                        if ((nearestField.getTolerance() == null)
166
                                                        || (!isSupported())) {
167
                                                return (IndexFeatureSet) index.getNearestFeatureSet(
168
                                                                nearestField.getCount(), nearestField
169
                                                                                .getValue());
170
                                        } else {
171
                                                return (IndexFeatureSet) index.getNearestFeatureSet(
172
                                                                nearestField.getCount(), nearestField
173
                                                                                .getValue(), nearestField
174
                                                                                .getTolerance());
175
                                        }
176
                                }
177
                                return null;
178
                        }
179
                }
180

    
181
                // Select applicable indexes
182
                List applyIndexes = new ArrayList();
183
                Iterator indexes = this.iterator();
184
                while (indexes.hasNext()) {
185
                        DefaultFeatureIndex index = (DefaultFeatureIndex) indexes.next();
186
            if (index.isValid()) {
187
                String[] attrs =
188
                    (String[]) index.getAttributeNames().toArray(new String[0]);
189
                for (int i = 0; i < attrs.length; i++) {
190
                    String attrname = attrs[i];
191
                    EvaluatorFieldValue[] values = null;
192
                    if (evaluator.getFieldsInfo() != null) {
193
                        values =
194
                            evaluator.getFieldsInfo().getFieldValues(attrname);
195
                    }
196
                    if (values != null) {
197
                        applyIndexes.add(new ApplyIndex(index, values));
198
                        break;
199
                    }
200
                }
201
            }
202
                }
203

    
204
                // If there's not any applicable index, return null
205
                if (applyIndexes.size() == 0) {
206
                        return null;
207
                }
208

    
209
                // Lookup an index with support for the requested function
210
                Iterator it = applyIndexes.iterator();
211
                ApplyIndex index = (ApplyIndex) it.next();
212
                while (it.hasNext() && (!index.isSupported())) {
213
                        index = (ApplyIndex) it.next();
214
                }
215

    
216
                // If there is not any any index supporting the function, use the
217
                // first one
218
                if (!index.isSupported()) {
219
                        logger
220
                                        .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
}