Statistics
| Revision:

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

History | View | Annotate | Download (5.09 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
        /**
55
         * A default constructor
56
         */
57
        public JoinTransform() {
58
                targetNamesMap = new HashMap();
59
        }
60

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

    
88
                // Initialize needed data
89
                this.setFeatureStore(store1);
90
                this.store2 = store2;
91
                this.keyAttr1 = keyAttr1;
92
                this.keyAttr2 = keyAttr2;
93
                this.attrs = attrs;
94

    
95
                // calculate this transform resulting feature type
96
                // by adding all specified attrs from store2 to store1's default
97
                // feature type
98
                EditableFeatureType type = this.getFeatureStore().getDefaultFeatureType().getEditable();
99

    
100
                for (int i = 0; i < attrs.length; i++) {
101
                        String name = attrs[i];
102

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

    
113
                        // keep correspondence between original name and transformed name
114
                        this.targetNamesMap.put(attrs[i], name);
115
                }
116

    
117
                // assign calculated feature type as this transform's feature type
118
                FeatureType[] types = new FeatureType[] { type.getNotEditableCopy() };
119
                setFeatureTypes(Arrays.asList(types), types[0]);
120
        }
121

    
122
        /**
123
         * 
124
         * 
125
         * @param source
126
         * 
127
         * @param target
128
         * 
129
         * @throws DataException
130
         */
131
        public void applyTransform(Feature source, EditableFeature target)
132
                        throws DataException {
133

    
134
                // copy the data from store1 into the resulting feature
135
                target.copyFrom(source);
136

    
137
                // ask store2 for the specified attributes, filtering by the key
138
                // attribute value
139
                // from the source feature
140
                Evaluator eval = DALLocator.getDataManager().createExpresion(
141
                                keyAttr2 + "=" + source.get(keyAttr1));
142
                FeatureQuery query = new FeatureQuery(attrs, eval);
143
                FeatureSet set = store2.getFeatureSet(query);
144

    
145
                // In this join implementation, we will take only the first matching
146
                // feature found in store2
147
                Iterator it = set.iterator();
148
                if (it.hasNext()) {
149
                        Feature feat = (Feature) it.next();
150

    
151
                        // copy all attributes from joined feature to target
152
                        Iterator it2 = feat.getType().iterator();
153
                        while (it2.hasNext()) {
154
                                FeatureAttributeDescriptor attr = (FeatureAttributeDescriptor) it2
155
                                                .next();
156
                                // find original attribute name
157
                                String targetName = (String) this.targetNamesMap.get(attr
158
                                                .getName());
159
                                // copy its value to target feature attribute
160
                                target.set(targetName, feat.get(attr.getName()));
161
                        }
162
                }
163
                set.dispose();
164
        }
165

    
166
        public void loadState(PersistentState state) throws PersistenceException {
167
                // TODO Auto-generated method stub
168

    
169
        }
170

    
171
        public void setState(PersistentState state) throws PersistenceException {
172
                // TODO Auto-generated method stub
173

    
174
        }
175

    
176
}