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 | 40435 | jjdelcerro | 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 | } |