svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / DefaultFeatureStoreTransforms.java
History | View | Annotate | Download (14.5 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.ArrayList; |
||
27 | import java.util.Collections; |
||
28 | import java.util.Iterator; |
||
29 | import java.util.List; |
||
30 | import java.util.ListIterator; |
||
31 | |||
32 | import org.gvsig.fmap.dal.exception.DataException; |
||
33 | import org.gvsig.fmap.dal.feature.EditableFeature; |
||
34 | 44753 | omartinez | import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
35 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.EditableFeatureType; |
36 | import org.gvsig.fmap.dal.feature.Feature; |
||
37 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
38 | import org.gvsig.fmap.dal.feature.FeatureStoreNotification; |
||
39 | import org.gvsig.fmap.dal.feature.FeatureStoreTransform; |
||
40 | import org.gvsig.fmap.dal.feature.FeatureStoreTransforms; |
||
41 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
42 | import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
||
43 | import org.gvsig.tools.ToolsLocator; |
||
44 | import org.gvsig.tools.dynobject.DynStruct; |
||
45 | import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException; |
||
46 | import org.gvsig.tools.persistence.Persistent; |
||
47 | import org.gvsig.tools.persistence.PersistentState; |
||
48 | import org.gvsig.tools.persistence.exception.PersistenceException; |
||
49 | 44165 | jjdelcerro | import org.slf4j.Logger; |
50 | import org.slf4j.LoggerFactory; |
||
51 | 44829 | omartinez | import org.gvsig.fmap.dal.feature.FeatureExtraColumns; |
52 | 40435 | jjdelcerro | |
53 | 43215 | jjdelcerro | public class DefaultFeatureStoreTransforms |
54 | implements FeatureStoreTransforms,
|
||
55 | Persistent { |
||
56 | 40435 | jjdelcerro | |
57 | 44165 | jjdelcerro | private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureStoreTransforms.class); |
58 | |||
59 | 43215 | jjdelcerro | private DefaultFeatureStore store;
|
60 | private List<FeatureStoreTransform> transforms; |
||
61 | private Boolean isTramsformValues; |
||
62 | private TransformTemporalList lastTransformStack;
|
||
63 | 40435 | jjdelcerro | |
64 | 43215 | jjdelcerro | public DefaultFeatureStoreTransforms() {
|
65 | this.store = null; |
||
66 | this.transforms = new ArrayList(); |
||
67 | this.isTramsformValues = false; |
||
68 | } |
||
69 | 40435 | jjdelcerro | |
70 | 43215 | jjdelcerro | public DefaultFeatureStoreTransforms(DefaultFeatureStore store) {
|
71 | this.store = store;
|
||
72 | this.transforms = new ArrayList(); |
||
73 | } |
||
74 | 40435 | jjdelcerro | |
75 | 43215 | jjdelcerro | protected void checkEditingMode() { |
76 | if( store == null || store.getMode() != FeatureStore.MODE_QUERY ) { |
||
77 | throw new IllegalStateException(); |
||
78 | } |
||
79 | } |
||
80 | 40435 | jjdelcerro | |
81 | 43215 | jjdelcerro | protected void notifyChangeToStore() { |
82 | this.store.notifyChange(FeatureStoreNotification.TRANSFORM_CHANGE);
|
||
83 | } |
||
84 | 40435 | jjdelcerro | |
85 | 43215 | jjdelcerro | @Override
|
86 | public FeatureStoreTransform add(FeatureStoreTransform transform)
|
||
87 | throws DataException {
|
||
88 | checkEditingMode(); |
||
89 | 43399 | jjdelcerro | try {
|
90 | transform.setUp(); |
||
91 | } catch (Exception ex) { |
||
92 | throw new RuntimeException("Can't set up transformation.", ex); |
||
93 | } |
||
94 | 43215 | jjdelcerro | if( transform.getDefaultFeatureType() != null ) { |
95 | if( !transform.getFeatureTypes().contains(transform.getDefaultFeatureType()) ) {
|
||
96 | throw new IllegalArgumentException(); // FIXME: Add specific type |
||
97 | } |
||
98 | this.transforms.add(transform);
|
||
99 | transform.setFeatureStore(store); |
||
100 | transform.setSourceMetadata(this.store.metadata);
|
||
101 | 46875 | fdiaz | transform.apply(this.store);
|
102 | 43215 | jjdelcerro | this.notifyChangeToStore();
|
103 | if( this.isTramsformValues == null || (!this.isTramsformValues) ) { |
||
104 | if( transform.isTransformsOriginalValues() ) {
|
||
105 | this.isTramsformValues = true; |
||
106 | } |
||
107 | 40435 | jjdelcerro | |
108 | 43215 | jjdelcerro | } |
109 | } |
||
110 | 40435 | jjdelcerro | |
111 | 43215 | jjdelcerro | return transform;
|
112 | } |
||
113 | 40435 | jjdelcerro | |
114 | 43215 | jjdelcerro | @Override
|
115 | public void clear() { |
||
116 | checkEditingMode(); |
||
117 | this.transforms.clear();
|
||
118 | this.notifyChangeToStore();
|
||
119 | this.isTramsformValues = Boolean.FALSE; |
||
120 | } |
||
121 | 40435 | jjdelcerro | |
122 | 43215 | jjdelcerro | @Override
|
123 | public FeatureStoreTransform getTransform(int index) { |
||
124 | return (FeatureStoreTransform) this.transforms.get(index); |
||
125 | } |
||
126 | 40435 | jjdelcerro | |
127 | 43215 | jjdelcerro | @Override
|
128 | public Iterator<FeatureStoreTransform> iterator() { |
||
129 | return Collections.unmodifiableList(transforms).iterator(); |
||
130 | } |
||
131 | 40435 | jjdelcerro | |
132 | 43215 | jjdelcerro | @Override
|
133 | public Object remove(int index) { |
||
134 | checkEditingMode(); |
||
135 | 46875 | fdiaz | FeatureStoreTransform trans = this.transforms.remove(index);
|
136 | trans.revoke(this.store);
|
||
137 | |||
138 | 43215 | jjdelcerro | this.notifyChangeToStore();
|
139 | this.isTramsformValues = null; |
||
140 | return trans;
|
||
141 | } |
||
142 | 40435 | jjdelcerro | |
143 | 43215 | jjdelcerro | @Override
|
144 | public boolean remove(FeatureStoreTransform transform) { |
||
145 | checkEditingMode(); |
||
146 | boolean removed = this.transforms.remove(transform); |
||
147 | if( removed ) {
|
||
148 | this.notifyChangeToStore();
|
||
149 | 40435 | jjdelcerro | |
150 | 43215 | jjdelcerro | } |
151 | this.isTramsformValues = null; |
||
152 | return removed;
|
||
153 | 40435 | jjdelcerro | |
154 | 43215 | jjdelcerro | } |
155 | 40435 | jjdelcerro | |
156 | 43215 | jjdelcerro | @Override
|
157 | public int size() { |
||
158 | return this.transforms.size(); |
||
159 | } |
||
160 | 40435 | jjdelcerro | |
161 | 43215 | jjdelcerro | @Override
|
162 | public boolean isEmpty() { |
||
163 | return this.transforms.isEmpty(); |
||
164 | } |
||
165 | 40435 | jjdelcerro | |
166 | 43215 | jjdelcerro | private class TransformTemporalListElement { |
167 | 40435 | jjdelcerro | |
168 | 43215 | jjdelcerro | public FeatureStoreTransform transform = null; |
169 | public FeatureType targetFeatureType = null; |
||
170 | } |
||
171 | 40435 | jjdelcerro | |
172 | 43215 | jjdelcerro | private class TransformTemporalList |
173 | extends ArrayList { |
||
174 | 40435 | jjdelcerro | |
175 | 43215 | jjdelcerro | /**
|
176 | *
|
||
177 | */
|
||
178 | private static final long serialVersionUID = 1677014259279944000L; |
||
179 | private FeatureType targetFType;
|
||
180 | 40435 | jjdelcerro | |
181 | 43215 | jjdelcerro | @Override
|
182 | public boolean add(Object arg0) { |
||
183 | if( this.isEmpty() ) { |
||
184 | targetFType = ((TransformTemporalListElement) arg0).targetFeatureType; |
||
185 | } |
||
186 | return super.add(arg0); |
||
187 | } |
||
188 | 40435 | jjdelcerro | |
189 | 43215 | jjdelcerro | } |
190 | 40435 | jjdelcerro | |
191 | 43215 | jjdelcerro | private TransformTemporalList getTransformTemporalList(FeatureType targetFeatureType) {
|
192 | if( this.lastTransformStack == null |
||
193 | || this.lastTransformStack.size() != this.transforms.size() |
||
194 | || !(this.lastTransformStack.targetFType.equals(targetFeatureType)) ) {
|
||
195 | TransformTemporalList result = new TransformTemporalList();
|
||
196 | TransformTemporalListElement item; |
||
197 | FeatureType nextFType = targetFeatureType; |
||
198 | 40435 | jjdelcerro | |
199 | 43215 | jjdelcerro | for( int i = transforms.size() - 1; i > -1; i-- ) { |
200 | item = new TransformTemporalListElement();
|
||
201 | item.transform = (FeatureStoreTransform) transforms.get(i); |
||
202 | item.targetFeatureType = nextFType; |
||
203 | nextFType = item.transform.getSourceFeatureTypeFrom(item.targetFeatureType); |
||
204 | result.add(item); |
||
205 | } |
||
206 | this.lastTransformStack = result;
|
||
207 | } |
||
208 | return this.lastTransformStack; |
||
209 | } |
||
210 | 40435 | jjdelcerro | |
211 | 43215 | jjdelcerro | public Feature applyTransform(DefaultFeature source,
|
212 | FeatureType targetFeatureType) |
||
213 | throws DataException {
|
||
214 | if( this.transforms.isEmpty() ) { |
||
215 | return source;
|
||
216 | } |
||
217 | 40435 | jjdelcerro | |
218 | 43215 | jjdelcerro | TransformTemporalList stack = this
|
219 | .getTransformTemporalList(targetFeatureType); |
||
220 | TransformTemporalListElement item; |
||
221 | FeatureProvider targetData; |
||
222 | 45787 | fdiaz | DefaultEditableFeature target; |
223 | 43215 | jjdelcerro | ListIterator iterator = stack.listIterator(stack.size());
|
224 | FeatureType tft = null;
|
||
225 | 40435 | jjdelcerro | |
226 | 43215 | jjdelcerro | while( iterator.hasPrevious() ) {
|
227 | item = (TransformTemporalListElement) iterator.previous(); |
||
228 | |||
229 | tft = item.targetFeatureType; |
||
230 | if( tft instanceof EditableFeatureType ) { |
||
231 | /*
|
||
232 | 40435 | jjdelcerro | * Must be non-editable to create
|
233 | * DefaultFeatureProvider
|
||
234 | 43215 | jjdelcerro | */
|
235 | tft = ((EditableFeatureType) tft).getNotEditableCopy(); |
||
236 | } |
||
237 | 40435 | jjdelcerro | |
238 | 43215 | jjdelcerro | targetData = this.store.createDefaultFeatureProvider(tft);
|
239 | 45787 | fdiaz | targetData.setNew(true);
|
240 | 43215 | jjdelcerro | targetData.setOID(source.getData().getOID()); |
241 | target = new DefaultEditableFeature(this.store, targetData); |
||
242 | item.transform.applyTransform(source, target); |
||
243 | 45787 | fdiaz | targetData.setNew(source.getData().isNew()); |
244 | target.setInserted(source.isInserted()); |
||
245 | 43215 | jjdelcerro | source = (DefaultFeature) target.getNotEditableCopy(); |
246 | } |
||
247 | 40435 | jjdelcerro | |
248 | 43215 | jjdelcerro | return source;
|
249 | 40435 | jjdelcerro | |
250 | 43215 | jjdelcerro | } |
251 | 40435 | jjdelcerro | |
252 | 43215 | jjdelcerro | public FeatureType getSourceFeatureTypeFrom(FeatureType targetFeatureType) {
|
253 | FeatureType tmpFType = targetFeatureType; |
||
254 | 40435 | jjdelcerro | |
255 | 43215 | jjdelcerro | for( int i = transforms.size() - 1; i > -1; i-- ) { |
256 | FeatureStoreTransform transform = transforms.get(i); |
||
257 | tmpFType = transform.getSourceFeatureTypeFrom(tmpFType); |
||
258 | } |
||
259 | 44753 | omartinez | // se mantienen
|
260 | 44829 | omartinez | List<EditableFeatureAttributeDescriptor> extraCols = targetFeatureType.getExtraColumns().getColumns();
|
261 | 44753 | omartinez | if (extraCols!=null & !extraCols.isEmpty()) { |
262 | 44829 | omartinez | FeatureExtraColumns tmpExtraCols = tmpFType.getExtraColumns(); |
263 | tmpExtraCols.merge(targetFeatureType.getExtraColumns()); |
||
264 | 44753 | omartinez | ((DefaultFeatureType) tmpFType).setExtraColumn(tmpExtraCols); |
265 | } |
||
266 | 43215 | jjdelcerro | return tmpFType;
|
267 | } |
||
268 | 40435 | jjdelcerro | |
269 | 43215 | jjdelcerro | public FeatureType getDefaultFeatureType() throws DataException { |
270 | if( this.transforms.isEmpty() ) { |
||
271 | return null; |
||
272 | } |
||
273 | FeatureStoreTransform transform = this.transforms.get(this.transforms.size() - 1); |
||
274 | return transform.getDefaultFeatureType();
|
||
275 | } |
||
276 | 40435 | jjdelcerro | |
277 | 43215 | jjdelcerro | public List<FeatureType> getFeatureTypes() throws DataException { |
278 | if( this.transforms.isEmpty() ) { |
||
279 | return null; |
||
280 | } |
||
281 | FeatureStoreTransform transform = this.transforms.get(this.transforms.size() - 1); |
||
282 | return transform.getFeatureTypes();
|
||
283 | } |
||
284 | 40435 | jjdelcerro | |
285 | 43215 | jjdelcerro | public FeatureStore getFeatureStore() {
|
286 | return this.store; |
||
287 | } |
||
288 | 40435 | jjdelcerro | |
289 | 43215 | jjdelcerro | public void setFeatureStore(FeatureStore featureStore) { |
290 | if( this.store != null ) { |
||
291 | throw new IllegalStateException(); |
||
292 | } |
||
293 | this.store = (DefaultFeatureStore) featureStore;
|
||
294 | for( FeatureStoreTransform transform : this ) { |
||
295 | transform.setFeatureStore(featureStore); |
||
296 | } |
||
297 | } |
||
298 | |||
299 | public void setStoreForClone(FeatureStore featureStore) { |
||
300 | this.store = (DefaultFeatureStore) featureStore;
|
||
301 | } |
||
302 | 40435 | jjdelcerro | |
303 | 43215 | jjdelcerro | @Override
|
304 | public boolean isTransformsOriginalValues() { |
||
305 | if( this.isTramsformValues == null ) { |
||
306 | this.isTramsformValues = false; |
||
307 | for( FeatureStoreTransform transform : this ) { |
||
308 | if( transform.isTransformsOriginalValues() ) {
|
||
309 | this.isTramsformValues = true; |
||
310 | break;
|
||
311 | } |
||
312 | } |
||
313 | } |
||
314 | return this.isTramsformValues; |
||
315 | } |
||
316 | 40435 | jjdelcerro | |
317 | 43215 | jjdelcerro | public FeatureType getFeatureType(String featureTypeId) |
318 | throws DataException {
|
||
319 | if( this.transforms.isEmpty() ) { |
||
320 | return null; |
||
321 | } |
||
322 | if( featureTypeId == null ) { |
||
323 | return this.getDefaultFeatureType(); |
||
324 | } |
||
325 | for( FeatureType fType : (List<FeatureType>) this.getFeatureTypes() ) { |
||
326 | |||
327 | } |
||
328 | Iterator iter = this.getFeatureTypes().iterator(); |
||
329 | FeatureType fType; |
||
330 | while( iter.hasNext() ) {
|
||
331 | fType = (FeatureType) iter.next(); |
||
332 | if( fType.getId().equals(featureTypeId) ) {
|
||
333 | return fType;
|
||
334 | } |
||
335 | } |
||
336 | return null; |
||
337 | } |
||
338 | 40435 | jjdelcerro | |
339 | 43215 | jjdelcerro | @Override
|
340 | public void saveToState(PersistentState state) throws PersistenceException { |
||
341 | // state.set("store", store);
|
||
342 | state.set("isTramsformValues", this.isTramsformValues); |
||
343 | state.set("transforms", this.transforms); |
||
344 | } |
||
345 | 40435 | jjdelcerro | |
346 | 43215 | jjdelcerro | @Override
|
347 | public void loadFromState(PersistentState state) |
||
348 | throws PersistenceException {
|
||
349 | this.isTramsformValues = (Boolean) state.get("isTramsformValues"); |
||
350 | this.transforms = new ArrayList(); |
||
351 | List<FeatureStoreTransform> x = (List<FeatureStoreTransform>) state.get("transforms"); |
||
352 | this.transforms.addAll(x);
|
||
353 | // this.store = (DefaultFeatureStore) state.get("store");
|
||
354 | } |
||
355 | 40435 | jjdelcerro | |
356 | 43215 | jjdelcerro | public static void registerPersistent() { |
357 | DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition( |
||
358 | DefaultFeatureStoreTransforms.class, |
||
359 | "DefaultFeatureStoreTransforms",
|
||
360 | "DefaultFeatureStoreTransforms Persistent definition",
|
||
361 | null,
|
||
362 | null
|
||
363 | ); |
||
364 | 40435 | jjdelcerro | |
365 | 43215 | jjdelcerro | definition.addDynFieldBoolean("isTramsformValues").setMandatory(false); |
366 | definition.addDynFieldList("transforms").setClassOfItems(FeatureStoreTransform.class).setMandatory(true); |
||
367 | definition.addDynFieldObject("store").setClassOfValue(FeatureStore.class).setMandatory(false); |
||
368 | 40435 | jjdelcerro | |
369 | 43215 | jjdelcerro | } |
370 | 40435 | jjdelcerro | |
371 | 43215 | jjdelcerro | public Object getDynValue(String name) throws DynFieldNotFoundException { |
372 | if( !this.transforms.isEmpty() ) { |
||
373 | 44165 | jjdelcerro | for (int i = this.transforms.size() - 1; i >= 0; i--) { |
374 | FeatureStoreTransform transform = transforms.get(i); |
||
375 | if( transform!=null && transform.hasDynValue(name) ) { |
||
376 | Object value;
|
||
377 | try {
|
||
378 | value = transform.getDynValue(name); |
||
379 | if( value!=null ) { |
||
380 | return value;
|
||
381 | } |
||
382 | } catch(Exception ex) { |
||
383 | LOGGER.warn("Cant retrieve value of '"+name+ "' in transform '"+transform.getName()+"'.", ex); |
||
384 | } |
||
385 | } |
||
386 | 43215 | jjdelcerro | } |
387 | } |
||
388 | 44165 | jjdelcerro | return null; |
389 | 43215 | jjdelcerro | } |
390 | 40435 | jjdelcerro | |
391 | 43215 | jjdelcerro | public void setDynValue(String name, Object value) throws DynFieldNotFoundException { |
392 | if( !this.transforms.isEmpty() ) { |
||
393 | FeatureStoreTransform transform = (FeatureStoreTransform) transforms.get(this.transforms.size() - 1); |
||
394 | transform.setDynValue(name, value); |
||
395 | } |
||
396 | } |
||
397 | 40435 | jjdelcerro | |
398 | 43215 | jjdelcerro | public boolean hasDynValue(String name) { |
399 | if( !this.transforms.isEmpty() ) { |
||
400 | 44165 | jjdelcerro | for (int i = this.transforms.size() - 1; i >= 0; i--) { |
401 | FeatureStoreTransform transform = transforms.get(i); |
||
402 | if( transform.hasDynValue(name) ) {
|
||
403 | return true; |
||
404 | } |
||
405 | 43215 | jjdelcerro | } |
406 | } |
||
407 | return false; |
||
408 | } |
||
409 | 40435 | jjdelcerro | |
410 | 43215 | jjdelcerro | @Override
|
411 | public Object clone() throws CloneNotSupportedException { |
||
412 | DefaultFeatureStoreTransforms cloned = (DefaultFeatureStoreTransforms) super.clone();
|
||
413 | cloned.transforms = new ArrayList(); |
||
414 | for( FeatureStoreTransform transform : transforms ) {
|
||
415 | cloned.transforms.add((FeatureStoreTransform) transform.clone()); |
||
416 | } |
||
417 | cloned.lastTransformStack = null;
|
||
418 | return cloned;
|
||
419 | } |
||
420 | 40435 | jjdelcerro | |
421 | } |