Statistics
| Revision:

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 / DefaultFeatureType.java @ 46078

History | View | Annotate | Download (45.4 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 44716 jjdelcerro
import java.io.File;
27 40435 jjdelcerro
import java.lang.ref.WeakReference;
28
import java.util.ArrayList;
29
import java.util.Collections;
30 44498 omartinez
import java.util.Date;
31 43981 omartinez
import java.util.HashSet;
32 40435 jjdelcerro
import java.util.Iterator;
33 43998 jjdelcerro
import java.util.LinkedHashSet;
34 40435 jjdelcerro
import java.util.List;
35 44716 jjdelcerro
import java.util.Objects;
36 43981 omartinez
import java.util.Set;
37 44262 jjdelcerro
import java.util.function.Predicate;
38 43610 jjdelcerro
import java.util.zip.CRC32;
39 45154 jjdelcerro
import javax.json.JsonObject;
40 45425 jjdelcerro
import javax.json.JsonValue;
41 43358 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
42 43377 jjdelcerro
import org.apache.commons.lang3.StringUtils;
43 40435 jjdelcerro
44
import org.cresques.cts.IProjection;
45
46
import org.gvsig.fmap.dal.DataTypes;
47
import org.gvsig.fmap.dal.exception.DataException;
48 45739 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
49 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureType;
50
import org.gvsig.fmap.dal.feature.Feature;
51
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
52 41342 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
53 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureRules;
54 43739 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStore;
55 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
56 44190 jjdelcerro
import org.gvsig.tools.ToolsLocator;
57 40435 jjdelcerro
import org.gvsig.tools.dynobject.DynClass;
58
import org.gvsig.tools.dynobject.DynField;
59
import org.gvsig.tools.dynobject.DynMethod;
60
import org.gvsig.tools.dynobject.DynObject;
61
import org.gvsig.tools.dynobject.DynObjectValueItem;
62
import org.gvsig.tools.dynobject.DynStruct;
63 44253 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct_v2;
64
import org.gvsig.tools.dynobject.Tags;
65 40435 jjdelcerro
import org.gvsig.tools.dynobject.exception.DynMethodException;
66
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
67 44253 jjdelcerro
import org.gvsig.tools.dynobject.impl.DefaultTags;
68 44498 omartinez
import org.gvsig.tools.i18n.I18nManager;
69 44190 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
70
import org.gvsig.tools.persistence.Persistent;
71
import org.gvsig.tools.persistence.PersistentState;
72
import org.gvsig.tools.persistence.exception.PersistenceException;
73 44829 omartinez
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
74 45425 jjdelcerro
import org.gvsig.json.Json;
75
import org.gvsig.json.JsonManager;
76
import org.gvsig.json.JsonObjectBuilder;
77
import org.gvsig.json.SupportToJson;
78 40435 jjdelcerro
79 44716 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
80 44253 jjdelcerro
public class DefaultFeatureType
81
        extends ArrayList<FeatureAttributeDescriptor>
82
        implements
83 45425 jjdelcerro
            FeatureType,
84
            Persistent,
85
            DynClass,
86
            DynStruct_v2,
87
            org.gvsig.tools.lang.Cloneable {
88 40435 jjdelcerro
89 44253 jjdelcerro
    /**
90
     *
91
     */
92
    private static final long serialVersionUID = -7988721447349282215L;
93 40435 jjdelcerro
94 44262 jjdelcerro
    public static final RecentUsedsAttributesImpl RECENTS_USEDS = new RecentUsedsAttributesImpl();
95
96 44253 jjdelcerro
    private DefaultFeatureRules rules;
97
    protected boolean hasEvaluators;
98
    protected boolean hasEmulators;
99
    protected String defaultGeometryAttributeName;
100
    protected String defaultTimeAttributeName;
101
    protected int defaultGeometryAttributeIndex;
102
    protected int defaultTimeAttributeIndex;
103
    private String id;
104
    protected boolean hasOID;
105
    protected boolean allowAtomaticValues;
106
    protected FeatureAttributeDescriptor[] pk = null;
107
    protected String internalID = null;
108 40435 jjdelcerro
109 44253 jjdelcerro
    private List srsList = null;
110
    private WeakReference storeRef;
111
    private boolean requiredFields;
112 40435 jjdelcerro
113 44253 jjdelcerro
    private String description;
114
    private String label;
115
    private Tags tags;
116 45154 jjdelcerro
    private FeatureExtraColumns extraColumns;
117 45739 jjdelcerro
    protected boolean checkFeaturesAtFinishEditing;
118
    protected boolean checkFeaturesAtInsert;
119 40435 jjdelcerro
120 44253 jjdelcerro
    public DefaultFeatureType() {
121
        // Usado en la persistencia.
122
        this.internalID = Integer.toHexString((int) (Math.random() * 100000)).toUpperCase();
123
        this.id = id = "default";
124
        this.rules = new DefaultFeatureRules();
125
        this.hasEvaluators = false;
126
        this.hasEmulators = false;
127
        this.defaultGeometryAttributeName = null;
128
        this.defaultTimeAttributeName = null;
129
        this.defaultGeometryAttributeIndex = -1;
130
        this.defaultTimeAttributeIndex = -1;
131
        this.allowAtomaticValues = false;
132
        this.tags = new DefaultTags();
133 45154 jjdelcerro
        this.extraColumns = new DefaultFeatureExtraColumns();
134 45778 fdiaz
        this.checkFeaturesAtFinishEditing = false;
135 45813 jjdelcerro
        this.checkFeaturesAtInsert = true;
136 44253 jjdelcerro
    }
137 40435 jjdelcerro
138 44253 jjdelcerro
    protected DefaultFeatureType(FeatureStore store, String id) {
139
        this();
140
        if (StringUtils.isEmpty(id)) {
141
            id = "default";
142
        }
143
        this.id = id;
144
        setStore(store);
145
    }
146 40435 jjdelcerro
147 44253 jjdelcerro
    protected DefaultFeatureType(FeatureStore store) {
148
        this(store, (String) null);
149
    }
150 43555 fdiaz
151 44253 jjdelcerro
    protected DefaultFeatureType(DefaultFeatureType other) {
152
        this(other.getStore(), (String) null);
153 44318 jjdelcerro
        copyFrom(other, true);
154 44253 jjdelcerro
    }
155 40435 jjdelcerro
156 44253 jjdelcerro
    protected DefaultFeatureType(DefaultFeatureType other,
157
            boolean copyAttributes) {
158
        this(other.getStore(), (String) null);
159 44318 jjdelcerro
        this.copyFrom(other, copyAttributes);
160 44253 jjdelcerro
    }
161 40435 jjdelcerro
162 44318 jjdelcerro
    @Override
163
    public void copyFrom(FeatureType other) {
164
        String internalIDSaved = this.internalID;
165
        String idSaved = this.id;
166
        copyFrom((DefaultFeatureType) other, true);
167
        this.id = idSaved;
168
        this.internalID = internalIDSaved;
169
    }
170 45739 jjdelcerro
171
    @Override
172
    public boolean isCheckFeaturesAtFinishEditing() {
173
        return this.checkFeaturesAtFinishEditing;
174
    }
175
176
    @Override
177
    public boolean isCheckFeaturesAtInsert() {
178
        return this.checkFeaturesAtInsert;
179
    }
180
181
182 44505 jjdelcerro
    protected void addAll(FeatureType attributes) {
183
        for (FeatureAttributeDescriptor attribute : attributes) {
184
            DefaultFeatureAttributeDescriptor copy = this.getCopyAttributeDescriptor((DefaultFeatureAttributeDescriptor) attribute);
185
            super.add(copy);
186
        }
187
        DefaultFeatureType ft = (DefaultFeatureType) attributes;
188
        this.pk = null;
189
        this.defaultGeometryAttributeName = ft.defaultGeometryAttributeName;
190
        this.defaultTimeAttributeName = ft.defaultTimeAttributeName;
191
        this.defaultGeometryAttributeIndex = ft.defaultGeometryAttributeIndex;
192
        this.defaultTimeAttributeIndex = ft.defaultTimeAttributeIndex;
193
    }
194
195 44318 jjdelcerro
    protected void copyFrom(DefaultFeatureType other, boolean copyAttributes) {
196 44253 jjdelcerro
        this.id = other.getId();
197
        if (copyAttributes) {
198 44505 jjdelcerro
            this.addAll((FeatureType)other);
199 44253 jjdelcerro
        }
200 44506 jjdelcerro
        this.defaultGeometryAttributeName = other.defaultGeometryAttributeName;
201
        this.defaultTimeAttributeName = other.defaultTimeAttributeName;
202
        this.defaultGeometryAttributeIndex = other.defaultGeometryAttributeIndex;
203
        this.defaultTimeAttributeIndex = other.defaultTimeAttributeIndex;
204 44505 jjdelcerro
205 44253 jjdelcerro
        this.hasEvaluators = other.hasEvaluators;
206
        this.hasEmulators = other.hasEmulators;
207
        this.rules = (DefaultFeatureRules) other.rules.getCopy();
208
        this.hasOID = other.hasOID;
209
        this.id = other.id; // XXX ???? copiar o no esto????
210
        this.internalID = other.internalID;
211
        this.label = other.label;
212
        this.description = other.description;
213 45154 jjdelcerro
        this.extraColumns = other.extraColumns.getCopy();
214 44253 jjdelcerro
        try {
215
            this.tags = (Tags) other.tags.clone();
216
        } catch (CloneNotSupportedException ex) {
217
218
        }
219 45739 jjdelcerro
        this.checkFeaturesAtFinishEditing = other.checkFeaturesAtFinishEditing;
220
        this.checkFeaturesAtInsert = other.checkFeaturesAtInsert;
221 44253 jjdelcerro
    }
222 44318 jjdelcerro
223
    protected DefaultFeatureAttributeDescriptor getCopyAttributeDescriptor(DefaultFeatureAttributeDescriptor src) {
224
        DefaultFeatureAttributeDescriptor copy = new DefaultFeatureAttributeDescriptor(src);
225
        copy.setFeatureType(this);
226
        return copy;
227 44253 jjdelcerro
    }
228 40435 jjdelcerro
229 44318 jjdelcerro
    @Override
230 44253 jjdelcerro
    public String getId() {
231
        return this.id;
232
    }
233 40435 jjdelcerro
234 44318 jjdelcerro
    @Override
235 44253 jjdelcerro
    public Object get(String name) {
236
        FeatureAttributeDescriptor attr;
237
        Iterator iter = this.iterator();
238
        while (iter.hasNext()) {
239
            attr = (FeatureAttributeDescriptor) iter.next();
240
            if (attr.getName().equalsIgnoreCase(name)) {
241
                return attr;
242
            }
243
        }
244
        return null;
245
    }
246 40435 jjdelcerro
247 44318 jjdelcerro
    @Override
248 44253 jjdelcerro
    public FeatureAttributeDescriptor getAttributeDescriptor(String name) {
249
        FeatureAttributeDescriptor attr;
250
        Iterator iter = this.iterator();
251
        while (iter.hasNext()) {
252
            attr = (FeatureAttributeDescriptor) iter.next();
253
            if (attr.getName().equalsIgnoreCase(name)) {
254
                return attr;
255
            }
256 42700 jjdelcerro
        }
257 44253 jjdelcerro
        return null;
258
    }
259 46061 omartinez
260
    @Override
261
    public FeatureAttributeDescriptor getAttributeDescriptorFromAll(String name) {
262
       FeatureAttributeDescriptor attrdesc = this.getAttributeDescriptor(name);
263
                if (attrdesc == null && this.getExtraColumns().get(name) != null) {
264
                        attrdesc = this.getExtraColumns().get(name);
265
                }
266
                return attrdesc;
267
    }
268 40435 jjdelcerro
269 44318 jjdelcerro
    @Override
270 44253 jjdelcerro
    public FeatureAttributeDescriptor getAttributeDescriptor(int index) {
271
        return (FeatureAttributeDescriptor) super.get(index);
272
    }
273 40435 jjdelcerro
274 44318 jjdelcerro
    @Override
275 44686 jjdelcerro
    public String getAttributeName(int index) {
276
      try {
277
        return super.get(index).getName();
278
      } catch(Exception ex) {
279
        return null;
280
      }
281
    }
282
283
    @Override
284 44253 jjdelcerro
    public FeatureType getCopy() {
285
        return new DefaultFeatureType(this);
286
    }
287 40435 jjdelcerro
288 44318 jjdelcerro
    @Override
289 44253 jjdelcerro
    public Object clone() {
290
        return this.getCopy();
291
    }
292 44077 jjdelcerro
293 44583 omartinez
    @Override
294 44253 jjdelcerro
    public int getDefaultGeometryAttributeIndex() {
295
        return this.defaultGeometryAttributeIndex;
296
    }
297 44077 jjdelcerro
298 44583 omartinez
    @Override
299 44253 jjdelcerro
    public String getDefaultGeometryAttributeName() {
300
        return this.defaultGeometryAttributeName;
301
    }
302 40435 jjdelcerro
303 44583 omartinez
    @Override
304 44253 jjdelcerro
    public int getDefaultTimeAttributeIndex() {
305
        return this.defaultTimeAttributeIndex;
306
    }
307 40435 jjdelcerro
308 44583 omartinez
    @Override
309 44253 jjdelcerro
    public String getDefaultTimeAttributeName() {
310
        return this.defaultTimeAttributeName;
311
    }
312 40435 jjdelcerro
313 44583 omartinez
    @Override
314 44253 jjdelcerro
    public EditableFeatureType getEditable() {
315
        return new DefaultEditableFeatureType(this);
316
    }
317 40435 jjdelcerro
318 44583 omartinez
    @Override
319 44253 jjdelcerro
    public int getIndex(String name) {
320
        FeatureAttributeDescriptor attr;
321
        Iterator iter = this.iterator();
322
        while (iter.hasNext()) {
323
            attr = (FeatureAttributeDescriptor) iter.next();
324
            if (attr.getName().equalsIgnoreCase(name)) {
325
                return attr.getIndex();
326
            }
327 43998 jjdelcerro
        }
328 44253 jjdelcerro
        return -1;
329
    }
330 41342 jjdelcerro
331 44583 omartinez
    @Override
332 44253 jjdelcerro
    public FeatureRules getRules() {
333
        return this.rules;
334
    }
335 40435 jjdelcerro
336 44583 omartinez
    @Override
337 44253 jjdelcerro
    public boolean hasEvaluators() {
338
        return this.hasEvaluators;
339
    }
340 40435 jjdelcerro
341 44253 jjdelcerro
    public boolean hasEmulators() {
342
        return this.hasEmulators;
343
    }
344 40435 jjdelcerro
345 44253 jjdelcerro
    public boolean hasRequiredFields() {
346
        return this.requiredFields;
347
    }
348
349 44583 omartinez
    @Override
350 44253 jjdelcerro
    public List getSRSs() {
351
        if (this.srsList == null) {
352
            ArrayList tmp = new ArrayList();
353
            Iterator iter = iterator();
354
            Iterator tmpIter;
355
            boolean allreadyHave;
356
            IProjection tmpSRS;
357
            FeatureAttributeDescriptor attr;
358
            while (iter.hasNext()) {
359
                attr = (FeatureAttributeDescriptor) iter.next();
360
                if (attr.getDataType().getType() == DataTypes.GEOMETRY
361
                        && attr.getSRS() != null) {
362
                    allreadyHave = false;
363
                    tmpIter = tmp.iterator();
364
                    while (tmpIter.hasNext()) {
365
                        tmpSRS = (IProjection) tmpIter.next();
366
                        if (tmpSRS.getAbrev().equals(attr.getSRS().getAbrev())) {
367
                            allreadyHave = true;
368
                            break;
369
                        }
370
                    }
371
                    if (!allreadyHave) {
372
                        tmp.add(attr.getSRS());
373
                    }
374 41212 jjdelcerro
                }
375 44253 jjdelcerro
            }
376
            this.srsList = Collections.unmodifiableList(tmp);
377
        }
378
        return this.srsList;
379
    }
380 40435 jjdelcerro
381 44583 omartinez
    @Override
382 44253 jjdelcerro
    public IProjection getDefaultSRS() {
383
        if (this.getDefaultGeometryAttributeIndex() < 0) {
384
            return null;
385
        }
386
        return this.getAttributeDescriptor(
387
                this.getDefaultGeometryAttributeIndex()).getSRS();
388
    }
389
390 45739 jjdelcerro
    public void validateFeature(EditableFeature feature, int check) throws DataException {
391
        DefaultFeatureRules theRules = (DefaultFeatureRules) this.getRules();
392
        theRules.validate(feature, check);
393 44253 jjdelcerro
    }
394
395 45739 jjdelcerro
    public void validateFeature(Feature feature, int check) throws DataException {
396
        DefaultFeatureRules theRules = (DefaultFeatureRules) this.getRules();
397
        theRules.validate(feature, check);
398
    }
399
400 44374 jjdelcerro
    public FeatureType getSubtype() throws DataException {
401
        return new SubtypeFeatureType(this, null, null, true);
402
    }
403
404 44253 jjdelcerro
    public FeatureType getSubtype(String[] names) throws DataException {
405 44374 jjdelcerro
        return this.getSubtype(names, null, true);
406 44253 jjdelcerro
    }
407 41212 jjdelcerro
408 44253 jjdelcerro
    public FeatureType getSubtype(String[] names, String[] constantsNames) throws DataException {
409 44374 jjdelcerro
        return this.getSubtype(names, constantsNames, true);
410
    }
411
412
    public FeatureType getSubtype(String[] names, String[] constantsNames, boolean includePk) throws DataException {
413 44253 jjdelcerro
        if (ArrayUtils.isEmpty(names) && ArrayUtils.isEmpty(constantsNames)) {
414
            return (FeatureType) this.clone();
415
        }
416 44374 jjdelcerro
        return new SubtypeFeatureType(this, names, constantsNames,includePk);
417 44253 jjdelcerro
    }
418 43998 jjdelcerro
419 44253 jjdelcerro
    public boolean isSubtypeOf(FeatureType featureType) {
420
        return false;
421
    }
422
423 44149 jjdelcerro
    @Override
424
    public List<FeatureAttributeDescriptor> toList() {
425
        return Collections.unmodifiableList(this);
426
    }
427 40435 jjdelcerro
428 44253 jjdelcerro
    @Override
429
    public Tags getTags() {
430
        return this.tags;
431
    }
432 40435 jjdelcerro
433 44253 jjdelcerro
    @Override
434
    public String getLabel() {
435
        return this.label;
436
    }
437
438
    @Override
439
    public void setLabel(String label) {
440
        this.label = label;
441
    }
442
443
    @Override
444
    public DynField addDynField(String name, int type) {
445
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
446
    }
447
448 44753 omartinez
    @Override
449 44829 omartinez
    public FeatureExtraColumns getExtraColumns() {
450 45154 jjdelcerro
        return extraColumns;
451 44753 omartinez
    }
452
453 44829 omartinez
    public void setExtraColumn(FeatureExtraColumns extraColumn) { //List<FeatureAttributeDescriptor> descriptors) {
454 45154 jjdelcerro
          this.extraColumns = extraColumn;
455 44753 omartinez
    }
456
457 45220 omartinez
    @Override
458
    public Iterable<FeatureAttributeDescriptor> getAllAttributeDescriptors() {
459
        Set<FeatureAttributeDescriptor> all = new HashSet<FeatureAttributeDescriptor>();
460
        for (FeatureAttributeDescriptor attributeDescriptor : this.getAttributeDescriptors()) {
461
            all.add(attributeDescriptor);
462
        }
463
        for (FeatureAttributeDescriptor extraColumn : this.getExtraColumns().getColumns()) {
464
            all.add(extraColumn);
465
        }
466
        return all;
467
    }
468
469 44253 jjdelcerro
    class SubtypeFeatureType extends DefaultFeatureType {
470
471
        /**
472
         *
473
         */
474
        private static final long serialVersionUID = 6913732960073922540L;
475
        WeakReference parent;
476
477 44374 jjdelcerro
        SubtypeFeatureType(DefaultFeatureType parent, String[] names, String[] constantsNames, boolean includePk)
478 44253 jjdelcerro
                throws DataException {
479
            super(parent, false);
480
            DefaultFeatureAttributeDescriptor attrcopy;
481
            Set<String> attrnames = new LinkedHashSet<>();
482
            Set<String> requiredAttrnames = new HashSet<>();
483
484
            if (ArrayUtils.isEmpty(names)) {
485
                for (FeatureAttributeDescriptor attrdesc : parent) {
486 44376 jjdelcerro
                    attrnames.add(attrdesc.getName().toLowerCase());
487 44253 jjdelcerro
                }
488 44376 jjdelcerro
            } else {
489 44826 jjdelcerro
                for (String name : names) {
490
                  name = name.toLowerCase();
491
                  attrnames.add(name);
492
                  requiredAttrnames.add(name);
493
                }
494 44253 jjdelcerro
            }
495
            // Add required fields for emulated fields
496
            if (parent.hasEmulators) {
497 44376 jjdelcerro
                // Ojo, este bucle falla cuando hay un campo calculado que depende
498
                // de otro campo calculado.
499 44253 jjdelcerro
                for (FeatureAttributeDescriptor attrdesc : parent) {
500
                    FeatureAttributeEmulator emulator = attrdesc.getFeatureAttributeEmulator();
501 44376 jjdelcerro
                    if (emulator != null && attrnames.contains(attrdesc.getName().toLowerCase())) {
502
                        String theNames[] = emulator.getRequiredFieldNames();
503
                        if (names != null) {
504
                            for (String name : theNames) {
505
                                name = name.toLowerCase();
506
                                attrnames.add(name);
507
                                requiredAttrnames.add(name);
508
                            }
509 43998 jjdelcerro
                        }
510
                    }
511 44253 jjdelcerro
                }
512
            }
513
            // Add missing pk fiels
514 44374 jjdelcerro
            if (includePk && !parent.hasOID()) {
515 44253 jjdelcerro
                for (FeatureAttributeDescriptor attrdesc : parent) {
516
                    if (attrdesc.isPrimaryKey()) {
517 44376 jjdelcerro
                        String name = attrdesc.getName().toLowerCase();
518
                        attrnames.add(name);
519
                        requiredAttrnames.add(name);
520 43998 jjdelcerro
                    }
521 44253 jjdelcerro
                }
522
            }
523 41212 jjdelcerro
524 44253 jjdelcerro
            // Copy attributes
525
            int i = 0;
526
            for (String name : attrnames) {
527
                DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) parent.get(name);
528
                if (attr == null) {
529
                    throw new SubtypeFeatureTypeNameException(name, parent.getId());
530
                }
531
                attrcopy = new DefaultFeatureAttributeDescriptor(attr);
532
                this.add(attrcopy);
533
                attrcopy.index = i++;
534
            }
535
536 44376 jjdelcerro
            // Set the constants attributes.
537 44253 jjdelcerro
            if (!ArrayUtils.isEmpty(constantsNames)) {
538
                for (String name : constantsNames) {
539 44583 omartinez
                    if (!requiredAttrnames.contains(name.toLowerCase())) {
540 44253 jjdelcerro
                        DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) this.get(name);
541
                        attr.setConstantValue(true);
542 41342 jjdelcerro
                    }
543
                }
544 44253 jjdelcerro
            }
545 40435 jjdelcerro
546 44253 jjdelcerro
            this.defaultGeometryAttributeIndex = this.getIndex(this.defaultGeometryAttributeName);
547
            if (this.defaultGeometryAttributeIndex < 0) {
548
                this.defaultGeometryAttributeName = null;
549
            }
550
            this.defaultTimeAttributeIndex = this.getIndex(this.defaultTimeAttributeName);
551
            if (this.defaultTimeAttributeIndex < 0) {
552
                this.defaultTimeAttributeName = null;
553
            }
554
            this.parent = new WeakReference(parent);
555
        }
556 40435 jjdelcerro
557 44374 jjdelcerro
        public FeatureType getSubtype(String[] names, boolean includePk) throws DataException {
558 44253 jjdelcerro
            return new SubtypeFeatureType((DefaultFeatureType) this.parent
559 44374 jjdelcerro
                    .get(), names, null, includePk);
560 44253 jjdelcerro
        }
561 40435 jjdelcerro
562 44253 jjdelcerro
        public boolean isSubtypeOf(FeatureType featureType) {
563
            if (featureType == null) {
564
                return false;
565
            }
566
            FeatureType parent = (FeatureType) this.parent.get();
567
            return featureType.equals(parent);
568
        }
569 40435 jjdelcerro
570 44253 jjdelcerro
        public EditableFeatureType getEditable() {
571
            throw new UnsupportedOperationException();
572
        }
573
    }
574 40435 jjdelcerro
575 44253 jjdelcerro
    public class SubtypeFeatureTypeNameException extends DataException {
576 40435 jjdelcerro
577 44253 jjdelcerro
        /**
578
         *
579
         */
580
        private static final long serialVersionUID = -4414242486723260101L;
581
        private final static String MESSAGE_FORMAT = "Attribute name '%(name)' not found in type (%(type)).";
582
        private final static String MESSAGE_KEY = "_SubtypeFeatureTypeNameException";
583 40435 jjdelcerro
584 44253 jjdelcerro
        public SubtypeFeatureTypeNameException(String name, String type) {
585
            super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
586
            setValue("name", name);
587
            setValue("type", type);
588
        }
589
    }
590 40435 jjdelcerro
591 44253 jjdelcerro
    public boolean hasOID() {
592
        return hasOID;
593
    }
594 40435 jjdelcerro
595 44583 omartinez
    @Override
596 44253 jjdelcerro
    public String toString() {
597
        StringBuffer s = new StringBuffer();
598
        s.append(this.getId());
599
        s.append(":[");
600
        String attName;
601
        for (int i = 0; i < size(); i++) {
602
            attName = ((FeatureAttributeDescriptor) get(i)).getName().toString();
603
            s.append(attName);
604
            if (i < size() - 1) {
605
                s.append(',');
606
            }
607
        }
608
        s.append(']');
609
        return s.toString();
610
    }
611 40435 jjdelcerro
612 44583 omartinez
    @Override
613 44253 jjdelcerro
    public Iterator<FeatureAttributeDescriptor> iterator() {
614
        return getIterator(super.iterator());
615
    }
616 40435 jjdelcerro
617 44253 jjdelcerro
    protected Iterator getIterator(Iterator iter) {
618
        return new DelegatedIterator(iter);
619
    }
620 40435 jjdelcerro
621 44253 jjdelcerro
    protected class DelegatedIterator implements Iterator {
622 40435 jjdelcerro
623 44253 jjdelcerro
        protected Iterator iterator;
624 40435 jjdelcerro
625 44253 jjdelcerro
        public DelegatedIterator(Iterator iter) {
626
            this.iterator = iter;
627
        }
628 40435 jjdelcerro
629 44583 omartinez
        @Override
630 44253 jjdelcerro
        public boolean hasNext() {
631
            return iterator.hasNext();
632
        }
633 40435 jjdelcerro
634 44583 omartinez
        @Override
635 44253 jjdelcerro
        public Object next() {
636
            return iterator.next();
637
        }
638 40435 jjdelcerro
639 44583 omartinez
        @Override
640 44253 jjdelcerro
        public void remove() {
641
            throw new UnsupportedOperationException();
642
        }
643 40435 jjdelcerro
644 44253 jjdelcerro
    }
645 40435 jjdelcerro
646 44583 omartinez
    @Override
647 44253 jjdelcerro
    public boolean allowAutomaticValues() {
648
        return this.allowAtomaticValues;
649
    }
650
651 44583 omartinez
    @Override
652 44253 jjdelcerro
    public FeatureAttributeDescriptor[] getAttributeDescriptors() {
653
        return (FeatureAttributeDescriptor[]) super
654
                .toArray(new FeatureAttributeDescriptor[super.size()]);
655
    }
656
657 44435 jjdelcerro
    @Override
658
    public boolean hasPrimaryKey() {
659
        if( pk!=null ) {
660
            return pk.length>0;
661
        }
662
        for (FeatureAttributeDescriptor attr : this) {
663
            if( attr.isPrimaryKey() ) {
664
                return true;
665
            }
666
        }
667
        return false;
668
    }
669
670
    @Override
671
    public boolean supportReferences() {
672
        return this.hasOID() || this.hasPrimaryKey();
673
    }
674
675
    @Override
676 44253 jjdelcerro
    public FeatureAttributeDescriptor[] getPrimaryKey() {
677
        if (pk == null) {
678
            List pks = new ArrayList();
679
            Iterator iter = super.iterator();
680
            FeatureAttributeDescriptor attr;
681
            while (iter.hasNext()) {
682
                attr = (FeatureAttributeDescriptor) iter.next();
683
                if (attr.isPrimaryKey()) {
684
                    pks.add(attr);
685
                }
686
            }
687
            if (pks.isEmpty()) {
688 43358 jjdelcerro
                pk = new FeatureAttributeDescriptor[0];
689
            } else {
690 44253 jjdelcerro
                pk = (FeatureAttributeDescriptor[]) pks.toArray(new FeatureAttributeDescriptor[pks.size()]);
691 43358 jjdelcerro
            }
692 44253 jjdelcerro
        }
693
        return pk;
694
    }
695 40435 jjdelcerro
696 44253 jjdelcerro
    public FeatureAttributeDescriptor getDefaultGeometryAttribute() {
697
        if (this.defaultGeometryAttributeIndex < 0) {
698
            return null;
699
        }
700
        return (FeatureAttributeDescriptor) super
701
                .get(this.defaultGeometryAttributeIndex);
702
    }
703 40435 jjdelcerro
704 44583 omartinez
    @Override
705 44253 jjdelcerro
    public boolean equals(Object o) {
706
        if (this == o) {
707
            return true;
708
        }
709
        if (!(o instanceof DefaultFeatureType)) {
710
            return false;
711
        }
712
        DefaultFeatureType other = (DefaultFeatureType) o;
713
        if (!this.id.equals(other.id)) {
714
            return false;
715
        }
716
        if (this.size() != other.size()) {
717
            return false;
718
        }
719
        FeatureAttributeDescriptor attr, attrOther;
720
        Iterator iter, iterOther;
721
        iter = this.iterator();
722
        iterOther = other.iterator();
723
        while (iter.hasNext()) {
724
            attr = (FeatureAttributeDescriptor) iter.next();
725
            attrOther = (FeatureAttributeDescriptor) iterOther.next();
726
            if (!attr.equals(attrOther)) {
727 44077 jjdelcerro
                return false;
728
            }
729 44253 jjdelcerro
        }
730 40435 jjdelcerro
731 44253 jjdelcerro
        if (!StringUtils.equals(defaultGeometryAttributeName, other.defaultGeometryAttributeName)) {
732
            return false;
733
        }
734
        if (!StringUtils.equals(defaultTimeAttributeName, other.defaultTimeAttributeName)) {
735
            return false;
736
        }
737
        return true;
738 40435 jjdelcerro
739 44253 jjdelcerro
    }
740 40435 jjdelcerro
741 44253 jjdelcerro
    /**
742
     * Start of DynClass interface implementation READONLY
743
     */
744 44583 omartinez
    @Override
745 44253 jjdelcerro
    public DynField addDynField(String name) {
746
        throw new UnsupportedOperationException();
747
    }
748 40435 jjdelcerro
749 44583 omartinez
    @Override
750 44253 jjdelcerro
    public DynField getDeclaredDynField(String name) {
751
        return (DynField) getAttributeDescriptor(name);
752
    }
753 40435 jjdelcerro
754 44583 omartinez
    @Override
755 44253 jjdelcerro
    public DynField[] getDeclaredDynFields() {
756
        return (DynField[]) getAttributeDescriptors();
757
    }
758 40435 jjdelcerro
759 44583 omartinez
    @Override
760 44253 jjdelcerro
    public String getDescription() {
761
        return this.description;
762
    }
763 40435 jjdelcerro
764 44583 omartinez
    @Override
765 44253 jjdelcerro
    public DynField getDynField(String name) {
766
        return (DynField) getAttributeDescriptor(name);
767
    }
768 40435 jjdelcerro
769 44583 omartinez
    @Override
770 44253 jjdelcerro
    public DynField[] getDynFields() {
771
        return (DynField[]) getAttributeDescriptors();
772
    }
773 40435 jjdelcerro
774 44583 omartinez
    @Override
775 44253 jjdelcerro
    public String getName() {
776
        return this.id + "_" + internalID;
777
    }
778 40435 jjdelcerro
779 44583 omartinez
    @Override
780 44253 jjdelcerro
    public void removeDynField(String name) {
781
        throw new UnsupportedOperationException();
782 40435 jjdelcerro
783 44253 jjdelcerro
    }
784 40435 jjdelcerro
785 44583 omartinez
    @Override
786 44253 jjdelcerro
    public void addDynMethod(DynMethod dynMethod) {
787
        throw new UnsupportedOperationException();
788 40435 jjdelcerro
789 44253 jjdelcerro
    }
790 40435 jjdelcerro
791 44253 jjdelcerro
    public void extend(DynClass dynClass) {
792
        throw new UnsupportedOperationException();
793 40435 jjdelcerro
794 44253 jjdelcerro
    }
795 40435 jjdelcerro
796 44583 omartinez
    @Override
797 44253 jjdelcerro
    public void extend(String dynClassName) {
798
        throw new UnsupportedOperationException();
799 40435 jjdelcerro
800 44253 jjdelcerro
    }
801 40435 jjdelcerro
802 44583 omartinez
    @Override
803 44253 jjdelcerro
    public void extend(String namespace, String dynClassName) {
804
        throw new UnsupportedOperationException();
805 40435 jjdelcerro
806 44253 jjdelcerro
    }
807 40435 jjdelcerro
808 44583 omartinez
    @Override
809 44253 jjdelcerro
    public DynMethod getDeclaredDynMethod(String name)
810
            throws DynMethodException {
811
        return null;
812
    }
813 40435 jjdelcerro
814 44583 omartinez
    @Override
815 44253 jjdelcerro
    public DynMethod[] getDeclaredDynMethods() throws DynMethodException {
816
        return null;
817
    }
818 40435 jjdelcerro
819 44583 omartinez
    @Override
820 44253 jjdelcerro
    public DynMethod getDynMethod(String name) throws DynMethodException {
821
        return null;
822
    }
823 40435 jjdelcerro
824 44583 omartinez
    @Override
825 44253 jjdelcerro
    public DynMethod getDynMethod(int code) throws DynMethodException {
826
        return null;
827
    }
828 40435 jjdelcerro
829 44583 omartinez
    @Override
830 44253 jjdelcerro
    public DynMethod[] getDynMethods() throws DynMethodException {
831
        return null;
832
    }
833 40435 jjdelcerro
834 44583 omartinez
    @Override
835 44253 jjdelcerro
    public DynClass[] getSuperDynClasses() {
836
        return null;
837
    }
838 40435 jjdelcerro
839 44583 omartinez
    @Override
840 44253 jjdelcerro
    public boolean isInstance(DynObject dynObject) {
841
        if (dynObject.getDynClass().getName() == getName()) {
842
            return true;
843
        }
844
        return false;
845
    }
846 40435 jjdelcerro
847 44583 omartinez
    @Override
848 44253 jjdelcerro
    public DynObject newInstance() {
849 40435 jjdelcerro
850 44253 jjdelcerro
        throw new UnsupportedOperationException();
851
    }
852 40435 jjdelcerro
853 44583 omartinez
    @Override
854 44253 jjdelcerro
    public void removeDynMethod(String name) {
855
        throw new UnsupportedOperationException();
856 40435 jjdelcerro
857 44253 jjdelcerro
    }
858 40435 jjdelcerro
859 44583 omartinez
    @Override
860 44253 jjdelcerro
    public DynField addDynFieldChoice(String name, int type,
861
            Object defaultValue, DynObjectValueItem[] values,
862
            boolean mandatory, boolean persistent) {
863
        throw new UnsupportedOperationException();
864
    }
865 40435 jjdelcerro
866 44583 omartinez
    @Override
867 44253 jjdelcerro
    public DynField addDynFieldRange(String name, int type,
868
            Object defaultValue, Object min, Object max, boolean mandatory,
869
            boolean persistent) {
870
        throw new UnsupportedOperationException();
871
    }
872 40435 jjdelcerro
873 44583 omartinez
    @Override
874 44253 jjdelcerro
    public DynField addDynFieldSingle(String name, int type,
875
            Object defaultValue, boolean mandatory, boolean persistent) {
876
        throw new UnsupportedOperationException();
877
    }
878 40435 jjdelcerro
879 44583 omartinez
    @Override
880 44253 jjdelcerro
    public void validate(DynObject object) throws DynObjectValidateException {
881
        //FIXME: not sure it's the correct code
882
        if (object instanceof Feature) {
883
            Feature fea = (Feature) object;
884
            if (fea.getType().equals(this)) {
885
                return;
886
            }
887
        }
888
        throw new DynObjectValidateException(this.id);
889
    }
890 40435 jjdelcerro
891 44583 omartinez
    @Override
892 44253 jjdelcerro
    public DynField addDynFieldLong(String name) {
893
        throw new UnsupportedOperationException();
894
    }
895 40435 jjdelcerro
896 44583 omartinez
    @Override
897 44253 jjdelcerro
    public DynField addDynFieldChoice(String name, int type,
898
            Object defaultValue, DynObjectValueItem[] values) {
899
        throw new UnsupportedOperationException();
900
    }
901 40435 jjdelcerro
902 44583 omartinez
    @Override
903 44253 jjdelcerro
    public DynField addDynFieldRange(String name, int type,
904
            Object defaultValue, Object min, Object max) {
905
        throw new UnsupportedOperationException();
906
    }
907 40435 jjdelcerro
908 44583 omartinez
    @Override
909 44253 jjdelcerro
    public DynField addDynFieldSingle(String name, int type, Object defaultValue) {
910
        throw new UnsupportedOperationException();
911
    }
912 40435 jjdelcerro
913 44583 omartinez
    @Override
914 44253 jjdelcerro
    public DynField addDynFieldString(String name) {
915
        throw new UnsupportedOperationException();
916
    }
917 43555 fdiaz
918 44583 omartinez
    @Override
919 44253 jjdelcerro
    public DynField addDynFieldInt(String name) {
920
        throw new UnsupportedOperationException();
921
    }
922 43555 fdiaz
923 44583 omartinez
    @Override
924 44253 jjdelcerro
    public DynField addDynFieldDouble(String name) {
925
        throw new UnsupportedOperationException();
926
    }
927 43555 fdiaz
928 44583 omartinez
    @Override
929 44253 jjdelcerro
    public DynField addDynFieldFloat(String name) {
930
        throw new UnsupportedOperationException();
931
    }
932 40435 jjdelcerro
933 44253 jjdelcerro
    public DynField addDynFieldBoolean(String name) {
934
        throw new UnsupportedOperationException();
935
    }
936 40435 jjdelcerro
937 44583 omartinez
    @Override
938 44253 jjdelcerro
    public DynField addDynFieldList(String name) {
939
        throw new UnsupportedOperationException();
940
    }
941 40435 jjdelcerro
942 44583 omartinez
    @Override
943 44253 jjdelcerro
    public DynField addDynFieldMap(String name) {
944
        throw new UnsupportedOperationException();
945
    }
946 40435 jjdelcerro
947 44583 omartinez
    @Override
948 44253 jjdelcerro
    public DynField addDynFieldObject(String name) {
949
        throw new UnsupportedOperationException();
950
    }
951 40435 jjdelcerro
952 44583 omartinez
    @Override
953 44253 jjdelcerro
    public DynField addDynFieldSet(String name) {
954
        throw new UnsupportedOperationException();
955
    }
956 40435 jjdelcerro
957 44583 omartinez
    @Override
958 44253 jjdelcerro
    public DynField addDynFieldArray(String name) {
959
        throw new UnsupportedOperationException();
960
    }
961 40435 jjdelcerro
962 44583 omartinez
    @Override
963 44253 jjdelcerro
    public DynField addDynFieldDate(String name) {
964
        throw new UnsupportedOperationException();
965
    }
966 40435 jjdelcerro
967 44583 omartinez
    @Override
968 44253 jjdelcerro
    public void extend(DynStruct struct) {
969
        throw new UnsupportedOperationException();
970
    }
971 40435 jjdelcerro
972 44583 omartinez
    @Override
973 44253 jjdelcerro
    public String getFullName() {
974 40435 jjdelcerro
        // TODO: usar el DynClassName
975 44253 jjdelcerro
        return this.id;
976
    }
977 40435 jjdelcerro
978 44583 omartinez
    @Override
979 44253 jjdelcerro
    public String getNamespace() {
980
        return "DALFeature";
981
    }
982 40435 jjdelcerro
983 44583 omartinez
    @Override
984 44253 jjdelcerro
    public DynStruct[] getSuperDynStructs() {
985
        return null;
986
    }
987 40435 jjdelcerro
988 44583 omartinez
    @Override
989 44253 jjdelcerro
    public void setDescription(String description) {
990
        this.description = description;
991
    }
992 40435 jjdelcerro
993 44583 omartinez
    @Override
994 44253 jjdelcerro
    public void setNamespace(String namespace) {
995
        throw new UnsupportedOperationException();
996
    }
997 40435 jjdelcerro
998 44583 omartinez
    @Override
999 44253 jjdelcerro
    public DynField addDynFieldFile(String name) {
1000
        throw new UnsupportedOperationException();
1001
    }
1002 40435 jjdelcerro
1003 44583 omartinez
    @Override
1004 44253 jjdelcerro
    public DynField addDynFieldFolder(String name) {
1005
        throw new UnsupportedOperationException();
1006
    }
1007 40435 jjdelcerro
1008 44583 omartinez
    @Override
1009 44253 jjdelcerro
    public DynField addDynFieldURL(String name) {
1010
        throw new UnsupportedOperationException();
1011
    }
1012 40435 jjdelcerro
1013 44583 omartinez
    @Override
1014 44253 jjdelcerro
    public DynField addDynFieldURI(String name) {
1015
        throw new UnsupportedOperationException();
1016
    }
1017 40435 jjdelcerro
1018 44583 omartinez
    @Override
1019 40435 jjdelcerro
    public boolean isExtendable(DynStruct dynStruct) {
1020
        return false;
1021
    }
1022
1023 44253 jjdelcerro
    public void extend(DynStruct[] structs) {
1024
        // TODO Auto-generated method stub
1025 43555 fdiaz
1026 44253 jjdelcerro
    }
1027 40435 jjdelcerro
1028 44583 omartinez
    @Override
1029 44253 jjdelcerro
    public void remove(DynStruct superDynStruct) {
1030
        // TODO Auto-generated method stub
1031 43555 fdiaz
1032 44253 jjdelcerro
    }
1033 40435 jjdelcerro
1034 44253 jjdelcerro
    public void removeAll(DynStruct[] superDynStruct) {
1035
        // TODO Auto-generated method stub
1036 43555 fdiaz
1037 44253 jjdelcerro
    }
1038 40435 jjdelcerro
1039 44583 omartinez
    @Override
1040 44253 jjdelcerro
    public FeatureAttributeDescriptor getDefaultTimeAttribute() {
1041
        if (this.defaultTimeAttributeIndex < 0) {
1042
            return null;
1043
        }
1044
        return (FeatureAttributeDescriptor) super
1045
                .get(this.defaultTimeAttributeIndex);
1046
    }
1047 43610 jjdelcerro
1048
    public void setDefaultTimeAttributeName(String name) {
1049
        if (name == null || name.length() == 0) {
1050
            this.defaultTimeAttributeIndex = -1;
1051
            return;
1052
        }
1053
        DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) this.get(name);
1054
        if (attr == null) {
1055
            throw new IllegalArgumentException("Attribute '" + name + "' not found.");
1056
        }
1057 44253 jjdelcerro
        if (attr.getIndex() < 0) {
1058 43610 jjdelcerro
            fixAll();
1059
        }
1060
        this.defaultTimeAttributeIndex = attr.getIndex();
1061
    }
1062 44253 jjdelcerro
1063 43610 jjdelcerro
    protected void fixAll() {
1064
        int i = 0;
1065
        Iterator iter = super.iterator();
1066
        DefaultFeatureAttributeDescriptor attr;
1067
1068
        while (iter.hasNext()) {
1069
            attr = (DefaultFeatureAttributeDescriptor) iter.next();
1070 44253 jjdelcerro
            if (attr.getOder() < 1) {
1071
                attr.setOrder(i * 10);
1072 44202 jjdelcerro
            }
1073 43610 jjdelcerro
            attr.setIndex(i++);
1074 44094 jjdelcerro
            attr.fixAll();
1075 43610 jjdelcerro
            if (attr.getEvaluator() != null) {
1076
                this.hasEvaluators = true;
1077
            }
1078
            if (attr.getFeatureAttributeEmulator() != null) {
1079
                this.hasEmulators = true;
1080 43998 jjdelcerro
                String[] x = attr.getFeatureAttributeEmulator().getRequiredFieldNames();
1081 44253 jjdelcerro
                if (!ArrayUtils.isEmpty(x)) {
1082 43998 jjdelcerro
                    this.requiredFields = true;
1083
                }
1084 43610 jjdelcerro
            }
1085 44253 jjdelcerro
            switch (attr.getType()) {
1086 44090 jjdelcerro
                case DataTypes.GEOMETRY:
1087 45152 fdiaz
                    if (this.defaultGeometryAttributeName == null
1088
                        || !StringUtils.equals(this.defaultGeometryAttributeName, attr.getName())) {
1089 44090 jjdelcerro
                        this.defaultGeometryAttributeName = attr.getName();
1090
                    }
1091
                    break;
1092
                case DataTypes.INSTANT:
1093
                case DataTypes.INTERVAL:
1094
                case DataTypes.DATE:
1095 44253 jjdelcerro
                    if (this.defaultTimeAttributeName == null && attr.isTime()) {
1096 44090 jjdelcerro
                        this.defaultTimeAttributeName = attr.getName();
1097
                    }
1098
                    break;
1099 43610 jjdelcerro
            }
1100
        }
1101
        if (this.defaultGeometryAttributeName != null) {
1102
            this.defaultGeometryAttributeIndex = this.getIndex(this.defaultGeometryAttributeName);
1103
        }
1104 44077 jjdelcerro
        if (this.defaultTimeAttributeName != null) {
1105
            this.defaultTimeAttributeIndex = this.getIndex(this.defaultTimeAttributeName);
1106
        }
1107 43610 jjdelcerro
        this.internalID = Long.toHexString(this.getCRC());
1108 44253 jjdelcerro
1109 43610 jjdelcerro
    }
1110 44253 jjdelcerro
1111 43610 jjdelcerro
    protected long getCRC() {
1112
        StringBuffer buffer = new StringBuffer();
1113
        for (int i = 0; i < this.size(); i++) {
1114
            FeatureAttributeDescriptor x = this.getAttributeDescriptor(i);
1115
            buffer.append(x.getName());
1116
            buffer.append(x.getDataTypeName());
1117
            buffer.append(x.getSize());
1118
        }
1119
        CRC32 crc = new CRC32();
1120
        byte[] data = buffer.toString().getBytes();
1121
        crc.update(data);
1122
        return crc.getValue();
1123
    }
1124 43739 jjdelcerro
1125
    @Override
1126
    public FeatureStore getStore() {
1127 44253 jjdelcerro
        if (this.storeRef == null) {
1128 43739 jjdelcerro
            return null;
1129
        }
1130
        return (FeatureStore) this.storeRef.get();
1131
    }
1132 44253 jjdelcerro
1133 44190 jjdelcerro
    public void setStore(FeatureStore store) {
1134 44253 jjdelcerro
        if (store == null) {
1135
            this.storeRef = null;
1136 44190 jjdelcerro
        } else {
1137
            this.storeRef = new WeakReference(store);
1138
        }
1139
    }
1140 43739 jjdelcerro
1141 44190 jjdelcerro
    @Override
1142 44262 jjdelcerro
    public List<FeatureAttributeDescriptor> getFilteredAttributes(
1143
            Predicate<FeatureAttributeDescriptor> filter,
1144
            int max
1145
    ) {
1146
        List<FeatureAttributeDescriptor> attrs = new ArrayList<>();
1147
        for (FeatureAttributeDescriptor attribute : this) {
1148
            if (filter.test(attribute)) {
1149
                attrs.add(attribute);
1150
            }
1151 45760 jjdelcerro
            if( max>0 && attrs.size()>= max) {
1152
                break;
1153
            }
1154 44262 jjdelcerro
        }
1155
        return attrs;
1156
    }
1157
1158
    @Override
1159
    public List<FeatureAttributeDescriptor> getRecentUseds() {
1160
        return RECENTS_USEDS.getAttributes(this);
1161
    }
1162
1163
    @Override
1164 44190 jjdelcerro
    public void loadFromState(PersistentState state)
1165
            throws PersistenceException {
1166
1167
        hasEvaluators = state.getBoolean("hasEvaluators");
1168
        hasEmulators = state.getBoolean("hasEmulators");
1169
        defaultGeometryAttributeName = state.getString("defaultGeometryAttributeName");
1170
        defaultTimeAttributeName = state.getString("defaultTimeAttributeName");
1171
        defaultGeometryAttributeIndex = state.getInt("defaultGeometryAttributeIndex");
1172
        defaultTimeAttributeIndex = state.getInt("defaultTimeAttributeIndex");
1173
        id = state.getString("id");
1174
        hasOID = state.getBoolean("hasOID");
1175
        allowAtomaticValues = state.getBoolean("allowAtomaticValues");
1176
1177
        requiredFields = state.getBoolean("requiredFields");
1178
        internalID = state.getString("internalID");
1179 44262 jjdelcerro
        tags = (Tags) state.get("tags");
1180
        if( tags == null ) {
1181
            this.tags = new DefaultTags();
1182
        }
1183 45739 jjdelcerro
        this.checkFeaturesAtFinishEditing = state.getBoolean("checkFeaturesAtFinishEditing");
1184
        this.checkFeaturesAtInsert = state.getBoolean("checkFeaturesAtInsert");
1185
1186 44190 jjdelcerro
        List<FeatureAttributeDescriptor> elements = state.getList("elements");
1187
        for (FeatureAttributeDescriptor element : elements) {
1188 44253 jjdelcerro
            ((DefaultFeatureAttributeDescriptor) element).setFeatureType(this);
1189 44190 jjdelcerro
            super.add(element);
1190
        }
1191 44261 jjdelcerro
        this.pk = null;
1192 45739 jjdelcerro
1193
        this.rules = new DefaultFeatureRules();
1194 45741 fdiaz
        List stateRules = state.getList("rules");
1195
        if(stateRules != null) {
1196
            this.rules.addAll(state.getList("rules"));
1197
        }
1198 44190 jjdelcerro
        this.fixAll();
1199
    }
1200
1201
    @Override
1202
    public void saveToState(PersistentState state) throws PersistenceException {
1203
1204
//        FIXME: rules
1205
        state.set("hasEvaluators", hasEvaluators);
1206
        state.set("hasEmulators", hasEmulators);
1207
        state.set("defaultGeometryAttributeName", defaultGeometryAttributeName);
1208
        state.set("defaultTimeAttributeName", defaultTimeAttributeName);
1209
        state.set("defaultGeometryAttributeIndex", defaultGeometryAttributeIndex);
1210
        state.set("defaultTimeAttributeIndex", defaultTimeAttributeIndex);
1211
        state.set("id", id);
1212
        state.set("hasOID", hasOID);
1213
        state.set("allowAtomaticValues", allowAtomaticValues);
1214
1215
        state.set("requiredFields", requiredFields);
1216
        state.set("internalID", internalID);
1217 44253 jjdelcerro
1218 44190 jjdelcerro
        List<FeatureAttributeDescriptor> elements = new ArrayList<>();
1219
        elements.addAll(this);
1220
        state.set("elements", elements);
1221 44262 jjdelcerro
        state.set("tags", tags);
1222 45739 jjdelcerro
        state.set("checkFeaturesAtFinishEditing",this.checkFeaturesAtFinishEditing);
1223
        state.set("checkFeaturesAtInsert",this.checkFeaturesAtInsert);
1224
        state.set("rules", this.rules.iterator());
1225 44190 jjdelcerro
    }
1226 44253 jjdelcerro
1227 44190 jjdelcerro
    private static final String FEATTYPE_PERSISTENCE_DEFINITION_NAME = "FeatureType";
1228
1229
    public static void registerPersistenceDefinition() {
1230
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1231 44253 jjdelcerro
1232 44190 jjdelcerro
        if (manager.getDefinition(FEATTYPE_PERSISTENCE_DEFINITION_NAME)
1233
                == null) {
1234
            DynStruct definition = manager.addDefinition(DefaultFeatureType.class,
1235
                    FEATTYPE_PERSISTENCE_DEFINITION_NAME,
1236
                    FEATTYPE_PERSISTENCE_DEFINITION_NAME
1237 44253 jjdelcerro
                    + " persistent definition",
1238 44190 jjdelcerro
                    null,
1239
                    null
1240
            );
1241
            definition.addDynFieldBoolean("hasEvaluators");
1242
            definition.addDynFieldBoolean("hasEmulators");
1243
            definition.addDynFieldString("defaultGeometryAttributeName");
1244
            definition.addDynFieldString("defaultTimeAttributeName");
1245
            definition.addDynFieldInt("defaultGeometryAttributeIndex");
1246
            definition.addDynFieldInt("defaultTimeAttributeIndex");
1247
            definition.addDynFieldString("id");
1248
            definition.addDynFieldBoolean("hasOID");
1249
            definition.addDynFieldBoolean("allowAtomaticValues");
1250 44253 jjdelcerro
1251 44190 jjdelcerro
            definition.addDynFieldBoolean("requiredFields");
1252 44253 jjdelcerro
            definition.addDynFieldString("internalID");
1253 44190 jjdelcerro
1254
            definition.addDynFieldList("elements")
1255 44253 jjdelcerro
                    .setClassOfItems(FeatureAttributeDescriptor.class);
1256 44262 jjdelcerro
1257 45739 jjdelcerro
            definition.addDynFieldObject("tags").setClassOfValue(Tags.class);
1258
            definition.addDynFieldBoolean("checkFeaturesAtFinishEditing")
1259
                    .setMandatory(false)
1260 45835 omartinez
                    .setDefaultFieldValue(false);
1261 45739 jjdelcerro
            definition.addDynFieldBoolean("checkFeaturesAtInsert")
1262
                    .setMandatory(false)
1263
                    .setDefaultFieldValue(true);
1264
            definition.addDynFieldList("rules")
1265
                    .setClassOfItems(FeatureRules.class);
1266 44190 jjdelcerro
        }
1267
    }
1268
1269 44439 jjdelcerro
    @Override
1270
    public FeatureStore getAsFeatureStore() {
1271
        FeatureStore store = FeatureTypeToStoreProviderAdapter.createFeatureStore(this);
1272
        return store;
1273
    }
1274 44498 omartinez
1275
1276 44583 omartinez
    @Override
1277 44498 omartinez
    public String getNewFieldName() {
1278
        I18nManager i18n = ToolsLocator.getI18nManager();
1279
        String prefix = i18n.getTranslation("_Field");
1280
        String fieldName;
1281
        for (int i = 1; i < 1000; i++) {
1282 44583 omartinez
            fieldName = prefix+i;
1283 44498 omartinez
            if( this.get(fieldName)==null ) {
1284
                return fieldName;
1285
            }
1286
        }
1287 44583 omartinez
        fieldName = prefix + (new Date()).getTime();
1288 44498 omartinez
        return fieldName;
1289
    }
1290 44500 omartinez
1291 44583 omartinez
    @Override
1292 44500 omartinez
   public FeatureType getOriginalFeatureType()  {
1293
        DefaultFeatureStore store = (DefaultFeatureStore) this.getStore();
1294
        if (store==null) {
1295
            return null;
1296
        }
1297
        return store.getOriginalFeatureType(this);
1298
    }
1299 44501 jjdelcerro
    @Override
1300
    public boolean hasOnlyMetadataChanges(FeatureType old) {
1301
        if( old == null ) {
1302
            throw new NullPointerException();
1303
        }
1304
        // Si hay campos nuevos -> false
1305
        for (FeatureAttributeDescriptor attr : this) {
1306 44507 omartinez
            if(!attr.isComputed() && old.getAttributeDescriptor(attr.getName())==null) {
1307 44501 jjdelcerro
                return false;
1308
            }
1309
        }
1310
1311
        // Si se ha eliminado algun campo -> false
1312
        for (FeatureAttributeDescriptor attr : old) {
1313 44507 omartinez
            if(!attr.isComputed() && this.getAttributeDescriptor(attr.getName())==null ) {
1314 44501 jjdelcerro
                return false;
1315
            }
1316
        }
1317
1318
        // No hay campos nuevos ni se ha eliminado ninguno, asi que comparamos
1319
        // los campos uno a uno.
1320
        for (FeatureAttributeDescriptor attr : this) {
1321
            FeatureAttributeDescriptor attrold = old.getAttributeDescriptor(attr.getName());
1322 44507 omartinez
            if(!attr.isComputed() && !attr.hasOnlyMetadataChanges(attrold) ) {
1323 44501 jjdelcerro
                return false;
1324
            }
1325
        }
1326
        return true;
1327
    }
1328 44716 jjdelcerro
1329
    public void writeAsDALFile(File file) {
1330
      try {
1331
        DALFile dalFile = DALFile.getDALFile();
1332
        dalFile.setFeatureType(this);
1333
        if( !dalFile.isEmpty() ) {
1334
          dalFile.write(file);
1335
        }
1336
      } catch (Exception ex) {
1337
        throw new RuntimeException("Can't write as DAL file ("+Objects.toString(file)+").", ex);
1338
      }
1339
    }
1340 45154 jjdelcerro
1341
    @Override
1342
    public JsonObject toJson() {
1343
        return this.toJsonBuilder().build();
1344
    }
1345
1346
    @Override
1347
    public JsonObjectBuilder toJsonBuilder() {
1348
        JsonObjectBuilder builder = Json.createObjectBuilder();
1349 45425 jjdelcerro
        builder.add_class(this);
1350
        builder.add("id",id);
1351
        builder.add("internalID",internalID);
1352
        builder.add("label",label);
1353
        builder.add("description",description);
1354
        builder.add("allowAtomaticValues",allowAtomaticValues);
1355
        builder.add("hasOID",hasOID);
1356
        builder.add("defaultGeometryAttributeName",defaultGeometryAttributeName);
1357
        builder.add("defaultTimeAttributeName",defaultTimeAttributeName);
1358 45739 jjdelcerro
        builder.add("checkFeaturesAtFinishEditing",checkFeaturesAtFinishEditing);
1359
        builder.add("checkFeaturesAtInsert",checkFeaturesAtInsert);
1360 45425 jjdelcerro
        builder.add("tags", tags);
1361
        builder.add("extraColumns", this.extraColumns);
1362
        builder.add("descriptors", this.iterator());
1363 45154 jjdelcerro
1364
        return builder;
1365
    }
1366 45425 jjdelcerro
1367
    public void fromJson(JsonObject json) {
1368
        this.clear();
1369
        this.id = json.getString("id", null);
1370
        this.internalID = json.getString("internalID", null);
1371
        this.label = json.getString("label", null);
1372
        this.description = json.getString("description",null);
1373
        this.allowAtomaticValues = json.getBoolean("allowAtomaticValues",false);
1374 45813 jjdelcerro
        this.checkFeaturesAtFinishEditing = json.getBoolean("checkFeaturesAtFinishEditing",false);
1375 45739 jjdelcerro
        this.checkFeaturesAtInsert = json.getBoolean("checkFeaturesAtInsert",true);
1376 45425 jjdelcerro
        this.hasOID = json.getBoolean("hasOID", false);
1377
        this.defaultGeometryAttributeName = json.getString("defaultGeometryAttributeName", null);
1378
        this.defaultTimeAttributeName = json.getString("defaultTimeAttributeName",null);
1379
        this.tags = (Tags) Json.toObject(json, "tags");
1380
        this.extraColumns = (FeatureExtraColumns) Json.toObject(json, "extraColumns");
1381
        if( json.containsKey("descriptors") ) {
1382
            for (JsonValue jsonValue : json.getJsonArray("descriptors")) {
1383
                DefaultEditableFeatureAttributeDescriptor attr = new DefaultEditableFeatureAttributeDescriptor(this, false);
1384
                attr.fromJson((JsonObject) jsonValue);
1385
                this.add(attr);
1386
            }
1387
        }
1388
    }
1389
1390
    private static class TheJsonSerializer implements JsonManager.JsonSerializer {
1391
1392
        public TheJsonSerializer() {
1393
        }
1394
1395
        @Override
1396
        public Class getObjectClass() {
1397
            return DefaultFeatureType.class;
1398
        }
1399
1400
        @Override
1401
        public Object toObject(JsonObject json) {
1402
            DefaultFeatureType o = new DefaultFeatureType();
1403
            o.fromJson(json);
1404
            return o;
1405
        }
1406
1407
        @Override
1408
        public JsonObjectBuilder toJsonBuilder(Object value) {
1409
            return ((SupportToJson)value).toJsonBuilder();
1410
        }
1411
1412
    }
1413
1414
    public static void selfRegister() {
1415
        Json.registerSerializer(new TheJsonSerializer());
1416
    }
1417
1418 44253 jjdelcerro
}