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

History | View | Annotate | Download (21.9 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 2
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.tools.dynobject.impl;
25

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

    
37
import org.gvsig.tools.ToolsLocator;
38
import org.gvsig.tools.dataTypes.CoercionException;
39
import org.gvsig.tools.dataTypes.DataType;
40
import org.gvsig.tools.dataTypes.DataTypes;
41
import org.gvsig.tools.dataTypes.DataTypesManager;
42
import org.gvsig.tools.dynobject.DynClass;
43
import org.gvsig.tools.dynobject.DynField;
44
import org.gvsig.tools.dynobject.DynField_v2;
45
import org.gvsig.tools.dynobject.DynObject;
46
import org.gvsig.tools.dynobject.DynObjectValueItem;
47
import org.gvsig.tools.dynobject.DynStruct;
48
import org.gvsig.tools.dynobject.Tags;
49
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
50
import org.gvsig.tools.dynobject.exception.DynFieldRequiredValueException;
51
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
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
public class DefaultDynField implements DynField_v2 {
58

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

    
61
    private String name;
62
    private String description;
63

    
64
    private ValueType type;
65

    
66
    private String subtype;
67

    
68
    private Object defaultValue;
69

    
70
    private int order;
71
    private boolean hidden;
72
    private String groupName;
73
    private DynObjectValueItem[] availableValues;
74
    private Object minValue;
75
    private Object maxValue;
76
    private boolean mandatory;
77
    private boolean persistent;
78
    private String label = null;
79

    
80
    private boolean validateElements;
81
    private boolean isReadOnly;
82
    private Tags tags = new DefaultTags();
83

    
84
    private ValueType itemsType;
85
    private boolean validateItems;
86

    
87
//        Para implementacion futura, como minimo para implementar
88
//        un copy entre dynobject y saber cuando parar.
89
//        Los valores deberan ser algo asi como:
90
//        - Composicion, 1:1 o 1:N y se copian.
91
//        - Agregacion, 1:N, no se copian
92
//        - Colaboracion, 1:1, no se copian
93
//        Y solo tendra efecto/sentido cuando el field sea de tipo
94
//        DynObject, y tal vez lista de DynObject
95
    private int relationType;
96

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

    
106
    protected DefaultDynField(String name, int dataType, Object defaultValue,
107
            boolean persistent, boolean mandatory) {
108
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
109

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

    
117
        this.defaultValue = defaultValue;
118
        this.persistent = persistent;
119
        this.mandatory = mandatory;
120
        this.validateElements = false;
121
        this.groupName = null;
122
        this.order = 0;
123
        this.hidden = false;
124
        this.availableValues = null;
125

    
126
        this.itemsType = new ValueType(DataTypes.UNKNOWN);
127
        this.validateItems = false;
128
    }
129

    
130
    protected ValueType getValueType() {
131
        return type;
132
    }
133

    
134
    public void check() throws ListBaseException {
135
    }
136

    
137
    public String toString() {
138
        StringBuffer buffer = new StringBuffer();
139

    
140
        buffer.append("DynField").append("[").append(this.hashCode())
141
                .append("]").append("( ").append("name='").append(this.name)
142
                .append("', ").append("description='").append(this.description)
143
                .append("', ").append("type='").append(this.type)
144
                .append("', ").append("subType='").append(this.subtype)
145
                .append("', ").append("mandatory='").append(this.isMandatory())
146
                .append("', ").append("defaultValue='")
147
                .append(this.getDefaultValue()).append("', ")
148
                .append("minValue='").append(this.minValue).append("', ")
149
                .append("maxValue='").append(this.maxValue).append("', ")
150
                .append("persistent='").append(this.isPersistent())
151
                .append(" )");
152
        return buffer.toString();
153
    }
154

    
155
    public String getName() {
156
        return name;
157
    }
158

    
159
    public DynField setName(String name) {
160
        if ( StringUtils.isBlank(name) ) {
161
            throw new IllegalArgumentException("name can't be null");
162
        }
163
        this.name = name;
164
        return this;
165
    }
166

    
167
    public DynField setDescription(String description) {
168
        this.description = description;
169
        return this;
170
    }
171

    
172
    public String getDescription() {
173
        return (description == null) ? getLabel() : description;
174
    }
175

    
176
    public DynField setLabel(String label) {
177
        this.label = label;
178
        return this;
179
    }
180

    
181
    public String getLabel() {
182
        return (label == null) ? getName() : label;
183
    }
184

    
185
    public DynField setType(int dataType) {
186
        this.type.setType(dataType);
187
        return this;
188
    }
189

    
190
    public DynField setType(DataType dataType) {
191
        this.type.setType(dataType);
192
        return this;
193
    }
194

    
195
    public int getType() {
196
        return this.type.getType();
197
    }
198

    
199
    public DataType getDataType() {
200
        return this.type.getDataType();
201
    }
202

    
203
    public DynField setSubtype(String subtype) {
204
        this.subtype = subtype;
205
        return this;
206
    }
207

    
208
    public String getSubtype() {
209
        return subtype;
210
    }
211

    
212
    public DynField setDefaultDynValue(Object defaultValue) {
213
        this.defaultValue = defaultValue;
214
        return this;
215
    }
216

    
217
    public Object getDefaultValue() {
218
        return defaultValue;
219
    }
220

    
221
    public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
222
        if ( availableValues == null || availableValues.length == 0 ) {
223
            this.availableValues = null;
224
        } else {
225
            this.availableValues = availableValues;
226
        }
227
        return this;
228
    }
229

    
230
    public DynField setAvailableValues(List availableValues) {
231
        if ( availableValues == null ) {
232
            this.availableValues = null;
233
        } else if ( availableValues.isEmpty() ) {
234
            this.availableValues = null;
235
        } else {
236
            this.availableValues = (DynObjectValueItem[]) availableValues
237
                    .toArray(new DynObjectValueItem[availableValues.size()]);
238
        }
239
        return this;
240
    }
241

    
242
    public DynObjectValueItem[] getAvailableValues() {
243
        return availableValues;
244
    }
245

    
246
    public DynField setMinValue(Object minValue) {
247
        try {
248
            this.minValue = this.coerce(minValue);
249
        } catch (CoercionException e) {
250
            IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
251
            ex.initCause(e);
252
            throw ex;
253
        }
254
        return this;
255
    }
256

    
257
    public Object getMinValue() {
258
        return minValue;
259
    }
260

    
261
    public DynField setMaxValue(Object maxValue) {
262
        try {
263
            this.maxValue = this.coerce(maxValue);
264
        } catch (CoercionException e) {
265
            IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
266
            ex.initCause(e);
267
            throw ex;
268
        }
269
        return this;
270
    }
271

    
272
    public Object getMaxValue() {
273
        return maxValue;
274
    }
275

    
276
    public boolean isMandatory() {
277
        return this.mandatory;
278
    }
279

    
280
    public boolean isPersistent() {
281
        return this.persistent;
282
    }
283

    
284
    public DynField setMandatory(boolean mandatory) {
285
        this.mandatory = mandatory;
286
        return this;
287
    }
288

    
289
    public DynField setPersistent(boolean persistent) {
290
        this.persistent = persistent;
291
        return this;
292
    }
293

    
294
    public DynField setTheTypeOfAvailableValues(int type) {
295
        return this; // FIXME: this method is @deprecated
296
    }
297

    
298
    public int getTheTypeOfAvailableValues() {
299
        return 1; // FIXME: this method is @deprecated
300
    }
301

    
302
    public boolean equals(Object obj) {
303
        if ( this == obj ) {
304
            return true;
305
        }
306
        if ( obj instanceof DynField ) {
307
            // FIXME: No esta claro que esto sea correcto.
308
            return name.equals(((DynField) obj).getName());
309
        }
310
        return false;
311
    }
312

    
313
    public Class getClassOfValue() {
314
        return this.type.getClassOfValue();
315
    }
316

    
317
    public DynField setClassOfValue(Class theClass) {
318
        this.type.setClassOfValue(theClass);
319
        return this;
320
    }
321

    
322
    public DynField setClassOfValue(String theClassName) {
323
        this.type.setClassOfValue(theClassName);
324
        return this;
325
    }
326

    
327
    public boolean isContainer() {
328
        if ( type.getDataType() == null ) {
329
            return false;
330
        }
331
        return type.getDataType().isContainer();
332
    }
333

    
334
    public void validate(Object value) throws DynFieldValidateException {
335
        Comparable v;
336
        if ( value == null ) {
337
            if ( this.mandatory ) {
338
                throw new DynFieldRequiredValueException(this, value);
339
            }
340
            return;
341
        }
342

    
343
        switch (this.type.getType()) {
344
        case DataTypes.BOOLEAN:
345
            if ( !(value instanceof Boolean) ) {
346
                throw new DynFieldValidateException(value, this);
347
            }
348
            break;
349

    
350
        case DataTypes.DOUBLE:
351
            if ( !(value instanceof Double) ) {
352
                throw new DynFieldValidateException(value, this);
353
            }
354
            break;
355

    
356
        case DataTypes.FLOAT:
357
            if ( !(value instanceof Float) ) {
358
                throw new DynFieldValidateException(value, this);
359
            }
360
            break;
361

    
362
        case DataTypes.BYTE:
363
            if ( !(value instanceof Byte) ) {
364
                throw new DynFieldValidateException(value, this);
365
            }
366
            break;
367

    
368
        case DataTypes.INT:
369
            if ( !(value instanceof Integer) ) {
370
                throw new DynFieldValidateException(value, this);
371
            }
372
            break;
373

    
374
        case DataTypes.LONG:
375
            if ( !(value instanceof Long) ) {
376
                throw new DynFieldValidateException(value, this);
377
            }
378
            break;
379

    
380
        case DataTypes.STRING:
381
            if ( !(value instanceof String) ) {
382
                throw new DynFieldValidateException(value, this);
383
            }
384
            break;
385

    
386
        case DataTypes.CHAR:
387
            if ( !(value instanceof String) ) {
388
                throw new DynFieldValidateException(value, this);
389
            }
390
            if ( ((String) value).length() > 1 ) {
391
                throw new DynFieldValidateException(value, this);
392
            }
393
            break;
394

    
395
        case DataTypes.DATE:
396
            if ( !(value instanceof Date) ) {
397
                throw new DynFieldValidateException(value, this);
398
            }
399
            break;
400

    
401
        case DataTypes.TIMESTAMP:
402
            if ( !(value instanceof Date) ) {
403
                throw new DynFieldValidateException(value, this);
404
            }
405
            break;
406

    
407
        case DataTypes.TIME:
408
            if ( !(value instanceof Date) ) {
409
                throw new DynFieldValidateException(value, this);
410
            }
411
            break;
412

    
413
        case DataTypes.FILE:
414
            if ( !(value instanceof File) ) {
415
                throw new DynFieldValidateException(value, this);
416
            }
417
            break;
418
        case DataTypes.FOLDER:
419
            if ( !(value instanceof File) ) {
420
                throw new DynFieldValidateException(value, this);
421
            }
422
            break;
423
        case DataTypes.URI:
424
            if ( !(value instanceof URI) ) {
425
                throw new DynFieldValidateException(value, this);
426
            }
427
            break;
428
        case DataTypes.URL:
429
            if ( !(value instanceof URL) ) {
430
                throw new DynFieldValidateException(value, this);
431
            }
432
            break;
433

    
434
        case DataTypes.ARRAY:
435
            // TODO: falta verificar que es un array del tipo que toca.
436
            break;
437

    
438
        case DataTypes.OBJECT:
439
            if ( this.type.getClassOfValue() != null ) {
440
                if ( !this.type.getClassOfValue().isInstance(value) ) {
441
                    throw new DynFieldValidateException(value, this);
442
                }
443
            }
444
            break;
445

    
446
        case DataTypes.MAP:
447
            if ( !(value instanceof Map) ) {
448
                throw new DynFieldValidateException(value, this);
449
            }
450
            validateCollection(value);
451
            break;
452

    
453
        case DataTypes.SET:
454
            if ( !(value instanceof Set) ) {
455
                throw new DynFieldValidateException(value, this);
456
            }
457
            validateCollection(value);
458
            break;
459

    
460
        case DataTypes.LIST:
461
            if ( !(value instanceof List) ) {
462
                throw new DynFieldValidateException(value, this);
463
            }
464
            validateCollection(value);
465
            break;
466

    
467
        case DataTypes.DYNOBJECT:
468
            if ( !(value instanceof DynObject) ) {
469
                throw new DynFieldValidateException(value, this);
470
            }
471
            if ( !this.getDynClassOfValue().isInstance((DynObject) value) ) {
472
                throw new DynFieldValidateException(value, this);
473
            }
474
            try {
475
                this.getDynClassOfValue().validate((DynObject) value);
476
            } catch (DynObjectValidateException e) {
477
                throw new DynFieldValidateException(value, this, e);
478
            }
479
            break;
480

    
481
        default:
482
            if ( this.type.getDataType().isObject() ) {
483
                if ( this.type.getClassOfValue() != null ) {
484
                    if ( !this.type.getClassOfValue().isInstance(value) ) {
485
                        throw new DynFieldValidateException(value, this);
486
                    }
487
                }
488
            }
489
        }
490

    
491
        if ( this.getAvailableValues() != null ) {
492
            if ( !(value instanceof Comparable) ) {
493
                throw new DynFieldValidateException(value, this);
494
            }
495
            v = (Comparable) value;
496
            boolean ok = false;
497
            for ( int i = 0; i < this.availableValues.length; i++ ) {
498
                if ( v.compareTo(this.availableValues[i].getValue()) == 0 ) {
499
                    ok = true;
500
                    break;
501
                }
502
            }
503
            if ( !ok ) {
504
                throw new DynFieldValidateException(value, this);
505
            }
506
        } else if ( this.getMaxValue() != null && this.getMinValue() != null ) {
507
            if ( !(value instanceof Comparable) ) {
508
                throw new DynFieldValidateException(value, this);
509
            }
510
            v = (Comparable) value;
511
            if ( v.compareTo(this.minValue) < 0
512
                    || v.compareTo(this.maxValue) > 0 ) {
513
                throw new DynFieldValidateException(value, this);
514
            }
515
        }
516
    }
517

    
518
    private void validateCollection(Object value) throws ValidateItemException {
519
        if ( this.validateItems ) {
520
            DynStruct dynClass = this.itemsType.getDynClassOfValue();
521
            if ( dynClass != null ) {
522
                int index = 0;
523
                Iterator it = ((Collection) value).iterator();
524
                while ( it.hasNext() ) {
525
                    try {
526
                        dynClass.validate((DynObject) it.next());
527
                        index++;
528
                    } catch (DynObjectValidateException ex) {
529
                        throw new ValidateItemException(ex, index);
530
                    }
531
                }
532
            }
533
        }
534

    
535
    }
536

    
537
    private static class ValidateItemException extends DynFieldValidateException {
538

    
539
        private static final long serialVersionUID = 9011437364983996567L;
540

    
541
        ValidateItemException(Throwable cause, int index) {
542
            super(
543
                    "Can't validate item %(index) of the collection.",
544
                    cause,
545
                    "_Cant_validate_item_%(index)_of_the_collection",
546
                    serialVersionUID
547
            );
548
            setValue("index", new Integer(index));
549
        }
550
    }
551

    
552
    public Object coerce(Object value) throws CoercionException {
553
        if ( value == null ) {
554
            return value; // O debe devolver this.defaultValue
555
        }
556
        try {
557
            return this.type.getDataType().coerce(value);
558
        } catch(Exception ex){
559
            throw new RuntimeException(ex);
560
        }
561
    }
562

    
563
    public String getGroup() {
564
        return this.groupName;
565
    }
566

    
567
    public DynField setGroup(String groupName) {
568
        this.groupName = groupName;
569
        return this;
570
    }
571

    
572
    public int getOder() {
573
        return this.order;
574
    }
575

    
576
    public DynField setOrder(int order) {
577
        this.order = order;
578
        return this;
579
    }
580

    
581
    public boolean isHidden() {
582
        return this.hidden;
583
    }
584

    
585
    public DynField setHidden(boolean hidden) {
586
        this.hidden = hidden;
587
        return this;
588
    }
589

    
590
    public boolean isReadOnly() {
591
        return this.isReadOnly;
592
    }
593

    
594
    public DynField setReadOnly(boolean isReadOnly) {
595
        this.isReadOnly = isReadOnly;
596
        return this;
597
    }
598

    
599
    public DynField setDefaultFieldValue(Object defaultValue) {
600
        try {
601
            this.defaultValue = this.coerce(defaultValue);
602
        } catch (CoercionException e) {
603
            IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
604
            ex.initCause(e);
605
            throw ex;
606
        }
607
        return this;
608
    }
609

    
610
    public Tags getTags() {
611
        return tags;
612
    }
613

    
614
    public String getClassNameOfValue() {
615
        return this.type.getClassNameOfValue();
616
    }
617

    
618
    public DynField setClassOfValue(DynStruct dynStruct) {
619
        this.type.setClassOfValue(dynStruct);
620
        return this;
621
    }
622

    
623
    public DynStruct getDynClassOfValue() {
624
        return this.type.getDynClassOfValue();
625
    }
626

    
627
    public int getRelationType() {
628
        return this.relationType;
629
    }
630

    
631
    public DynField setRelationType(int relationType) {
632
        this.relationType = relationType;
633
        return this;
634
    }
635

    
636
    public DynField setElementsType(int type) {
637
        this.setTypeOfItems(type);
638
        return this;
639
    }
640

    
641
    public DynField setElementsType(DynStruct type) {
642
        this.setClassOfItems(type);
643
        return this;
644
    }
645

    
646
    public DynField getElementsType() {
647
        throw new UnsupportedOperationException("This operation is not suported nevermore.");
648
    }
649

    
650
    public DynField setClassOfItems(DynStruct dynStrct) {
651
        if ( !this.isContainer() ) {
652
            throw new IllegalStateException("Can't assign validateElements in non container.");
653
        }
654
        this.itemsType.setClassOfValue(dynStrct);
655
        return this;
656
    }
657

    
658
    public DynField setClassOfItems(String theClassNameOfValue) {
659
        if ( !this.isContainer() ) {
660
            throw new IllegalStateException("Can't assign validateElements in non container.");
661
        }
662
        this.itemsType.setClassOfValue(theClassNameOfValue);
663
        return this;
664
    }
665

    
666
    public String getClassNameOfItems() {
667
        if ( !this.isContainer() ) {
668
            throw new IllegalStateException("Can't assign validateElements in non container.");
669
        }
670
        return this.itemsType.getClassNameOfValue();
671
    }
672

    
673
    public DynStruct getDynClassOfItems() {
674
        if ( !this.isContainer() ) {
675
            throw new IllegalStateException("Can't assign validateElements in non container.");
676
        }
677
        return this.itemsType.getDynClassOfValue();
678
    }
679

    
680
    public DynField setClassOfItems(Class theClass)
681
            throws DynFieldIsNotAContainerException {
682
        if ( !this.isContainer() ) {
683
            throw new IllegalStateException("Can't assign validateElements in non container.");
684
        }
685
        this.itemsType.setClassOfValue(theClass);
686
        return this;
687
    }
688

    
689
    public Class getClassOfItems() {
690
        if ( !this.isContainer() ) {
691
            throw new IllegalStateException("Can't assign validateElements in non container.");
692
        }
693
        return this.itemsType.getClassOfValue();
694
    }
695

    
696
    public DynField setTypeOfItems(int type) {
697
        if ( !this.isContainer() ) {
698
            throw new IllegalStateException("Can't assign validateElements in non container.");
699
        }
700
        this.itemsType.setType(type);
701
        return this;
702
    }
703

    
704
    public int getTypeOfItems() {
705
        if ( !this.isContainer() ) {
706
            throw new IllegalStateException("Can't assign validateElements in non container.");
707
        }
708
        return this.itemsType.getType();
709
    }
710

    
711
    public DynField setValidateElements(boolean validate) {
712
        if ( !this.isContainer() ) {
713
            throw new IllegalStateException("Can't assign validateElements in non container.");
714
        }
715
        this.validateItems = validate;
716
        return this;
717
    }
718

    
719
    public boolean getValidateElements() {
720
        if ( !this.isContainer() ) {
721
            throw new IllegalStateException("Can't assign validateElements in non container.");
722
        }
723
        return this.validateItems;
724
    }
725

    
726
}