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

History | View | Annotate | Download (8.85 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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2008 {{Company}}   {{Task}}
27
 */
28

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

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

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

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

    
52
/**
53
 * This class provides access to a FeatureStore local indexes and also decides
54
 * which index to use given an evaluator containing the filter expression.
55
 * 
56
 * @author jyarza
57
 */
58
public class DefaultFeatureIndexes implements FeatureIndexes {
59

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

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

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

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

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

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

    
119
        class ApplyIndex {
120

    
121
            DefaultFeatureIndex index;
122
            EvaluatorFieldValue[] data;
123

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

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

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

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

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

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

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

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

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

    
230
    }
231

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

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