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

History | View | Annotate | Download (8.8 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

    
59
    private static final Logger LOG = LoggerFactory
60
        .getLogger(DefaultFeatureIndexes.class);
61
    // Access by index name
62
    private Map names;
63
    // Store to which this belongs
64
    private DefaultFeatureStore store;
65

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

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

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

    
101
    public Iterator iterator() {
102
        return names.values().iterator();
103
    }
104

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

    
118
        class ApplyIndex {
119

    
120
            DefaultFeatureIndex index;
121
            EvaluatorFieldValue[] data;
122

    
123
            ApplyIndex(DefaultFeatureIndex index, EvaluatorFieldValue[] data) {
124
                this.index = index;
125
                this.data = data;
126
            }
127

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

    
146
            /**
147
             * Applies the index using the evaluator fields
148
             * 
149
             * @return FeatureSet with the result
150
             * @throws FeatureIndexException
151
             */
152
            IndexFeatureSet apply() throws FeatureIndexException {
153

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

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

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

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

    
219
        // If there is not any any index supporting the function, use the
220
        // first one
221
        if (!index.isSupported()) {
222
            LOG.info("No index support for the evaluator values. Using default index.");
223
            index = (ApplyIndex) applyIndexes.get(0);
224
        }
225

    
226
        // Apply index
227
        return index.apply();
228

    
229
    }
230

    
231
    public boolean areValid() {
232
        Iterator indexes = this.iterator();
233
        while (indexes.hasNext()) {
234
            FeatureIndex index = (FeatureIndex) indexes.next();
235
            if (!index.isValid()) {
236
                return false;
237
            }
238
        }
239
        return true;
240
    }
241

    
242
    public String toString() {
243
        StringBuffer text = new StringBuffer(super.toString());
244
        text.append(": [");
245
        Iterator indexes = this.iterator();
246
        while (indexes.hasNext()) {
247
            FeatureIndex index = (FeatureIndex) indexes.next();
248
            text.append(index);
249
            text.append("]");
250
            if (indexes.hasNext()) {
251
                text.append(", ");
252
            }
253
        }
254
        return text.toString();
255
    }
256
}