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

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