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 @ 40559
History | View | Annotate | Download (6.78 KB)
1 | 40559 | jjdelcerro | /**
|
---|---|---|---|
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 | 40435 | jjdelcerro | package org.gvsig.fmap.dal.feature.impl; |
25 | |||
26 | import java.util.Arrays; |
||
27 | import java.util.HashMap; |
||
28 | import java.util.Iterator; |
||
29 | import java.util.Map; |
||
30 | |||
31 | import org.gvsig.fmap.dal.DALLocator; |
||
32 | import org.gvsig.fmap.dal.exception.DataException; |
||
33 | import org.gvsig.fmap.dal.feature.AbstractFeatureStoreTransform; |
||
34 | import org.gvsig.fmap.dal.feature.EditableFeature; |
||
35 | import org.gvsig.fmap.dal.feature.EditableFeatureType; |
||
36 | import org.gvsig.fmap.dal.feature.Feature; |
||
37 | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
||
38 | import org.gvsig.fmap.dal.feature.FeatureQuery; |
||
39 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
40 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
41 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
42 | import org.gvsig.tools.dispose.DisposableIterator; |
||
43 | import org.gvsig.tools.dispose.DisposeUtils; |
||
44 | import org.gvsig.tools.evaluator.Evaluator; |
||
45 | import org.gvsig.tools.persistence.PersistentState; |
||
46 | import org.gvsig.tools.persistence.exception.PersistenceException; |
||
47 | |||
48 | public class JoinTransform extends AbstractFeatureStoreTransform { |
||
49 | |||
50 | /**
|
||
51 | * Store from which the join transform will get the additional attributes
|
||
52 | */
|
||
53 | private FeatureStore store2;
|
||
54 | |||
55 | /**
|
||
56 | * name of the key attr in store1 that will be used to match features in
|
||
57 | * store2
|
||
58 | */
|
||
59 | private String keyAttr1; |
||
60 | |||
61 | /**
|
||
62 | * name of the key attr in store2 that will be used to match features in
|
||
63 | * store1
|
||
64 | */
|
||
65 | private String keyAttr2; |
||
66 | |||
67 | /**
|
||
68 | * names of the attributes to join from store2 to store1
|
||
69 | */
|
||
70 | private String[] attrs; |
||
71 | |||
72 | /**
|
||
73 | * Attribute names may change after transformation if they are repeated in
|
||
74 | * both stores. This map keeps correspondence between store2 original names
|
||
75 | * and their transformed counterparts.
|
||
76 | */
|
||
77 | private Map targetNamesMap; |
||
78 | |||
79 | private FeatureType originalFeatureType;
|
||
80 | |||
81 | /**
|
||
82 | * A default constructor
|
||
83 | */
|
||
84 | public JoinTransform() {
|
||
85 | targetNamesMap = new HashMap(); |
||
86 | } |
||
87 | |||
88 | /**
|
||
89 | * Initializes all the necessary data for this transform
|
||
90 | *
|
||
91 | * @param store1
|
||
92 | * store whose default feature type is the target of this
|
||
93 | * transform
|
||
94 | *
|
||
95 | * @param store2
|
||
96 | * store whose default feature type will provide the new
|
||
97 | * attributes to join
|
||
98 | *
|
||
99 | * @param keyAttr1
|
||
100 | * key attribute in store1 that matches keyAttr2 in store2
|
||
101 | * (foreign key), used for joining both stores.
|
||
102 | *
|
||
103 | * @param keyAttr2
|
||
104 | * key attribute in store2 that matches keyAttr1 in store2
|
||
105 | * (foreign key), used for joining both stores.
|
||
106 | *
|
||
107 | * @param attrs
|
||
108 | * names of the attributes in store2 that will be joined to
|
||
109 | * store1.
|
||
110 | */
|
||
111 | public void initialize(FeatureStore store1, FeatureStore store2, |
||
112 | String keyAttr1, String keyAttr2, String[] attrs) |
||
113 | throws DataException {
|
||
114 | |||
115 | // Initialize needed data
|
||
116 | this.setFeatureStore(store1);
|
||
117 | |||
118 | this.store2 = store2;
|
||
119 | this.keyAttr1 = keyAttr1;
|
||
120 | this.keyAttr2 = keyAttr2;
|
||
121 | this.attrs = attrs;
|
||
122 | this.originalFeatureType = this.getFeatureStore() |
||
123 | .getDefaultFeatureType(); |
||
124 | |||
125 | // calculate this transform resulting feature type
|
||
126 | // by adding all specified attrs from store2 to store1's default
|
||
127 | // feature type
|
||
128 | EditableFeatureType type = this.getFeatureStore().getDefaultFeatureType().getEditable();
|
||
129 | |||
130 | for (int i = 0; i < attrs.length; i++) { |
||
131 | String name = attrs[i];
|
||
132 | |||
133 | // If an attribute already exists with the same name in store1's
|
||
134 | // default feature type,
|
||
135 | // calculate an alternate name and add it to our type
|
||
136 | int j = 0; |
||
137 | while (type.getIndex(name) >= 0) { |
||
138 | name = attrs[i] + "_" + ++j;
|
||
139 | } |
||
140 | type.add(name, store2.getDefaultFeatureType() |
||
141 | .getAttributeDescriptor(attrs[i]).getType()); |
||
142 | |||
143 | // keep correspondence between original name and transformed name
|
||
144 | this.targetNamesMap.put(attrs[i], name);
|
||
145 | } |
||
146 | |||
147 | // assign calculated feature type as this transform's feature type
|
||
148 | FeatureType[] types = new FeatureType[] { type.getNotEditableCopy() }; |
||
149 | setFeatureTypes(Arrays.asList(types), types[0]); |
||
150 | } |
||
151 | |||
152 | /**
|
||
153 | *
|
||
154 | *
|
||
155 | * @param source
|
||
156 | *
|
||
157 | * @param target
|
||
158 | *
|
||
159 | * @throws DataException
|
||
160 | */
|
||
161 | public void applyTransform(Feature source, EditableFeature target) |
||
162 | throws DataException {
|
||
163 | |||
164 | // copy the data from store1 into the resulting feature
|
||
165 | target.copyFrom(source); |
||
166 | |||
167 | // ask store2 for the specified attributes, filtering by the key
|
||
168 | // attribute value
|
||
169 | // from the source feature
|
||
170 | Evaluator eval = DALLocator.getDataManager().createExpresion( |
||
171 | keyAttr2 + "=" + source.get(keyAttr1));
|
||
172 | FeatureQuery query = this.getFeatureStore().createFeatureQuery();
|
||
173 | query.setAttributeNames(attrs); |
||
174 | query.setFilter(eval); |
||
175 | |||
176 | FeatureSet set = null;
|
||
177 | DisposableIterator it = null;
|
||
178 | |||
179 | try {
|
||
180 | set = store2.getFeatureSet(query); |
||
181 | |||
182 | // In this join implementation, we will take only the first matching
|
||
183 | // feature found in store2
|
||
184 | it = set.iterator(); |
||
185 | if (it.hasNext()) {
|
||
186 | Feature feat = (Feature) it.next(); |
||
187 | |||
188 | // copy all attributes from joined feature to target
|
||
189 | Iterator it2 = feat.getType().iterator();
|
||
190 | while (it2.hasNext()) {
|
||
191 | FeatureAttributeDescriptor attr = |
||
192 | (FeatureAttributeDescriptor) it2.next(); |
||
193 | // find original attribute name
|
||
194 | String targetName =
|
||
195 | (String) this.targetNamesMap.get(attr.getName()); |
||
196 | // copy its value to target feature attribute
|
||
197 | target.set(targetName, feat.get(attr.getName())); |
||
198 | } |
||
199 | } |
||
200 | } finally {
|
||
201 | DisposeUtils.dispose(set); |
||
202 | DisposeUtils.dispose(it); |
||
203 | } |
||
204 | } |
||
205 | |||
206 | public void saveToState(PersistentState state) throws PersistenceException { |
||
207 | // TODO Auto-generated method stub
|
||
208 | |||
209 | } |
||
210 | |||
211 | public void loadFromState(PersistentState state) throws PersistenceException { |
||
212 | // TODO Auto-generated method stub
|
||
213 | |||
214 | } |
||
215 | |||
216 | /*
|
||
217 | * (non-Javadoc)
|
||
218 | *
|
||
219 | * @see
|
||
220 | * org.gvsig.fmap.dal.feature.FeatureStoreTransform#getSourceFeatureTypeFrom
|
||
221 | * (org.gvsig.fmap.dal.feature.FeatureType)
|
||
222 | */
|
||
223 | public FeatureType getSourceFeatureTypeFrom(FeatureType targetFeatureType) {
|
||
224 | return this.originalFeatureType; |
||
225 | } |
||
226 | |||
227 | public boolean isTransformsOriginalValues() { |
||
228 | return false; |
||
229 | } |
||
230 | |||
231 | } |