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 @ 44077

History | View | Annotate | Download (26.1 KB)

1
/**
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
package org.gvsig.fmap.dal.feature.impl;
25

    
26
import java.lang.ref.WeakReference;
27
import java.util.ArrayList;
28
import java.util.Arrays;
29
import java.util.Collections;
30
import java.util.HashSet;
31
import java.util.Iterator;
32
import java.util.LinkedHashSet;
33
import java.util.List;
34
import java.util.Set;
35
import java.util.zip.CRC32;
36
import org.apache.commons.lang3.ArrayUtils;
37
import org.apache.commons.lang3.StringUtils;
38

    
39
import org.cresques.cts.IProjection;
40

    
41
import org.gvsig.fmap.dal.DataTypes;
42
import org.gvsig.fmap.dal.exception.DataException;
43
import org.gvsig.fmap.dal.feature.EditableFeatureType;
44
import org.gvsig.fmap.dal.feature.Feature;
45
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
47
import org.gvsig.fmap.dal.feature.FeatureRules;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.dal.feature.FeatureType;
50
import org.gvsig.tools.dynobject.DynClass;
51
import org.gvsig.tools.dynobject.DynField;
52
import org.gvsig.tools.dynobject.DynMethod;
53
import org.gvsig.tools.dynobject.DynObject;
54
import org.gvsig.tools.dynobject.DynObjectValueItem;
55
import org.gvsig.tools.dynobject.DynStruct;
56
import org.gvsig.tools.dynobject.exception.DynMethodException;
57
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
58

    
59
public class DefaultFeatureType extends ArrayList<FeatureAttributeDescriptor> implements FeatureType,
60
                DynClass, org.gvsig.tools.lang.Cloneable {
61

    
62
        /**
63
         *
64
         */
65
        private static final long serialVersionUID = -7988721447349282215L;
66

    
67
        private DefaultFeatureRules rules;
68
        protected boolean hasEvaluators;
69
        protected boolean hasEmulators;
70
        protected String defaultGeometryAttributeName;
71
        protected String defaultTimeAttributeName;
72
        protected int defaultGeometryAttributeIndex;
73
        protected int defaultTimeAttributeIndex;
74
        private String id;
75
        protected boolean hasOID;
76
        protected boolean allowAtomaticValues;
77
        protected FeatureAttributeDescriptor[] pk = null;
78
        protected String internalID = null;
79

    
80
        private List srsList = null;
81
        private WeakReference storeRef;
82
        private boolean requiredFields;
83

    
84
        protected DefaultFeatureType(FeatureStore store, String id) {
85
            if (StringUtils.isEmpty(id)) {
86
                id = "default";
87
            }
88
            if( store == null ) {
89
                this.storeRef = null; 
90
            } else {
91
                this.storeRef = new WeakReference(store);
92
            }
93
            this.internalID = Integer.toHexString((int) (Math.random() * 100000)).toUpperCase();
94
            this.id = id;
95
            this.rules = new DefaultFeatureRules();
96
            this.hasEvaluators = false;
97
            this.hasEmulators = false;
98
            this.defaultGeometryAttributeName = null;
99
            this.defaultTimeAttributeName = null;
100
            this.defaultGeometryAttributeIndex = -1;
101
            this.defaultTimeAttributeIndex = -1;
102
            this.allowAtomaticValues = false;
103
        }
104

    
105
        protected DefaultFeatureType(FeatureStore store) {
106
                this(store, (String)null);
107
        }
108

    
109
        protected DefaultFeatureType(DefaultFeatureType other) {
110
                this(other.getStore(), (String)null);
111
                initialize(other, true);
112
        }
113

    
114
        protected DefaultFeatureType(DefaultFeatureType other,
115
                        boolean copyAttributes) {
116
                this(other.getStore(), (String)null);
117
                initialize(other, copyAttributes);
118
        }
119

    
120
        protected void initialize(DefaultFeatureType other, boolean copyAttributes) {
121
                this.id = other.getId();
122
                if (copyAttributes) {
123
                    Iterator iter = other.iterator();
124
                    DefaultFeatureAttributeDescriptor attr;
125
                    while (iter.hasNext()) {
126
                            attr = (DefaultFeatureAttributeDescriptor) iter.next();
127
                            this.intitalizeAddAttibute(attr);
128
                    }
129
                    if( other.pk!=null ) {
130
                        this.pk = new FeatureAttributeDescriptor[other.pk.length];
131
                        for( int i=0; i<other.pk.length; i++ ) {
132
                            this.pk[i] = other.pk[i].getCopy();
133
                        }
134
                    }
135
                }
136
                this.defaultGeometryAttributeName = other.defaultGeometryAttributeName;
137
                this.defaultTimeAttributeName = other.defaultTimeAttributeName;
138
                this.hasEvaluators = other.hasEvaluators;
139
                this.hasEmulators = other.hasEmulators;
140
                this.rules = (DefaultFeatureRules) other.rules.getCopy();
141
                this.defaultGeometryAttributeIndex = other.defaultGeometryAttributeIndex;
142
                this.defaultTimeAttributeIndex = other.defaultTimeAttributeIndex;
143
                this.hasOID = other.hasOID;
144
                this.id = other.id; // XXX ???? copiar o no esto????
145
                this.internalID = other.internalID;
146
        }
147

    
148
        protected void intitalizeAddAttibute(DefaultFeatureAttributeDescriptor attr) {
149
                super.add(attr.getCopy());
150
        }
151

    
152
        public String getId() {
153
                return this.id;
154
        }
155

    
156
        public Object get(String name) {
157
                FeatureAttributeDescriptor attr;
158
                Iterator iter = this.iterator();
159
                while (iter.hasNext()) {
160
                        attr = (FeatureAttributeDescriptor) iter.next();
161
                        if (attr.getName().equalsIgnoreCase(name)) {
162
                                return attr;
163
                        }
164
                }
165
                return null;
166
        }
167

    
168
        public FeatureAttributeDescriptor getAttributeDescriptor(String name) {
169
                FeatureAttributeDescriptor attr;
170
                Iterator iter = this.iterator();
171
                while (iter.hasNext()) {
172
                        attr = (FeatureAttributeDescriptor) iter.next();
173
                        if (attr.getName().equalsIgnoreCase(name)) {
174
                                return attr;
175
                        }
176
                }
177
                return null;
178
        }
179

    
180
        public FeatureAttributeDescriptor getAttributeDescriptor(int index) {
181
                return (FeatureAttributeDescriptor) super.get(index);
182
        }
183

    
184
        public FeatureType getCopy() {
185
                return new DefaultFeatureType(this);
186
        }
187

    
188
        public Object clone() {
189
            return this.getCopy();
190
        }
191

    
192
        public int getDefaultGeometryAttributeIndex() {
193
                return this.defaultGeometryAttributeIndex;
194
        }
195

    
196
        public String getDefaultGeometryAttributeName() {
197
                return this.defaultGeometryAttributeName;
198
        }
199

    
200
        public int getDefaultTimeAttributeIndex() {
201
                return this.defaultTimeAttributeIndex;
202
        }
203

    
204
        public String getDefaultTimeAttributeName() {
205
                return this.defaultTimeAttributeName;
206
        }
207

    
208
        public EditableFeatureType getEditable() {
209
                return new DefaultEditableFeatureType(this);
210
        }
211

    
212
        public int getIndex(String name) {
213
                FeatureAttributeDescriptor attr;
214
                Iterator iter = this.iterator();
215
                while (iter.hasNext()) {
216
                        attr = (FeatureAttributeDescriptor) iter.next();
217
                        if (attr.getName().equalsIgnoreCase(name)) {
218
                                return attr.getIndex();
219
                        }
220
                }
221
                return -1;
222
        }
223

    
224
        public FeatureRules getRules() {
225
                return this.rules;
226
        }
227

    
228
        public boolean hasEvaluators() {
229
                return this.hasEvaluators;
230
        }
231

    
232
        public boolean hasEmulators() {
233
                return this.hasEmulators;
234
        }
235
        
236
        public boolean hasRequiredFields() {
237
            return this.requiredFields;
238
        }
239

    
240
        public List getSRSs() {
241
                if (this.srsList == null) {
242
                        ArrayList tmp = new ArrayList();
243
                        Iterator iter = iterator();
244
                        Iterator tmpIter;
245
                        boolean allreadyHave;
246
                        IProjection tmpSRS;
247
                        FeatureAttributeDescriptor attr;
248
                        while (iter.hasNext()){
249
                                attr = (FeatureAttributeDescriptor) iter.next();
250
                                if (attr.getDataType().getType() == DataTypes.GEOMETRY
251
                                                && attr.getSRS() != null) {
252
                                        allreadyHave = false;
253
                                        tmpIter = tmp.iterator();
254
                                        while (tmpIter.hasNext()) {
255
                                                tmpSRS = (IProjection) tmpIter.next();
256
                                                if (tmpSRS.getAbrev().equals(attr.getSRS().getAbrev())) {
257
                                                        allreadyHave = true;
258
                                                        break;
259
                                                }
260
                                        }
261
                                        if (!allreadyHave) {
262
                                                tmp.add(attr.getSRS());
263
                                        }
264
                                }
265
                        }
266
                        this.srsList = Collections.unmodifiableList(tmp);
267
                }
268
                return this.srsList;
269
        }
270

    
271
        public IProjection getDefaultSRS() {
272
                if (this.getDefaultGeometryAttributeIndex() < 0) {
273
                        return null;
274
                }
275
                return this.getAttributeDescriptor(
276
                                this.getDefaultGeometryAttributeIndex()).getSRS();
277
        }
278

    
279
        public void validateFeature(Feature feature, int mode) throws DataException {
280
            DefaultFeatureRules rules = (DefaultFeatureRules) this.getRules();
281
            rules.validate(feature,mode);
282
        }
283

    
284
        public FeatureType getSubtype(String[] names) throws DataException {
285
                if( names==null || names.length <1) {
286
                    return (FeatureType) this.clone();
287
                }
288
                return new SubtypeFeatureType(this, names, null);
289
        }
290

    
291
        public FeatureType getSubtype(String[] names, String[] constantsNames) throws DataException {
292
        if( ArrayUtils.isEmpty(names) && ArrayUtils.isEmpty(constantsNames) ) {
293
            return (FeatureType) this.clone();
294
        }
295
                return new SubtypeFeatureType(this, names,constantsNames);
296
        }
297

    
298
        public FeatureType getSubtype() throws DataException {
299
                return new SubtypeFeatureType(this, null,null);
300
        }
301

    
302
        public boolean isSubtypeOf(FeatureType featureType) {
303
                return false;
304
        }
305

    
306

    
307

    
308
        class SubtypeFeatureType extends DefaultFeatureType {
309
                /**
310
                 *
311
                 */
312
                private static final long serialVersionUID = 6913732960073922540L;
313
                WeakReference parent;
314

    
315
                SubtypeFeatureType(DefaultFeatureType parent, String[] names, String[] constantsNames)
316
                        throws DataException {
317
                    super(parent, false);
318
                    DefaultFeatureAttributeDescriptor attrcopy;
319
                    Set<String> attrnames = new LinkedHashSet<>();
320
                    Set<String> requiredAttrnames = new HashSet<>();
321
                    
322
                    if ( ArrayUtils.isEmpty(names) ) {
323
                        for (FeatureAttributeDescriptor attrdesc : parent) {
324
                            attrnames.add(attrdesc.getName());
325
                        }
326
                    } else {
327
                        attrnames.addAll(Arrays.asList(names));
328
                        requiredAttrnames.addAll(Arrays.asList(names));
329
                    }
330
                    // Add required fields for emulated fields
331
                    if ( parent.hasEmulators ) {
332
                        for (FeatureAttributeDescriptor attrdesc : parent) {
333
                            FeatureAttributeEmulator emulator = attrdesc.getFeatureAttributeEmulator();
334
                            if ( emulator != null ) {
335
                                String ss[] = emulator.getRequiredFieldNames();
336
                                if ( ss != null ) {
337
                                    attrnames.addAll(Arrays.asList(ss));
338
                                    requiredAttrnames.addAll(Arrays.asList(ss));
339
                                }
340
                            }
341
                        }
342
                    }
343
                    // Add missing pk fiels
344
                    if ( !parent.hasOID() ) {
345
                        for (FeatureAttributeDescriptor attrdesc : parent) {
346
                            if ( attrdesc.isPrimaryKey() ) {
347
                                attrnames.add(attrdesc.getName());
348
                                requiredAttrnames.add(attrdesc.getName());
349
                            }
350
                        }
351
                    }
352
                        
353
                    // Copy attributes
354
                    int i = 0;
355
                    for (String name : attrnames) {
356
                        DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) parent.get(name);
357
                        if ( attr == null ) {
358
                            throw new SubtypeFeatureTypeNameException(name, parent.getId());
359
                        }
360
                        attrcopy = new DefaultFeatureAttributeDescriptor(attr);
361
                        this.add(attrcopy);
362
                        attrcopy.index = i++;
363
                    }
364
                    
365
                    // Set the consttants attributes.
366
                    if ( !ArrayUtils.isEmpty(constantsNames) ) {
367
                        for (String name : constantsNames) {
368
                            if ( !requiredAttrnames.contains(name) ) { 
369
                                DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) this.get(name);
370
                                attr.setConstantValue(true);
371
                            }
372
                        }
373
                    }
374

    
375
                    this.defaultGeometryAttributeIndex = this.getIndex(this.defaultGeometryAttributeName);
376
                    if ( this.defaultGeometryAttributeIndex < 0 ) {
377
                        this.defaultGeometryAttributeName = null;
378
                    }
379
                    this.defaultTimeAttributeIndex = this.getIndex(this.defaultTimeAttributeName);
380
                    if ( this.defaultTimeAttributeIndex < 0 ) {
381
                        this.defaultTimeAttributeName = null;
382
                    }
383
                    this.parent = new WeakReference(parent);
384
                }
385

    
386
                public FeatureType getSubtype(String[] names) throws DataException {
387
                        return new SubtypeFeatureType((DefaultFeatureType) this.parent
388
                                        .get(), names, null);
389
                }
390

    
391
                public boolean isSubtypeOf(FeatureType featureType) {
392
                        if (featureType == null) {
393
                                return false;
394
                        }
395
                        FeatureType parent = (FeatureType) this.parent.get();
396
                        return featureType.equals(parent);
397
                }
398

    
399
                public EditableFeatureType getEditable() {
400
                        throw new UnsupportedOperationException();
401
                }
402
        }
403

    
404
        public class SubtypeFeatureTypeNameException extends DataException {
405

    
406
                /**
407
                 *
408
                 */
409
                private static final long serialVersionUID = -4414242486723260101L;
410
                private final static String MESSAGE_FORMAT = "Attribute name '%(name)' not found in type (%(type)).";
411
                private final static String MESSAGE_KEY = "_SubtypeFeatureTypeNameException";
412

    
413
                public SubtypeFeatureTypeNameException(String name, String type) {
414
                        super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
415
                        setValue("name", name);
416
                        setValue("type", type);
417
                }
418
        }
419

    
420
        public boolean hasOID() {
421
                return hasOID;
422
        }
423
        public String toString(){
424
                StringBuffer s = new StringBuffer();
425
                s.append(this.getId());
426
                s.append(":[");
427
                String attName;
428
                for (int i = 0; i < size(); i++) {
429
                        attName =((FeatureAttributeDescriptor)get(i)).getName().toString();
430
                        s.append(attName);
431
                        if (i < size() - 1) {
432
                                s.append(',');
433
                        }
434
                }
435
                s.append(']');
436
                return s.toString();
437
        }
438

    
439
        public Iterator iterator() {
440
                return getIterator(super.iterator());
441
        }
442

    
443
        protected Iterator getIterator(Iterator iter) {
444
                return new DelegatedIterator(iter);
445
        }
446

    
447
        protected class DelegatedIterator implements Iterator {
448

    
449
                protected Iterator iterator;
450

    
451
                public DelegatedIterator(Iterator iter) {
452
                        this.iterator = iter;
453
                }
454

    
455
                public boolean hasNext() {
456
                        return iterator.hasNext();
457
                }
458

    
459
                public Object next() {
460
                        return iterator.next();
461
                }
462

    
463
                public void remove() {
464
                        throw new UnsupportedOperationException();
465
                }
466

    
467
        }
468

    
469
        public boolean allowAutomaticValues() {
470
                return this.allowAtomaticValues;
471
        }
472

    
473
        public FeatureAttributeDescriptor[] getAttributeDescriptors() {
474
                return (FeatureAttributeDescriptor[]) super
475
                                .toArray(new FeatureAttributeDescriptor[super.size()]);
476
        }
477

    
478
        public FeatureAttributeDescriptor[] getPrimaryKey() {
479
                if (pk == null) {
480
                        List pks = new ArrayList();
481
                        Iterator iter = super.iterator();
482
                        FeatureAttributeDescriptor attr;
483
                        while (iter.hasNext()){
484
                                attr = (FeatureAttributeDescriptor) iter.next();
485
                                if (attr.isPrimaryKey()){
486
                                        pks.add(attr);
487
                                }
488
                        }
489
            if( pks.isEmpty() ) {
490
                pk = new FeatureAttributeDescriptor[0];
491
            } else {
492
                pk = (FeatureAttributeDescriptor[])pks.toArray(new FeatureAttributeDescriptor[pks.size()]);
493
            }
494
                }
495
                return pk;
496
        }
497

    
498
        public FeatureAttributeDescriptor getDefaultGeometryAttribute() {
499
                if (this.defaultGeometryAttributeIndex < 0) {
500
                        return null;
501
                }
502
                return (FeatureAttributeDescriptor) super
503
                                .get(this.defaultGeometryAttributeIndex);
504
        }
505

    
506

    
507

    
508
        public boolean equals(Object o) {
509
            if (this == o) {
510
                    return true;
511
            }
512
            if (!(o instanceof DefaultFeatureType)) {
513
                    return false;
514
            }
515
            DefaultFeatureType other = (DefaultFeatureType) o;
516
            if (!this.id.equals(other.id)) {
517
                    return false;
518
            }
519
            if (this.size() != other.size()) {
520
                    return false;
521
            }
522
            FeatureAttributeDescriptor attr,attrOther;
523
            Iterator iter,iterOther;
524
            iter = this.iterator();
525
            iterOther = other.iterator();
526
            while (iter.hasNext()) {
527
                    attr = (FeatureAttributeDescriptor) iter.next();
528
                    attrOther = (FeatureAttributeDescriptor) iterOther.next();
529
                    if (!attr.equals(attrOther)) {
530
                            return false;
531
                    }
532
            }
533

    
534
            if( !StringUtils.equals(defaultGeometryAttributeName, other.defaultGeometryAttributeName)) {
535
                return false;
536
            }
537
            if( !StringUtils.equals(defaultTimeAttributeName, other.defaultTimeAttributeName)) {
538
                return false;
539
            }
540
            return true;
541

    
542
        }
543

    
544
        /**
545
         * Start of DynClass interface implementation
546
         * READONLY
547
         */
548

    
549
        public DynField addDynField(String name) {
550
                throw new UnsupportedOperationException();
551
        }
552

    
553
        public DynField getDeclaredDynField(String name) {
554
                return (DynField) getAttributeDescriptor(name);
555
        }
556

    
557
        public DynField[] getDeclaredDynFields() {
558
                return (DynField[]) getAttributeDescriptors();
559
        }
560

    
561
        public String getDescription() {
562
                return null;
563
        }
564

    
565
        public DynField getDynField(String name) {
566
                return (DynField) getAttributeDescriptor(name);
567
        }
568

    
569
        public DynField[] getDynFields() {
570
                return (DynField[]) getAttributeDescriptors();
571
        }
572

    
573
        public String getName() {
574
                return this.id + "_" + internalID;
575
        }
576

    
577
        public void removeDynField(String name) {
578
                throw new UnsupportedOperationException();
579

    
580
        }
581

    
582
        public void addDynMethod(DynMethod dynMethod) {
583
                throw new UnsupportedOperationException();
584

    
585
        }
586

    
587
        public void extend(DynClass dynClass) {
588
                throw new UnsupportedOperationException();
589

    
590
        }
591

    
592
        public void extend(String dynClassName) {
593
                throw new UnsupportedOperationException();
594

    
595
        }
596

    
597
        public void extend(String namespace, String dynClassName) {
598
                throw new UnsupportedOperationException();
599

    
600
        }
601

    
602
        public DynMethod getDeclaredDynMethod(String name)
603
                        throws DynMethodException {
604
                return null;
605
        }
606

    
607
        public DynMethod[] getDeclaredDynMethods() throws DynMethodException {
608
                return null;
609
        }
610

    
611
        public DynMethod getDynMethod(String name) throws DynMethodException {
612
                return null;
613
        }
614

    
615
        public DynMethod getDynMethod(int code) throws DynMethodException {
616
                return null;
617
        }
618

    
619
        public DynMethod[] getDynMethods() throws DynMethodException {
620
                return null;
621
        }
622

    
623
        public DynClass[] getSuperDynClasses() {
624
                return null;
625
        }
626

    
627
        public boolean isInstance(DynObject dynObject) {
628
                if (dynObject.getDynClass().getName() == getName()) {
629
                        return true;
630
                }
631
                return false;
632
        }
633

    
634
        public DynObject newInstance() {
635

    
636
                throw new UnsupportedOperationException();
637
        }
638

    
639
        public void removeDynMethod(String name) {
640
                throw new UnsupportedOperationException();
641

    
642
        }
643

    
644
        public DynField addDynFieldChoice(String name, int type,
645
                        Object defaultValue, DynObjectValueItem[] values,
646
                        boolean mandatory, boolean persistent) {
647
                throw new UnsupportedOperationException();
648
        }
649

    
650
        public DynField addDynFieldRange(String name, int type,
651
                        Object defaultValue, Object min, Object max, boolean mandatory,
652
                        boolean persistent) {
653
                throw new UnsupportedOperationException();
654
        }
655

    
656
        public DynField addDynFieldSingle(String name, int type,
657
                        Object defaultValue, boolean mandatory, boolean persistent) {
658
                throw new UnsupportedOperationException();
659
        }
660

    
661
        public void validate(DynObject object) throws DynObjectValidateException {
662
                //FIXME: not sure it's the correct code
663
                if (object instanceof Feature) {
664
                        Feature fea = (Feature) object;
665
                        if (fea.getType().equals(this)) {
666
                                return;
667
                        }
668
                }
669
                throw new DynObjectValidateException(this.id);
670
        }
671

    
672
        public DynField addDynFieldLong(String name) {
673
                throw new UnsupportedOperationException();
674
        }
675

    
676
        public DynField addDynFieldChoice(String name, int type,
677
                        Object defaultValue, DynObjectValueItem[] values) {
678
                throw new UnsupportedOperationException();
679
        }
680

    
681
        public DynField addDynFieldRange(String name, int type,
682
                        Object defaultValue, Object min, Object max) {
683
                throw new UnsupportedOperationException();
684
        }
685

    
686
        public DynField addDynFieldSingle(String name, int type, Object defaultValue) {
687
                throw new UnsupportedOperationException();
688
        }
689

    
690
        public DynField addDynFieldString(String name) {
691
                throw new UnsupportedOperationException();
692
        }
693

    
694
        public DynField addDynFieldInt(String name) {
695
                throw new UnsupportedOperationException();
696
        }
697

    
698
        public DynField addDynFieldDouble(String name) {
699
                throw new UnsupportedOperationException();
700
        }
701

    
702
        public DynField addDynFieldFloat(String name) {
703
                throw new UnsupportedOperationException();
704
        }
705

    
706
        public DynField addDynFieldBoolean(String name) {
707
                throw new UnsupportedOperationException();
708
        }
709

    
710
        public DynField addDynFieldList(String name) {
711
                throw new UnsupportedOperationException();
712
        }
713

    
714
        public DynField addDynFieldMap(String name) {
715
                throw new UnsupportedOperationException();
716
        }
717

    
718
        public DynField addDynFieldObject(String name) {
719
                throw new UnsupportedOperationException();
720
        }
721

    
722
        public DynField addDynFieldSet(String name) {
723
                throw new UnsupportedOperationException();
724
        }
725

    
726
        public DynField addDynFieldArray(String name) {
727
                throw new UnsupportedOperationException();
728
        }
729

    
730
        public DynField addDynFieldDate(String name) {
731
                throw new UnsupportedOperationException();
732
        }
733

    
734
        public void extend(DynStruct struct) {
735
                throw new UnsupportedOperationException();
736
        }
737

    
738
        public String getFullName() {
739
        // TODO: usar el DynClassName
740
                return this.id;
741
        }
742

    
743
        public String getNamespace() {
744
                return "DALFeature";
745
        }
746

    
747
        public DynStruct[] getSuperDynStructs() {
748
                return null;
749
        }
750

    
751
        public void setDescription(String description) {
752
                throw new UnsupportedOperationException();
753
        }
754

    
755
        public void setNamespace(String namespace) {
756
                throw new UnsupportedOperationException();
757
        }
758

    
759
        public DynField addDynFieldFile(String name) {
760
                throw new UnsupportedOperationException();
761
        }
762

    
763
        public DynField addDynFieldFolder(String name) {
764
                throw new UnsupportedOperationException();
765
        }
766

    
767
        public DynField addDynFieldURL(String name) {
768
                throw new UnsupportedOperationException();
769
        }
770

    
771
        public DynField addDynFieldURI(String name) {
772
                throw new UnsupportedOperationException();
773
        }
774

    
775
    public boolean isExtendable(DynStruct dynStruct) {
776
        return false;
777
    }
778

    
779
        public void extend(DynStruct[] structs) {
780
                // TODO Auto-generated method stub
781

    
782
        }
783

    
784
        public void remove(DynStruct superDynStruct) {
785
                // TODO Auto-generated method stub
786

    
787
        }
788

    
789
        public void removeAll(DynStruct[] superDynStruct) {
790
                // TODO Auto-generated method stub
791

    
792
        }
793

    
794
        public FeatureAttributeDescriptor getDefaultTimeAttribute() {
795
                if (this.defaultTimeAttributeIndex < 0) {
796
                        return null;
797
                }
798
                return (FeatureAttributeDescriptor) super
799
                                .get(this.defaultTimeAttributeIndex);
800
        }
801

    
802
    public void setDefaultTimeAttributeName(String name) {
803
        if (name == null || name.length() == 0) {
804
            this.defaultTimeAttributeIndex = -1;
805
            return;
806
        }
807
        DefaultFeatureAttributeDescriptor attr = (DefaultFeatureAttributeDescriptor) this.get(name);
808
        if (attr == null) {
809
            throw new IllegalArgumentException("Attribute '" + name + "' not found.");
810
        }
811
        if( attr.getIndex()<0 ) {
812
            fixAll();
813
        }
814
        this.defaultTimeAttributeIndex = attr.getIndex();
815
    }
816
    
817
    protected void fixAll() {
818
        int i = 0;
819
        Iterator iter = super.iterator();
820
        DefaultFeatureAttributeDescriptor attr;
821

    
822
        while (iter.hasNext()) {
823
            attr = (DefaultFeatureAttributeDescriptor) iter.next();
824
            attr.setIndex(i++);
825
            if (attr instanceof DefaultEditableFeatureAttributeDescriptor) {
826
                ((DefaultEditableFeatureAttributeDescriptor) attr).fixAll();
827
            }
828
            if (attr.getEvaluator() != null) {
829
                this.hasEvaluators = true;
830
            }
831
            if (attr.getFeatureAttributeEmulator() != null) {
832
                this.hasEmulators = true;
833
                String[] x = attr.getFeatureAttributeEmulator().getRequiredFieldNames();
834
                if( !ArrayUtils.isEmpty(x) ) {
835
                    this.requiredFields = true;
836
                }
837
            }
838
            if (this.defaultGeometryAttributeName == null && attr.getType() == DataTypes.GEOMETRY) {
839
                this.defaultGeometryAttributeName = attr.getName();
840
            }
841
            if (this.defaultTimeAttributeName == null && 
842
                    (attr.getType() == DataTypes.INSTANT || attr.getType() == DataTypes.INTERVAL) ) {
843
                this.defaultTimeAttributeName = attr.getName();
844
            }
845
        }
846
        if (this.defaultGeometryAttributeName != null) {
847
            this.defaultGeometryAttributeIndex = this.getIndex(this.defaultGeometryAttributeName);
848
        }
849
        if (this.defaultTimeAttributeName != null) {
850
            this.defaultTimeAttributeIndex = this.getIndex(this.defaultTimeAttributeName);
851
        }
852
        this.internalID = Long.toHexString(this.getCRC());
853
        
854
    }
855
    
856
    protected long getCRC() {
857
        StringBuffer buffer = new StringBuffer();
858
        for (int i = 0; i < this.size(); i++) {
859
            FeatureAttributeDescriptor x = this.getAttributeDescriptor(i);
860
            buffer.append(x.getName());
861
            buffer.append(x.getDataTypeName());
862
            buffer.append(x.getSize());
863
        }
864
        CRC32 crc = new CRC32();
865
        byte[] data = buffer.toString().getBytes();
866
        crc.update(data);
867
        return crc.getValue();
868
    }
869

    
870
    @Override
871
    public FeatureStore getStore() {
872
        if( this.storeRef == null ) {
873
            return null;
874
        }
875
        return (FeatureStore) this.storeRef.get();
876
    }
877

    
878
}