Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / test / java / org / gvsig / fmap / dal / feature / impl / JoinTransform.java @ 40435

History | View | Annotate | Download (5.85 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.dispose.DisposableIterator;
20
import org.gvsig.tools.dispose.DisposeUtils;
21
import org.gvsig.tools.evaluator.Evaluator;
22
import org.gvsig.tools.persistence.PersistentState;
23
import org.gvsig.tools.persistence.exception.PersistenceException;
24

    
25
public class JoinTransform extends AbstractFeatureStoreTransform {
26

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

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

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

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

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

    
56
        private FeatureType originalFeatureType;
57

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

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

    
92
                // Initialize needed data
93
                this.setFeatureStore(store1);
94

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

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

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

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

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

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

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

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

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

    
153
                FeatureSet set = null;
154
                DisposableIterator it = null;
155

    
156
                try {
157
                        set = store2.getFeatureSet(query);
158

    
159
                        // In this join implementation, we will take only the first matching
160
                        // feature found in store2
161
                        it = set.iterator();
162
                        if (it.hasNext()) {
163
                                Feature feat = (Feature) it.next();
164

    
165
                                // copy all attributes from joined feature to target
166
                                Iterator it2 = feat.getType().iterator();
167
                                while (it2.hasNext()) {
168
                                        FeatureAttributeDescriptor attr =
169
                                                        (FeatureAttributeDescriptor) it2.next();
170
                                        // find original attribute name
171
                                        String targetName =
172
                                                        (String) this.targetNamesMap.get(attr.getName());
173
                                        // copy its value to target feature attribute
174
                                        target.set(targetName, feat.get(attr.getName()));
175
                                }
176
                        }
177
                } finally {
178
                        DisposeUtils.dispose(set);
179
                        DisposeUtils.dispose(it);
180
                }
181
        }
182

    
183
        public void saveToState(PersistentState state) throws PersistenceException {
184
                // TODO Auto-generated method stub
185

    
186
        }
187

    
188
        public void loadFromState(PersistentState state) throws PersistenceException {
189
                // TODO Auto-generated method stub
190

    
191
        }
192

    
193
        /*
194
         * (non-Javadoc)
195
         *
196
         * @see
197
         * org.gvsig.fmap.dal.feature.FeatureStoreTransform#getSourceFeatureTypeFrom
198
         * (org.gvsig.fmap.dal.feature.FeatureType)
199
         */
200
        public FeatureType getSourceFeatureTypeFrom(FeatureType targetFeatureType) {
201
                return this.originalFeatureType;
202
        }
203

    
204
        public boolean isTransformsOriginalValues() {
205
                return false;
206
        }
207

    
208
}