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

History | View | Annotate | Download (28.3 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.gvsig.tools.i18n.I18nManager;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

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

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

    
63
    private String name;
64
    private String description;
65

    
66
    private ValueType valueType;
67

    
68
    private String subtype;
69

    
70
    private Object defaultValue;
71

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

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

    
85
    private boolean isReadOnly;
86
    private Tags tags = new DefaultTags();
87

    
88
    private ValueType itemsType;
89
    private boolean validateItems;
90

    
91
    private int relationType;
92
    private DynMethod calculate = null;
93

    
94
    public DefaultDynField(String name, int dataType) {
95
        this(name, // field name
96
                dataType, // data type
97
                null, // default value
98
                true, // persistent
99
                false // mandatory
100
        );
101
    }
102

    
103
    @SuppressWarnings("OverridableMethodCallInConstructor")
104
    protected DefaultDynField(String name, int dataType, Object defaultValue,
105
            boolean persistent, boolean mandatory) {
106
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
107

    
108
        if (StringUtils.isBlank(name)) {
109
            throw new IllegalArgumentException("name can't be null");
110
        }
111
        this.name = name;
112
        this.valueType = new ValueType(dataType);
113
        this.subtype = this.getSubtype();
114

    
115
        this.defaultValue = defaultValue;
116
        this.persistent = persistent;
117
        this.mandatory = mandatory;
118
        this.groupName = null;
119
        this.order = 0;
120
        this.hidden = false;
121
        this.availableValues = null;
122

    
123
        this.itemsType = new ValueType(DataTypes.UNKNOWN);
124
        this.validateItems = false;
125
        this.relationType = RELATION_TYPE_NONE;
126
    }
127

    
128
    @Override
129
    public void copyFrom(DynField other) {
130
        try {
131
            this.name = other.getName();
132
            this.description = other.getDescription();
133
            this.subtype = other.getSubtype();
134
            this.defaultValue = other.getDefaultValue();
135
            this.order = other.getOder();
136
            this.hidden = other.isHidden();
137
            this.groupName = other.getGroup();
138
            this.minValue = other.getMinValue();
139
            this.maxValue = other.getMaxValue();
140
            this.mandatory = other.isMandatory();
141
            this.persistent = other.isMandatory();
142
            this.isReadOnly = other.isReadOnly();
143
            this.tags = new DefaultTags();
144

    
145
            if (other instanceof DynField_v2) {
146
                DynField_v2 other2 = (DynField_v2) other;
147
                this.tags.add(other2.getTags());
148
                this.label = other2.getLabel();
149
                this.validateItems = other2.getValidateElements();
150

    
151
                if (other2.isCalculated()) {
152
                    this.setCalculateMethod(other2.getCalculateMethod());
153
                }
154

    
155
                if( other2.isAvailableValuesCalculated() ) {
156
                    this.availableValuesMethod = other2.getAvailableValuesMethod();
157
                } else {
158
                    DynObjectValueItem[] x = other.getAvailableValues();
159
                    if( x != null ) {
160
                    this.availableValues = x.clone();
161
                    }
162
                }
163

    
164
                this.setType(other.getDataType());
165
                this.setClassOfValue(other2.getClassOfValue());
166
                this.setClassOfValue(other2.getDynClassOfValue());
167

    
168
                this.itemsType.setType(other2.getTypeOfItems());
169
                this.itemsType.setClassOfValue(other2.getClassOfItems());
170
                this.itemsType.setClassOfValue(other2.getDynClassOfItems());
171
            }
172
        } catch(Exception ex) {
173
            log.warn("Can't copy dynfield from '"+other.getName()+"'.", ex);
174
            throw ex;
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 StringUtils.isBlank(label) ? getName() : label;
262
    }
263

    
264
    @Override
265
    public String getLocalizedLabel() {
266
        if( StringUtils.isBlank(this.label) ) {
267
            return this.getName();
268
        }
269
        I18nManager i18n = ToolsLocator.getI18nManager();
270
        return i18n.getTranslation(this.label);
271
    }
272

    
273
    @Override
274
    public DynField setShortLabel(String shortLabel) {
275
        this.shortLabel = shortLabel;
276
        return this;
277
    }
278

    
279
    @Override
280
    public String getShortLabel() {
281
        return StringUtils.isBlank(shortLabel) ? getLabel() : shortLabel;
282
    }
283

    
284
    @Override
285
    public String getLocalizedShortLabel() {
286
        if( StringUtils.isBlank(shortLabel) ) {
287
            return this.getLocalizedLabel();
288
        }
289
        I18nManager i18n = ToolsLocator.getI18nManager();
290
        return i18n.getTranslation(shortLabel);
291
    }
292

    
293
    @Override
294
    public DynField setType(int dataType) {
295
        this.valueType.setType(dataType);
296
        return this;
297
    }
298

    
299
    @Override
300
    public DynField setType(DataType dataType) {
301
        this.valueType.setType(dataType);
302
        return this;
303
    }
304

    
305
    @Override
306
    public int getType() {
307
        return this.valueType.getType();
308
    }
309

    
310
    @Override
311
    public DataType getDataType() {
312
        return this.valueType.getDataType();
313
    }
314

    
315
    @Override
316
    public DynField setSubtype(String subtype) {
317
        this.subtype = subtype;
318
        return this;
319
    }
320

    
321
    @Override
322
    public String getSubtype() {
323
        return subtype;
324
    }
325

    
326
    @Override
327
    public DynField setDefaultDynValue(Object defaultValue) {
328
        this.defaultValue = defaultValue;
329
        return this;
330
    }
331

    
332
    @Override
333
    public Object getDefaultValue() {
334
        return defaultValue;
335
    }
336

    
337
    @Override
338
    public boolean isAvailableValuesCalculated() {
339
        return this.availableValuesMethod != null;
340
    }
341

    
342
    @Override
343
    public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
344
        if (availableValues == null || availableValues.length == 0) {
345
            this.availableValues = null;
346
        } else {
347
            this.availableValues = availableValues;
348
        }
349
        return this;
350
    }
351

    
352
    @Override
353
    public DynField setAvailableValues(List availableValues) {
354
        if (availableValues == null) {
355
            this.availableValues = null;
356
        } else if (availableValues.isEmpty()) {
357
            this.availableValues = null;
358
        } else {
359
            this.availableValues = (DynObjectValueItem[]) availableValues
360
                    .toArray(new DynObjectValueItem[availableValues.size()]);
361
        }
362
        return this;
363
    }
364

    
365
    @Override
366
    public DynField setAvailableValues(DynMethod computeAvailableValues) {
367
        this.availableValuesMethod = computeAvailableValues;
368
        return this;
369
    }
370

    
371
    @Override
372
    public DynMethod getAvailableValuesMethod() {
373
        return this.availableValuesMethod;
374
    }
375

    
376
    
377
    @Override
378
    public DynObjectValueItem[] getAvailableValues() {
379
        return this.getAvailableValues(null);
380
    }
381

    
382
    @Override
383
    public DynObjectValueItem[] getAvailableValues(DynObject self) {
384
        if (this.availableValuesMethod != null) {
385
            DynObjectValueItem[] values;
386
            try {
387
                values = (DynObjectValueItem[]) this.availableValuesMethod.invoke(self, new Object[]{this});
388
            } catch (DynMethodException ex) {
389
                return this.availableValues;
390
            }
391
            if (values != null) {
392
                return values;
393
            }
394
        }
395
        return this.availableValues;
396
    }
397

    
398
    @Override
399
    public DynField setMinValue(Object minValue) {
400
        try {
401
            this.minValue = this.coerce(minValue);
402
        } catch (CoercionException e) {
403
            throw new IllegalArgumentException();
404
        }
405
        return this;
406
    }
407

    
408
    @Override
409
    public Object getMinValue() {
410
        return minValue;
411
    }
412

    
413
    @Override
414
    public DynField setMaxValue(Object maxValue) {
415
        try {
416
            this.maxValue = this.coerce(maxValue);
417
        } catch (CoercionException e) {
418
            throw new IllegalArgumentException(e);
419
        }
420
        return this;
421
    }
422

    
423
    @Override
424
    public Object getMaxValue() {
425
        return maxValue;
426
    }
427

    
428
    @Override
429
    public boolean isMandatory() {
430
        return this.mandatory;
431
    }
432

    
433
    @Override
434
    public boolean isPersistent() {
435
        if (this.isCalculated()) {
436
            return false;
437
        }
438
        return this.persistent;
439
    }
440

    
441
    @Override
442
    public DynField setMandatory(boolean mandatory) {
443
        this.mandatory = mandatory;
444
        return this;
445
    }
446

    
447
    @Override
448
    public DynField setPersistent(boolean persistent) {
449
        if (this.isCalculated()) {
450
            persistent = false;
451
        }
452
        this.persistent = persistent;
453
        return this;
454
    }
455

    
456
    @Override
457
    public DynField setTheTypeOfAvailableValues(int type) {
458
        return this; // FIXME: this method is @deprecated
459
    }
460

    
461
    @Override
462
    public int getTheTypeOfAvailableValues() {
463
        return 1; // FIXME: this method is @deprecated
464
    }
465

    
466
    /**
467
     *
468
     * @param obj
469
     * @return
470
     */
471
    @Override
472
    public boolean equals(Object obj) {
473
        if (this == obj) {
474
            return true;
475
        }
476
        if (obj instanceof DynField) {
477
            // FIXME: No esta claro que esto sea correcto.
478
            return name.equals(((DynField) obj).getName());
479
        }
480
        return false;
481
    }
482

    
483
    @Override
484
    public Class getClassOfValue() {
485
        return this.valueType.getClassOfValue();
486
    }
487

    
488
    @Override
489
    public DynField setClassOfValue(Class theClass) {
490
        this.valueType.setClassOfValue(theClass);
491
        return this;
492
    }
493

    
494
    @Override
495
    public DynField setClassOfValue(String theClassName) {
496
        this.valueType.setClassOfValue(theClassName);
497
        return this;
498
    }
499

    
500
    @Override
501
    public boolean isContainer() {
502
        if (valueType.getDataType() == null) {
503
            return false;
504
        }
505
        return valueType.getDataType().isContainer();
506
    }
507

    
508
    @Override
509
    public void validate(Object value) throws DynFieldValidateException {
510
        Comparable v;
511
        if (value == null) {
512
            if (this.mandatory) {
513
                throw new DynFieldRequiredValueException(this, value);
514
            }
515
            return;
516
        }
517

    
518
        switch (this.valueType.getType()) {
519
            case DataTypes.BOOLEAN:
520
                if (!(value instanceof Boolean)) {
521
                    throw new DynFieldValidateException(value, this);
522
                }
523
                break;
524

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

    
531
            case DataTypes.FLOAT:
532
                if (!(value instanceof Float)) {
533
                    throw new DynFieldValidateException(value, this);
534
                }
535
                break;
536

    
537
            case DataTypes.BYTE:
538
                if (!(value instanceof Byte)) {
539
                    throw new DynFieldValidateException(value, this);
540
                }
541
                break;
542

    
543
            case DataTypes.INT:
544
                if (!(value instanceof Integer)) {
545
                    throw new DynFieldValidateException(value, this);
546
                }
547
                break;
548

    
549
            case DataTypes.LONG:
550
                if (!(value instanceof Long)) {
551
                    throw new DynFieldValidateException(value, this);
552
                }
553
                break;
554

    
555
            case DataTypes.STRING:
556
                if (!(value instanceof String)) {
557
                    throw new DynFieldValidateException(value, this);
558
                }
559
                break;
560

    
561
            case DataTypes.CHAR:
562
                if (!(value instanceof String)) {
563
                    throw new DynFieldValidateException(value, this);
564
                }
565
                if (((String) value).length() > 1) {
566
                    throw new DynFieldValidateException(value, this);
567
                }
568
                break;
569

    
570
            case DataTypes.DATE:
571
                if (!(value instanceof Date)) {
572
                    throw new DynFieldValidateException(value, this);
573
                }
574
                break;
575

    
576
            case DataTypes.TIMESTAMP:
577
                if (!(value instanceof Date)) {
578
                    throw new DynFieldValidateException(value, this);
579
                }
580
                break;
581

    
582
            case DataTypes.TIME:
583
                if (!(value instanceof Date)) {
584
                    throw new DynFieldValidateException(value, this);
585
                }
586
                break;
587

    
588
            case DataTypes.FILE:
589
                if (!(value instanceof File)) {
590
                    throw new DynFieldValidateException(value, this);
591
                }
592
                break;
593
            case DataTypes.FOLDER:
594
                if (!(value instanceof File)) {
595
                    throw new DynFieldValidateException(value, this);
596
                }
597
                break;
598
            case DataTypes.URI:
599
                if (!(value instanceof URI)) {
600
                    throw new DynFieldValidateException(value, this);
601
                }
602
                break;
603
            case DataTypes.URL:
604
                if (!(value instanceof URL)) {
605
                    throw new DynFieldValidateException(value, this);
606
                }
607
                break;
608

    
609
            case DataTypes.ARRAY:
610
                // TODO: falta verificar que es un array del tipo que toca.
611
                break;
612

    
613
            case DataTypes.OBJECT:
614
                if (this.valueType.getClassOfValue() != null) {
615
                    if (!this.valueType.getClassOfValue().isInstance(value)) {
616
                        throw new DynFieldValidateException(value, this);
617
                    }
618
                }
619
                break;
620

    
621
            case DataTypes.MAP:
622
                if (!(value instanceof Map)) {
623
                    throw new DynFieldValidateException(value, this);
624
                }
625
                validateCollection(value);
626
                break;
627

    
628
            case DataTypes.SET:
629
                if (!(value instanceof Set)) {
630
                    throw new DynFieldValidateException(value, this);
631
                }
632
                validateCollection(value);
633
                break;
634

    
635
            case DataTypes.LIST:
636
                if (!(value instanceof List)) {
637
                    throw new DynFieldValidateException(value, this);
638
                }
639
                validateCollection(value);
640
                break;
641

    
642
            case DataTypes.DYNOBJECT:
643
                if (!(value instanceof DynObject)) {
644
                    throw new DynFieldValidateException(value, this);
645
                }
646
                if (!this.getDynClassOfValue().isInstance((DynObject) value)) {
647
                    throw new DynFieldValidateException(value, this);
648
                }
649
                try {
650
                    this.getDynClassOfValue().validate((DynObject) value);
651
                } catch (DynObjectValidateException e) {
652
                    throw new DynFieldValidateException(value, this, e);
653
                }
654
                break;
655

    
656
            default:
657
                if (this.valueType.getDataType().isObject()) {
658
                    if (this.valueType.getClassOfValue() != null) {
659
                        if (!this.valueType.getClassOfValue().isInstance(value)) {
660
                            throw new DynFieldValidateException(value, this);
661
                        }
662
                    }
663
                }
664
        }
665

    
666
        if (this.getAvailableValues() != null) {
667
            if (!(value instanceof Comparable)) {
668
                throw new DynFieldValidateException(value, this);
669
            }
670
            v = (Comparable) value;
671
            boolean ok = false;
672
            for (DynObjectValueItem availableValue : this.availableValues) {
673
                if (v.compareTo(availableValue.getValue()) == 0) {
674
                    ok = true;
675
                    break;
676
                }
677
            }
678
            if (!ok) {
679
                throw new DynFieldValidateException(value, this);
680
            }
681
        } else if (this.getMaxValue() != null && this.getMinValue() != null) {
682
            if (!(value instanceof Comparable)) {
683
                throw new DynFieldValidateException(value, this);
684
            }
685
            v = (Comparable) value;
686
            if (v.compareTo(this.minValue) < 0
687
                    || v.compareTo(this.maxValue) > 0) {
688
                throw new DynFieldValidateException(value, this);
689
            }
690
        }
691
    }
692

    
693
    private void validateCollection(Object value) throws ValidateItemException {
694
        if (this.validateItems) {
695
            DynStruct dynClass = this.itemsType.getDynClassOfValue();
696
            if (dynClass != null) {
697
                int index = 0;
698
                Iterator it = ((Collection) value).iterator();
699
                while (it.hasNext()) {
700
                    try {
701
                        dynClass.validate((DynObject) it.next());
702
                        index++;
703
                    } catch (DynObjectValidateException ex) {
704
                        throw new ValidateItemException(ex, index);
705
                    }
706
                }
707
            }
708
        }
709

    
710
    }
711

    
712
    private static class ValidateItemException extends DynFieldValidateException {
713

    
714
        private static final long serialVersionUID = 9011437364983996567L;
715

    
716
        ValidateItemException(Throwable cause, int index) {
717
            super(
718
                    "Can't validate item %(index) of the collection.",
719
                    cause,
720
                    "_Cant_validate_item_%(index)_of_the_collection",
721
                    serialVersionUID
722
            );
723
            setValue("index", index);
724
        }
725
    }
726

    
727
    @Override
728
    public Object coerce(Object value) throws CoercionException {
729
        if (value == null) {
730
            return value; // O debe devolver this.defaultValue
731
        }
732
        try {
733
            return this.valueType.getDataType().coerce(value);
734
        } catch (Exception ex) {
735
            throw new RuntimeException(ex);
736
        }
737
    }
738

    
739
    @Override
740
    public String getGroup() {
741
        return this.groupName;
742
    }
743

    
744
    @Override
745
    public DynField setGroup(String groupName) {
746
        this.groupName = groupName;
747
        return this;
748
    }
749

    
750
    @Override
751
    public int getOder() {
752
        return this.order;
753
    }
754

    
755
    @Override
756
    public DynField setOrder(int order) {
757
        this.order = order;
758
        return this;
759
    }
760

    
761
    @Override
762
    public boolean isHidden() {
763
        return this.hidden;
764
    }
765

    
766
    @Override
767
    public DynField setHidden(boolean hidden) {
768
        this.hidden = hidden;
769
        return this;
770
    }
771

    
772
    @Override
773
    public boolean isReadOnly() {
774
        return this.isReadOnly;
775
    }
776

    
777
    @Override
778
    public DynField setReadOnly(boolean isReadOnly) {
779
        this.isReadOnly = isReadOnly;
780
        return this;
781
    }
782

    
783
    @Override
784
    public DynField setDefaultFieldValue(Object defaultValue) {
785
        try {
786
            this.defaultValue = this.coerce(defaultValue);
787
        } catch (CoercionException e) {
788
            throw new IllegalArgumentException(e);
789
        }
790
        return this;
791
    }
792

    
793
    @Override
794
    public Tags getTags() {
795
        return tags;
796
    }
797

    
798
    @Override
799
    public String getClassNameOfValue() {
800
        return this.valueType.getClassNameOfValue();
801
    }
802

    
803
    @Override
804
    public DynField setClassOfValue(DynStruct dynStruct) {
805
        this.valueType.setClassOfValue(dynStruct);
806
        return this;
807
    }
808

    
809
    @Override
810
    public DynStruct getDynClassOfValue() {
811
        return this.valueType.getDynClassOfValue();
812
    }
813

    
814
    @Override
815
    public int getRelationType() {
816
        return this.relationType;
817
    }
818

    
819
    @Override
820
    public DynField setRelationType(int relationType) {
821
        this.relationType = relationType;
822
        return this;
823
    }
824

    
825
    @Override
826
    public DynField setElementsType(int type) {
827
        this.setTypeOfItems(type);
828
        return this;
829
    }
830

    
831
    @Override
832
    public DynField setElementsType(DynStruct type) {
833
        this.setClassOfItems(type);
834
        return this;
835
    }
836

    
837
    @Override
838
    public DynField getElementsType() {
839
        throw new UnsupportedOperationException("This operation is not suported nevermore.");
840
    }
841

    
842
    @Override
843
    public DynField setClassOfItems(DynStruct dynStrct) {
844
        if (dynStrct!=null && !this.isContainer()) {
845
            throw new IllegalStateException("Can't assign classOfItems in non container.");
846
        }
847
        this.itemsType.setClassOfValue(dynStrct);
848
        return this;
849
    }
850

    
851
    @Override
852
    public DynField setClassOfItems(String theClassNameOfValue) {
853
        if (theClassNameOfValue!=null && !this.isContainer()) {
854
            throw new IllegalStateException("Can't assign classOfItems in non container.");
855
        }
856
        this.itemsType.setClassOfValue(theClassNameOfValue);
857
        return this;
858
    }
859

    
860
    @Override
861
    public String getClassNameOfItems() {
862
        if( this.itemsType==null || 
863
                this.itemsType.getClassNameOfValue()==null ) {
864
            return null;
865
        }
866
        if (!this.isContainer()) {
867
            throw new IllegalStateException("Can't get classNameOfItems in non container.");
868
        }
869
        return this.itemsType.getClassNameOfValue();
870
    }
871

    
872
    @Override
873
    public DynStruct getDynClassOfItems() {
874
        if( this.itemsType==null || 
875
                this.itemsType.getDynClassOfValue()==null ) {
876
            return null;
877
        }
878
        if (!this.isContainer()) {
879
            throw new IllegalStateException("Can't get dynClassOfItems in non container.");
880
        }
881
        return this.itemsType.getDynClassOfValue();
882
    }
883

    
884
    @Override
885
    public DynField setClassOfItems(Class theClass)
886
            throws DynFieldIsNotAContainerException {
887
        if (theClass!=null && !this.isContainer()) {
888
            throw new IllegalStateException("Can't assign classNameOfItems in non container.");
889
        }
890
        this.itemsType.setClassOfValue(theClass);
891
        return this;
892
    }
893

    
894
    @Override
895
    public Class getClassOfItems() {
896
        if( this.itemsType==null || 
897
                this.itemsType.getClassOfValue()==null ) {
898
            return null;
899
        }
900
        if (!this.isContainer()) {
901
            throw new IllegalStateException("Can't get classOfItems in non container.");
902
        }
903
        return this.itemsType.getClassOfValue();
904
    }
905

    
906
    @Override
907
    public DynField setTypeOfItems(int type) {
908
        if (!this.isContainer()) {
909
            throw new IllegalStateException("Can't assign typeOfItems in non container.");
910
        }
911
        this.itemsType.setType(type);
912
        return this;
913
    }
914

    
915
    @Override
916
    public int getTypeOfItems() {
917
        if (!this.isContainer()) {
918
            throw new IllegalStateException("Can't get typeOfItems in non container.");
919
        }
920
        return this.itemsType.getType();
921
    }
922

    
923
    @Override
924
    public DynField setValidateElements(boolean validate) {
925
        if (!this.isContainer()) {
926
            throw new IllegalStateException("Can't assign validateElements in non container.");
927
        }
928
        this.validateItems = validate;
929
        return this;
930
    }
931

    
932
    @Override
933
    public boolean getValidateElements() {
934
        if (!this.isContainer()) {
935
            throw new IllegalStateException("Can't get validateElements in non container.");
936
        }
937
        return this.validateItems;
938
    }
939

    
940
    @Override
941
    public Object clone() throws CloneNotSupportedException {
942
        DefaultDynField other = (DefaultDynField) super.clone();
943
        other.tags = (Tags) this.tags.clone();
944
        other.valueType = (ValueType) this.valueType.clone();
945
        other.itemsType = (ValueType) this.itemsType.clone();
946
        if( this.availableValues==null ) {
947
            other.availableValues = null;
948
        } else {
949
            other.availableValues = this.availableValues.clone();
950
        }
951
        other.calculate = (DynMethod) this.calculate;
952
        return other;
953
    }
954

    
955
}