Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / dynobject / impl / DefaultDynField.java @ 1860

History | View | Annotate | Download (27.6 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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 2 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.tools.dynobject.impl;
24

    
25
import java.io.File;
26
import java.net.URI;
27
import java.net.URL;
28
import java.util.Collection;
29
import java.util.Date;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Set;
34
import org.apache.commons.lang3.StringUtils;
35

    
36
import org.gvsig.tools.ToolsLocator;
37
import org.gvsig.tools.dataTypes.CoercionException;
38
import org.gvsig.tools.dataTypes.DataType;
39
import org.gvsig.tools.dataTypes.DataTypes;
40
import org.gvsig.tools.dataTypes.DataTypesManager;
41
import org.gvsig.tools.dynobject.DynField;
42
import org.gvsig.tools.dynobject.DynField_v2;
43
import org.gvsig.tools.dynobject.DynMethod;
44
import org.gvsig.tools.dynobject.DynObject;
45
import org.gvsig.tools.dynobject.DynObjectValueItem;
46
import org.gvsig.tools.dynobject.DynStruct;
47
import org.gvsig.tools.dynobject.Tags;
48
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
49
import org.gvsig.tools.dynobject.exception.DynFieldRequiredValueException;
50
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
51
import org.gvsig.tools.dynobject.exception.DynMethodException;
52
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
53
import org.gvsig.tools.exception.ListBaseException;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
@SuppressWarnings("EqualsAndHashcode")
58
public class DefaultDynField implements DynField_v2 {
59

    
60
    public static final Logger log = LoggerFactory.getLogger(DefaultDynField.class);
61

    
62
    private String name;
63
    private String description;
64

    
65
    private ValueType valueType;
66

    
67
    private String subtype;
68

    
69
    private Object defaultValue;
70

    
71
    private int order;
72
    private boolean hidden;
73
    private String groupName;
74
    private DynObjectValueItem[] availableValues;
75
    private DynMethod availableValuesMethod = null;
76

    
77
    private Object minValue;
78
    private Object maxValue;
79
    private boolean mandatory;
80
    private boolean persistent;
81
    private String label = null;
82

    
83
    private boolean isReadOnly;
84
    private Tags tags = new DefaultTags();
85

    
86
    private ValueType itemsType;
87
    private boolean validateItems;
88

    
89
//        Para implementacion futura, como minimo para implementar
90
//        un copy entre dynobject y saber cuando parar.
91
//        Los valores deberan ser algo asi como:
92
//        - Identidad/Identity, 1:1 y se copian.
93
//        - Composicion/Composition, 1:N y se copian.
94
//        - Agregacion/Aggregate, 1:N, no se copian
95
//        - Colaboracion/Collaboration, 1:1, no se copian
96
//        Y solo tendra efecto/sentido cuando el field sea de tipo
97
//        DynObject, y tal vez lista de DynObject
98
    private int relationType;
99
    private DynMethod calculate = null;
100

    
101
    public DefaultDynField(String name, int dataType) {
102
        this(name, // field name
103
                dataType, // data type
104
                null, // default value
105
                true, // persistent
106
                false // mandatory
107
        );
108
    }
109

    
110
    @SuppressWarnings("OverridableMethodCallInConstructor")
111
    protected DefaultDynField(String name, int dataType, Object defaultValue,
112
            boolean persistent, boolean mandatory) {
113
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
114

    
115
        if (StringUtils.isBlank(name)) {
116
            throw new IllegalArgumentException("name can't be null");
117
        }
118
        this.name = name;
119
        this.valueType = new ValueType(dataType);
120
        this.subtype = this.getSubtype();
121

    
122
        this.defaultValue = defaultValue;
123
        this.persistent = persistent;
124
        this.mandatory = mandatory;
125
        this.groupName = null;
126
        this.order = 0;
127
        this.hidden = false;
128
        this.availableValues = null;
129

    
130
        this.itemsType = new ValueType(DataTypes.UNKNOWN);
131
        this.validateItems = false;
132
        this.relationType = RELATION_TYPE_NONE;
133
    }
134

    
135
    @Override
136
    public void copyFrom(DynField other) {
137
        this.name = other.getName();
138
        this.description = other.getDescription();
139
        this.subtype = other.getSubtype();
140
        this.defaultValue = other.getDefaultValue();
141
        this.order = other.getOder();
142
        this.hidden = other.isHidden();
143
        this.groupName = other.getGroup();
144
        this.minValue = other.getMinValue();
145
        this.maxValue = other.getMaxValue();
146
        this.mandatory = other.isMandatory();
147
        this.persistent = other.isMandatory();
148
        this.isReadOnly = other.isReadOnly();
149
        this.tags = new DefaultTags();
150

    
151
        if (other instanceof DynField_v2) {
152
            DynField_v2 other2 = (DynField_v2) other;
153
            this.tags.add(other2.getTags());
154
            this.label = other2.getLabel();
155
            this.validateItems = other2.getValidateElements();
156
            
157
            if (other2.isCalculated()) {
158
                this.setCalculateMethod(other2.getCalculateMethod());
159
            }
160
            
161
            if( other2.isAvailableValuesCalculated() ) {
162
                this.availableValuesMethod = other2.getAvailableValuesMethod();
163
            } else {
164
                this.availableValues = other.getAvailableValues().clone();
165
            }
166
            
167
            this.setType(other.getDataType());
168
            this.setClassOfValue(other2.getClassOfValue());
169
            this.setClassOfValue(other2.getDynClassOfValue());
170
            
171
            this.setTypeOfItems(other2.getTypeOfItems());
172
            this.setClassOfItems(other2.getClassOfItems());
173
            this.setClassOfItems(other2.getDynClassOfItems());
174
        }
175

    
176
    }
177

    
178
    protected ValueType getValueType() {
179
        return valueType;
180
    }
181

    
182
    @Override
183
    public DynField setCalculateMethod(DynMethod method) {
184
        this.calculate = method;
185
        this.persistent = false;
186
        return this;
187
    }
188

    
189
    public DynMethod getCalculateMethod() {
190
        return this.calculate;
191
    }
192

    
193
    @Override
194
    public boolean isCalculated() {
195
        return this.calculate != null;
196
    }
197

    
198
    @Override
199
    public Object getCalculatedValue(DynObject self) {
200
        try {
201
            return this.calculate.invoke(self, new Object[]{this});
202
        } catch (DynMethodException ex) {
203
            throw new RuntimeException(ex);
204
        }
205
    }
206

    
207
    public void check() throws ListBaseException {
208
    }
209

    
210
    @Override
211
    public String toString() {
212
        StringBuilder buffer = new StringBuilder();
213

    
214
        buffer.append("DynField").append("[").append(this.hashCode())
215
                .append("]").append("( ").append("name='").append(this.name)
216
                .append("', ").append("description='").append(this.description)
217
                .append("', ").append("type='").append(this.valueType)
218
                .append("', ").append("subType='").append(this.subtype)
219
                .append("', ").append("mandatory='").append(this.isMandatory())
220
                .append("', ").append("defaultValue='")
221
                .append(this.getDefaultValue()).append("', ")
222
                .append("minValue='").append(this.minValue).append("', ")
223
                .append("maxValue='").append(this.maxValue).append("', ")
224
                .append("persistent='").append(this.isPersistent())
225
                .append(" )");
226
        return buffer.toString();
227
    }
228

    
229
    @Override
230
    public String getName() {
231
        return name;
232
    }
233

    
234
    public DynField setName(String name) {
235
        if (StringUtils.isBlank(name)) {
236
            throw new IllegalArgumentException("name can't be null");
237
        }
238
        this.name = name;
239
        return this;
240
    }
241

    
242
    @Override
243
    public DynField setDescription(String description) {
244
        this.description = description;
245
        return this;
246
    }
247

    
248
    @Override
249
    public String getDescription() {
250
        return (description == null) ? getLabel() : description;
251
    }
252

    
253
    @Override
254
    public DynField setLabel(String label) {
255
        this.label = label;
256
        return this;
257
    }
258

    
259
    @Override
260
    public String getLabel() {
261
        return (label == null) ? getName() : label;
262
    }
263

    
264
    @Override
265
    public DynField setType(int dataType) {
266
        this.valueType.setType(dataType);
267
        return this;
268
    }
269

    
270
    @Override
271
    public DynField setType(DataType dataType) {
272
        this.valueType.setType(dataType);
273
        return this;
274
    }
275

    
276
    @Override
277
    public int getType() {
278
        return this.valueType.getType();
279
    }
280

    
281
    @Override
282
    public DataType getDataType() {
283
        return this.valueType.getDataType();
284
    }
285

    
286
    @Override
287
    public DynField setSubtype(String subtype) {
288
        this.subtype = subtype;
289
        return this;
290
    }
291

    
292
    @Override
293
    public String getSubtype() {
294
        return subtype;
295
    }
296

    
297
    @Override
298
    public DynField setDefaultDynValue(Object defaultValue) {
299
        this.defaultValue = defaultValue;
300
        return this;
301
    }
302

    
303
    @Override
304
    public Object getDefaultValue() {
305
        return defaultValue;
306
    }
307

    
308
    @Override
309
    public boolean isAvailableValuesCalculated() {
310
        return this.availableValuesMethod != null;
311
    }
312

    
313
    @Override
314
    public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
315
        if (availableValues == null || availableValues.length == 0) {
316
            this.availableValues = null;
317
        } else {
318
            this.availableValues = availableValues;
319
        }
320
        return this;
321
    }
322

    
323
    @Override
324
    public DynField setAvailableValues(List availableValues) {
325
        if (availableValues == null) {
326
            this.availableValues = null;
327
        } else if (availableValues.isEmpty()) {
328
            this.availableValues = null;
329
        } else {
330
            this.availableValues = (DynObjectValueItem[]) availableValues
331
                    .toArray(new DynObjectValueItem[availableValues.size()]);
332
        }
333
        return this;
334
    }
335

    
336
    @Override
337
    public DynField setAvailableValues(DynMethod computeAvailableValues) {
338
        this.availableValuesMethod = computeAvailableValues;
339
        return this;
340
    }
341

    
342
    @Override
343
    public DynMethod getAvailableValuesMethod() {
344
        return this.availableValuesMethod;
345
    }
346

    
347
    
348
    @Override
349
    public DynObjectValueItem[] getAvailableValues() {
350
        return this.getAvailableValues(null);
351
    }
352

    
353
    @Override
354
    public DynObjectValueItem[] getAvailableValues(DynObject self) {
355
        if (this.availableValuesMethod != null) {
356
            DynObjectValueItem[] values;
357
            try {
358
                values = (DynObjectValueItem[]) this.availableValuesMethod.invoke(self, new Object[]{this});
359
            } catch (DynMethodException ex) {
360
                return this.availableValues;
361
            }
362
            if (values != null) {
363
                return values;
364
            }
365
        }
366
        return this.availableValues;
367
    }
368

    
369
    @Override
370
    public DynField setMinValue(Object minValue) {
371
        try {
372
            this.minValue = this.coerce(minValue);
373
        } catch (CoercionException e) {
374
            throw new IllegalArgumentException();
375
        }
376
        return this;
377
    }
378

    
379
    @Override
380
    public Object getMinValue() {
381
        return minValue;
382
    }
383

    
384
    @Override
385
    public DynField setMaxValue(Object maxValue) {
386
        try {
387
            this.maxValue = this.coerce(maxValue);
388
        } catch (CoercionException e) {
389
            throw new IllegalArgumentException(e);
390
        }
391
        return this;
392
    }
393

    
394
    @Override
395
    public Object getMaxValue() {
396
        return maxValue;
397
    }
398

    
399
    @Override
400
    public boolean isMandatory() {
401
        return this.mandatory;
402
    }
403

    
404
    @Override
405
    public boolean isPersistent() {
406
        if (this.isCalculated()) {
407
            return false;
408
        }
409
        return this.persistent;
410
    }
411

    
412
    @Override
413
    public DynField setMandatory(boolean mandatory) {
414
        this.mandatory = mandatory;
415
        return this;
416
    }
417

    
418
    @Override
419
    public DynField setPersistent(boolean persistent) {
420
        if (this.isCalculated()) {
421
            persistent = false;
422
        }
423
        this.persistent = persistent;
424
        return this;
425
    }
426

    
427
    @Override
428
    public DynField setTheTypeOfAvailableValues(int type) {
429
        return this; // FIXME: this method is @deprecated
430
    }
431

    
432
    @Override
433
    public int getTheTypeOfAvailableValues() {
434
        return 1; // FIXME: this method is @deprecated
435
    }
436

    
437
    /**
438
     *
439
     * @param obj
440
     * @return
441
     */
442
    @Override
443
    public boolean equals(Object obj) {
444
        if (this == obj) {
445
            return true;
446
        }
447
        if (obj instanceof DynField) {
448
            // FIXME: No esta claro que esto sea correcto.
449
            return name.equals(((DynField) obj).getName());
450
        }
451
        return false;
452
    }
453

    
454
    @Override
455
    public Class getClassOfValue() {
456
        return this.valueType.getClassOfValue();
457
    }
458

    
459
    @Override
460
    public DynField setClassOfValue(Class theClass) {
461
        this.valueType.setClassOfValue(theClass);
462
        return this;
463
    }
464

    
465
    @Override
466
    public DynField setClassOfValue(String theClassName) {
467
        this.valueType.setClassOfValue(theClassName);
468
        return this;
469
    }
470

    
471
    @Override
472
    public boolean isContainer() {
473
        if (valueType.getDataType() == null) {
474
            return false;
475
        }
476
        return valueType.getDataType().isContainer();
477
    }
478

    
479
    @Override
480
    public void validate(Object value) throws DynFieldValidateException {
481
        Comparable v;
482
        if (value == null) {
483
            if (this.mandatory) {
484
                throw new DynFieldRequiredValueException(this, value);
485
            }
486
            return;
487
        }
488

    
489
        switch (this.valueType.getType()) {
490
            case DataTypes.BOOLEAN:
491
                if (!(value instanceof Boolean)) {
492
                    throw new DynFieldValidateException(value, this);
493
                }
494
                break;
495

    
496
            case DataTypes.DOUBLE:
497
                if (!(value instanceof Double)) {
498
                    throw new DynFieldValidateException(value, this);
499
                }
500
                break;
501

    
502
            case DataTypes.FLOAT:
503
                if (!(value instanceof Float)) {
504
                    throw new DynFieldValidateException(value, this);
505
                }
506
                break;
507

    
508
            case DataTypes.BYTE:
509
                if (!(value instanceof Byte)) {
510
                    throw new DynFieldValidateException(value, this);
511
                }
512
                break;
513

    
514
            case DataTypes.INT:
515
                if (!(value instanceof Integer)) {
516
                    throw new DynFieldValidateException(value, this);
517
                }
518
                break;
519

    
520
            case DataTypes.LONG:
521
                if (!(value instanceof Long)) {
522
                    throw new DynFieldValidateException(value, this);
523
                }
524
                break;
525

    
526
            case DataTypes.STRING:
527
                if (!(value instanceof String)) {
528
                    throw new DynFieldValidateException(value, this);
529
                }
530
                break;
531

    
532
            case DataTypes.CHAR:
533
                if (!(value instanceof String)) {
534
                    throw new DynFieldValidateException(value, this);
535
                }
536
                if (((String) value).length() > 1) {
537
                    throw new DynFieldValidateException(value, this);
538
                }
539
                break;
540

    
541
            case DataTypes.DATE:
542
                if (!(value instanceof Date)) {
543
                    throw new DynFieldValidateException(value, this);
544
                }
545
                break;
546

    
547
            case DataTypes.TIMESTAMP:
548
                if (!(value instanceof Date)) {
549
                    throw new DynFieldValidateException(value, this);
550
                }
551
                break;
552

    
553
            case DataTypes.TIME:
554
                if (!(value instanceof Date)) {
555
                    throw new DynFieldValidateException(value, this);
556
                }
557
                break;
558

    
559
            case DataTypes.FILE:
560
                if (!(value instanceof File)) {
561
                    throw new DynFieldValidateException(value, this);
562
                }
563
                break;
564
            case DataTypes.FOLDER:
565
                if (!(value instanceof File)) {
566
                    throw new DynFieldValidateException(value, this);
567
                }
568
                break;
569
            case DataTypes.URI:
570
                if (!(value instanceof URI)) {
571
                    throw new DynFieldValidateException(value, this);
572
                }
573
                break;
574
            case DataTypes.URL:
575
                if (!(value instanceof URL)) {
576
                    throw new DynFieldValidateException(value, this);
577
                }
578
                break;
579

    
580
            case DataTypes.ARRAY:
581
                // TODO: falta verificar que es un array del tipo que toca.
582
                break;
583

    
584
            case DataTypes.OBJECT:
585
                if (this.valueType.getClassOfValue() != null) {
586
                    if (!this.valueType.getClassOfValue().isInstance(value)) {
587
                        throw new DynFieldValidateException(value, this);
588
                    }
589
                }
590
                break;
591

    
592
            case DataTypes.MAP:
593
                if (!(value instanceof Map)) {
594
                    throw new DynFieldValidateException(value, this);
595
                }
596
                validateCollection(value);
597
                break;
598

    
599
            case DataTypes.SET:
600
                if (!(value instanceof Set)) {
601
                    throw new DynFieldValidateException(value, this);
602
                }
603
                validateCollection(value);
604
                break;
605

    
606
            case DataTypes.LIST:
607
                if (!(value instanceof List)) {
608
                    throw new DynFieldValidateException(value, this);
609
                }
610
                validateCollection(value);
611
                break;
612

    
613
            case DataTypes.DYNOBJECT:
614
                if (!(value instanceof DynObject)) {
615
                    throw new DynFieldValidateException(value, this);
616
                }
617
                if (!this.getDynClassOfValue().isInstance((DynObject) value)) {
618
                    throw new DynFieldValidateException(value, this);
619
                }
620
                try {
621
                    this.getDynClassOfValue().validate((DynObject) value);
622
                } catch (DynObjectValidateException e) {
623
                    throw new DynFieldValidateException(value, this, e);
624
                }
625
                break;
626

    
627
            default:
628
                if (this.valueType.getDataType().isObject()) {
629
                    if (this.valueType.getClassOfValue() != null) {
630
                        if (!this.valueType.getClassOfValue().isInstance(value)) {
631
                            throw new DynFieldValidateException(value, this);
632
                        }
633
                    }
634
                }
635
        }
636

    
637
        if (this.getAvailableValues() != null) {
638
            if (!(value instanceof Comparable)) {
639
                throw new DynFieldValidateException(value, this);
640
            }
641
            v = (Comparable) value;
642
            boolean ok = false;
643
            for (DynObjectValueItem availableValue : this.availableValues) {
644
                if (v.compareTo(availableValue.getValue()) == 0) {
645
                    ok = true;
646
                    break;
647
                }
648
            }
649
            if (!ok) {
650
                throw new DynFieldValidateException(value, this);
651
            }
652
        } else if (this.getMaxValue() != null && this.getMinValue() != null) {
653
            if (!(value instanceof Comparable)) {
654
                throw new DynFieldValidateException(value, this);
655
            }
656
            v = (Comparable) value;
657
            if (v.compareTo(this.minValue) < 0
658
                    || v.compareTo(this.maxValue) > 0) {
659
                throw new DynFieldValidateException(value, this);
660
            }
661
        }
662
    }
663

    
664
    private void validateCollection(Object value) throws ValidateItemException {
665
        if (this.validateItems) {
666
            DynStruct dynClass = this.itemsType.getDynClassOfValue();
667
            if (dynClass != null) {
668
                int index = 0;
669
                Iterator it = ((Collection) value).iterator();
670
                while (it.hasNext()) {
671
                    try {
672
                        dynClass.validate((DynObject) it.next());
673
                        index++;
674
                    } catch (DynObjectValidateException ex) {
675
                        throw new ValidateItemException(ex, index);
676
                    }
677
                }
678
            }
679
        }
680

    
681
    }
682

    
683
    private static class ValidateItemException extends DynFieldValidateException {
684

    
685
        private static final long serialVersionUID = 9011437364983996567L;
686

    
687
        ValidateItemException(Throwable cause, int index) {
688
            super(
689
                    "Can't validate item %(index) of the collection.",
690
                    cause,
691
                    "_Cant_validate_item_%(index)_of_the_collection",
692
                    serialVersionUID
693
            );
694
            setValue("index", index);
695
        }
696
    }
697

    
698
    @Override
699
    public Object coerce(Object value) throws CoercionException {
700
        if (value == null) {
701
            return value; // O debe devolver this.defaultValue
702
        }
703
        try {
704
            return this.valueType.getDataType().coerce(value);
705
        } catch (Exception ex) {
706
            throw new RuntimeException(ex);
707
        }
708
    }
709

    
710
    @Override
711
    public String getGroup() {
712
        return this.groupName;
713
    }
714

    
715
    @Override
716
    public DynField setGroup(String groupName) {
717
        this.groupName = groupName;
718
        return this;
719
    }
720

    
721
    @Override
722
    public int getOder() {
723
        return this.order;
724
    }
725

    
726
    @Override
727
    public DynField setOrder(int order) {
728
        this.order = order;
729
        return this;
730
    }
731

    
732
    @Override
733
    public boolean isHidden() {
734
        return this.hidden;
735
    }
736

    
737
    @Override
738
    public DynField setHidden(boolean hidden) {
739
        this.hidden = hidden;
740
        return this;
741
    }
742

    
743
    @Override
744
    public boolean isReadOnly() {
745
        return this.isReadOnly;
746
    }
747

    
748
    @Override
749
    public DynField setReadOnly(boolean isReadOnly) {
750
        this.isReadOnly = isReadOnly;
751
        return this;
752
    }
753

    
754
    @Override
755
    public DynField setDefaultFieldValue(Object defaultValue) {
756
        try {
757
            this.defaultValue = this.coerce(defaultValue);
758
        } catch (CoercionException e) {
759
            throw new IllegalArgumentException(e);
760
        }
761
        return this;
762
    }
763

    
764
    @Override
765
    public Tags getTags() {
766
        return tags;
767
    }
768

    
769
    @Override
770
    public String getClassNameOfValue() {
771
        return this.valueType.getClassNameOfValue();
772
    }
773

    
774
    @Override
775
    public DynField setClassOfValue(DynStruct dynStruct) {
776
        this.valueType.setClassOfValue(dynStruct);
777
        return this;
778
    }
779

    
780
    @Override
781
    public DynStruct getDynClassOfValue() {
782
        return this.valueType.getDynClassOfValue();
783
    }
784

    
785
    @Override
786
    public int getRelationType() {
787
        return this.relationType;
788
    }
789

    
790
    @Override
791
    public DynField setRelationType(int relationType) {
792
        this.relationType = relationType;
793
        return this;
794
    }
795

    
796
    @Override
797
    public DynField setElementsType(int type) {
798
        this.setTypeOfItems(type);
799
        return this;
800
    }
801

    
802
    @Override
803
    public DynField setElementsType(DynStruct type) {
804
        this.setClassOfItems(type);
805
        return this;
806
    }
807

    
808
    @Override
809
    public DynField getElementsType() {
810
        throw new UnsupportedOperationException("This operation is not suported nevermore.");
811
    }
812

    
813
    @Override
814
    public DynField setClassOfItems(DynStruct dynStrct) {
815
        if (dynStrct!=null && !this.isContainer()) {
816
            throw new IllegalStateException("Can't assign classOfItems in non container.");
817
        }
818
        this.itemsType.setClassOfValue(dynStrct);
819
        return this;
820
    }
821

    
822
    @Override
823
    public DynField setClassOfItems(String theClassNameOfValue) {
824
        if (theClassNameOfValue!=null && !this.isContainer()) {
825
            throw new IllegalStateException("Can't assign classOfItems in non container.");
826
        }
827
        this.itemsType.setClassOfValue(theClassNameOfValue);
828
        return this;
829
    }
830

    
831
    @Override
832
    public String getClassNameOfItems() {
833
        if( this.itemsType==null || 
834
                this.itemsType.getClassNameOfValue()==null ) {
835
            return null;
836
        }
837
        if (!this.isContainer()) {
838
            throw new IllegalStateException("Can't get classNameOfItems in non container.");
839
        }
840
        return this.itemsType.getClassNameOfValue();
841
    }
842

    
843
    @Override
844
    public DynStruct getDynClassOfItems() {
845
        if( this.itemsType==null || 
846
                this.itemsType.getDynClassOfValue()==null ) {
847
            return null;
848
        }
849
        if (!this.isContainer()) {
850
            throw new IllegalStateException("Can't get dynClassOfItems in non container.");
851
        }
852
        return this.itemsType.getDynClassOfValue();
853
    }
854

    
855
    @Override
856
    public DynField setClassOfItems(Class theClass)
857
            throws DynFieldIsNotAContainerException {
858
        if (theClass!=null && !this.isContainer()) {
859
            throw new IllegalStateException("Can't assign classNameOfItems in non container.");
860
        }
861
        this.itemsType.setClassOfValue(theClass);
862
        return this;
863
    }
864

    
865
    @Override
866
    public Class getClassOfItems() {
867
        if( this.itemsType==null || 
868
                this.itemsType.getClassOfValue()==null ) {
869
            return null;
870
        }
871
        if (!this.isContainer()) {
872
            throw new IllegalStateException("Can't get classOfItems in non container.");
873
        }
874
        return this.itemsType.getClassOfValue();
875
    }
876

    
877
    @Override
878
    public DynField setTypeOfItems(int type) {
879
        if (!this.isContainer()) {
880
            throw new IllegalStateException("Can't assign typeOfItems in non container.");
881
        }
882
        this.itemsType.setType(type);
883
        return this;
884
    }
885

    
886
    @Override
887
    public int getTypeOfItems() {
888
        if (!this.isContainer()) {
889
            throw new IllegalStateException("Can't get typeOfItems in non container.");
890
        }
891
        return this.itemsType.getType();
892
    }
893

    
894
    @Override
895
    public DynField setValidateElements(boolean validate) {
896
        if (!this.isContainer()) {
897
            throw new IllegalStateException("Can't assign validateElements in non container.");
898
        }
899
        this.validateItems = validate;
900
        return this;
901
    }
902

    
903
    @Override
904
    public boolean getValidateElements() {
905
        if (!this.isContainer()) {
906
            throw new IllegalStateException("Can't get validateElements in non container.");
907
        }
908
        return this.validateItems;
909
    }
910

    
911
    @Override
912
    public Object clone() throws CloneNotSupportedException {
913
        DefaultDynField other = (DefaultDynField) super.clone();
914
        other.tags = (Tags) this.tags.clone();
915
        other.valueType = (ValueType) this.valueType.clone();
916
        other.itemsType = (ValueType) this.itemsType.clone();
917
        if( this.availableValues==null ) {
918
            other.availableValues = null;
919
        } else {
920
            other.availableValues = this.availableValues.clone();
921
        }
922
        other.calculate = (DynMethod) this.calculate;
923
        return other;
924
    }
925

    
926
}