Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dal / src-test / org / gvsig / fmap / dal / feature / impl / JoinTransform.java @ 28076

History | View | Annotate | Download (5.62 KB)

1
package org.gvsig.fmap.dal.feature.impl;
2

    
3
import java.util.Arrays;
4
import java.util.HashMap;
5
import java.util.Iterator;
6
import java.util.Map;
7

    
8
import org.gvsig.fmap.dal.DALLocator;
9
import org.gvsig.fmap.dal.exception.DataException;
10
import org.gvsig.fmap.dal.feature.AbstractFeatureStoreTransform;
11
import org.gvsig.fmap.dal.feature.EditableFeature;
12
import org.gvsig.fmap.dal.feature.EditableFeatureType;
13
import org.gvsig.fmap.dal.feature.Feature;
14
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
15
import org.gvsig.fmap.dal.feature.FeatureQuery;
16
import org.gvsig.fmap.dal.feature.FeatureSet;
17
import org.gvsig.fmap.dal.feature.FeatureStore;
18
import org.gvsig.fmap.dal.feature.FeatureType;
19
import org.gvsig.tools.evaluator.Evaluator;
20
import org.gvsig.tools.persistence.PersistenceException;
21
import org.gvsig.tools.persistence.PersistentState;
22

    
23
public class JoinTransform extends AbstractFeatureStoreTransform {
24

    
25
        /**
26
         * Store from which the join transform will get the additional attributes
27
         */
28
        private FeatureStore store2;
29

    
30
        /**
31
         * name of the key attr in store1 that will be used to match features in
32
         * store2
33
         */
34
        private String keyAttr1;
35

    
36
        /**
37
         * name of the key attr in store2 that will be used to match features in
38
         * store1
39
         */
40
        private String keyAttr2;
41

    
42
        /**
43
         * names of the attributes to join from store2 to store1
44
         */
45
        private String[] attrs;
46

    
47
        /**
48
         * Attribute names may change after transformation if they are repeated in
49
         * both stores. This map keeps correspondence between store2 original names
50
         * and their transformed counterparts.
51
         */
52
        private Map targetNamesMap;
53

    
54
        private FeatureType originalFeatureType;
55

    
56
        /**
57
         * A default constructor
58
         */
59
        public JoinTransform() {
60
                targetNamesMap = new HashMap();
61
        }
62

    
63
        /**
64
         * Initializes all the necessary data for this transform
65
         *
66
         * @param store1
67
         *            store whose default feature type is the target of this
68
         *            transform
69
         *
70
         * @param store2
71
         *            store whose default feature type will provide the new
72
         *            attributes to join
73
         *
74
         * @param keyAttr1
75
         *            key attribute in store1 that matches keyAttr2 in store2
76
         *            (foreign key), used for joining both stores.
77
         *
78
         * @param keyAttr2
79
         *            key attribute in store2 that matches keyAttr1 in store2
80
         *            (foreign key), used for joining both stores.
81
         *
82
         * @param attrs
83
         *            names of the attributes in store2 that will be joined to
84
         *            store1.
85
         */
86
        public void initialize(FeatureStore store1, FeatureStore store2,
87
                        String keyAttr1, String keyAttr2, String[] attrs)
88
                        throws DataException {
89

    
90
                // Initialize needed data
91
                this.setFeatureStore(store1);
92

    
93
                this.store2 = store2;
94
                this.keyAttr1 = keyAttr1;
95
                this.keyAttr2 = keyAttr2;
96
                this.attrs = attrs;
97
                this.originalFeatureType = this.getFeatureStore()
98
                                .getDefaultFeatureType();
99

    
100
                // calculate this transform resulting feature type
101
                // by adding all specified attrs from store2 to store1's default
102
                // feature type
103
                EditableFeatureType type = this.getFeatureStore().getDefaultFeatureType().getEditable();
104

    
105
                for (int i = 0; i < attrs.length; i++) {
106
                        String name = attrs[i];
107

    
108
                        // If an attribute already exists with the same name in store1's
109
                        // default feature type,
110
                        // calculate an alternate name and add it to our type
111
                        int j = 0;
112
                        while (type.getIndex(name) >= 0) {
113
                                name = attrs[i] + "_" + ++j;
114
                        }
115
                        type.add(name, store2.getDefaultFeatureType()
116
                                        .getAttributeDescriptor(attrs[i]).getDataType());
117

    
118
                        // keep correspondence between original name and transformed name
119
                        this.targetNamesMap.put(attrs[i], name);
120
                }
121

    
122
                // assign calculated feature type as this transform's feature type
123
                FeatureType[] types = new FeatureType[] { type.getNotEditableCopy() };
124
                setFeatureTypes(Arrays.asList(types), types[0]);
125
        }
126

    
127
        /**
128
         *
129
         *
130
         * @param source
131
         *
132
         * @param target
133
         *
134
         * @throws DataException
135
         */
136
        public void applyTransform(Feature source, EditableFeature target)
137
                        throws DataException {
138

    
139
                // copy the data from store1 into the resulting feature
140
                target.copyFrom(source);
141

    
142
                // ask store2 for the specified attributes, filtering by the key
143
                // attribute value
144
                // from the source feature
145
                Evaluator eval = DALLocator.getDataManager().createExpresion(
146
                                keyAttr2 + "=" + source.get(keyAttr1));
147
                FeatureQuery query = this.getFeatureStore().createFeatureQuery();
148
                query.setAttributeNames(attrs);
149
                query.setFilter(eval);
150
                FeatureSet set = store2.getFeatureSet(query);
151

    
152
                // In this join implementation, we will take only the first matching
153
                // feature found in store2
154
                Iterator it = set.iterator();
155
                if (it.hasNext()) {
156
                        Feature feat = (Feature) it.next();
157

    
158
                        // copy all attributes from joined feature to target
159
                        Iterator it2 = feat.getType().iterator();
160
                        while (it2.hasNext()) {
161
                                FeatureAttributeDescriptor attr = (FeatureAttributeDescriptor) it2
162
                                                .next();
163
                                // find original attribute name
164
                                String targetName = (String) this.targetNamesMap.get(attr
165
                                                .getName());
166
                                // copy its value to target feature attribute
167
                                target.set(targetName, feat.get(attr.getName()));
168
                        }
169
                }
170
                set.dispose();
171
        }
172

    
173
        public void saveToState(PersistentState state) throws PersistenceException {
174
                // TODO Auto-generated method stub
175

    
176
        }
177

    
178
        public void setState(PersistentState state) throws PersistenceException {
179
                // TODO Auto-generated method stub
180

    
181
        }
182

    
183
        /*
184
         * (non-Javadoc)
185
         *
186
         * @see
187
         * org.gvsig.fmap.dal.feature.FeatureStoreTransform#getSourceFeatureTypeFrom
188
         * (org.gvsig.fmap.dal.feature.FeatureType)
189
         */
190
        public FeatureType getSourceFeatureTypeFrom(FeatureType targetFeatureType) {
191
                return this.originalFeatureType;
192
        }
193

    
194
        public boolean isTransformsOriginalValues() {
195
                return false;
196
        }
197

    
198
}