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

History | View | Annotate | Download (15.6 KB)

1
package org.gvsig.tools.dynobject.impl;
2

    
3
import java.io.File;
4
import java.net.URI;
5
import java.net.URL;
6
import java.util.Date;
7
import java.util.Iterator;
8
import java.util.List;
9
import java.util.Map;
10
import java.util.Set;
11

    
12
import org.gvsig.tools.ToolsLocator;
13
import org.gvsig.tools.dataTypes.CoercionException;
14
import org.gvsig.tools.dataTypes.DataType;
15
import org.gvsig.tools.dataTypes.DataTypes;
16
import org.gvsig.tools.dataTypes.DataTypesManager;
17
import org.gvsig.tools.dynobject.DynClass;
18
import org.gvsig.tools.dynobject.DynField;
19
import org.gvsig.tools.dynobject.DynObject;
20
import org.gvsig.tools.dynobject.DynObjectException;
21
import org.gvsig.tools.dynobject.DynObjectValueItem;
22
import org.gvsig.tools.dynobject.DynStruct;
23
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
24
import org.gvsig.tools.dynobject.exception.DynFieldRequiredValueException;
25
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
26
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
27
import org.gvsig.tools.exception.ListBaseException;
28

    
29
public class DefaultDynField implements DynField {
30
        private String name;
31
        private String description;
32

    
33
        private DataType dataType;
34
        private String subtype;
35

    
36
        private Object defaultValue;
37

    
38
        private int order;
39
        private boolean hidden;
40
        private String groupName;
41
        private DynObjectValueItem[] availableValues;
42
        private Object minValue;
43
        private Object maxValue;
44
        private boolean mandatory;
45
        private boolean persistent;
46
        private Class theClass;
47
        private DynField elementsType;
48
        private boolean validateElements;
49
        private boolean isReadOnly;
50
        private Class theClassOfItems = null;
51

    
52
        public void check() throws ListBaseException {
53
                ListBaseException exceptions = null;
54

    
55
                if (name == null) {
56
                        exceptions = CheckDynFieldListException.add(exceptions, name,
57
                                        "name", name);
58
                }
59
                if (exceptions != null) {
60
                        throw exceptions;
61
                }
62
        }
63

    
64
        public static class CheckDynFieldListException extends ListBaseException {
65

    
66
                public static class CheckDynFieldException extends DynObjectException {
67

    
68
                        /**
69
                         * 
70
                         */
71
                        private static final long serialVersionUID = 2486744641818117262L;
72

    
73
                        public CheckDynFieldException(String attrname, Object attrvalue) {
74
                                super("Wrong value %(value) for attribute %(name).",
75
                                                "Wrong_value_XvalueX_for_attribute_XnameX",
76
                                                serialVersionUID);
77
                        }
78
                }
79

    
80
                /**
81
                 * 
82
                 */
83
                private static final long serialVersionUID = 1L;
84

    
85
                public CheckDynFieldListException(String name) {
86
                        super("Inconsistent field %(name) definition.",
87
                                        "_Inconsistent_field_XnameX_definition", serialVersionUID);
88
                        if (name == null) {
89
                                name = "[unknow]";
90
                        }
91
                        setValue("name", name);
92
                }
93

    
94
                public static ListBaseException add(ListBaseException exceptions,
95
                                String name, String attrname, Object attrvalue) {
96
                        if (exceptions == null) {
97
                                exceptions = new CheckDynFieldListException(name);
98
                        }
99
                        exceptions.add(new CheckDynFieldException(attrname, attrvalue));
100
                        return exceptions;
101
                }
102
        }
103

    
104
        public DefaultDynField(String name) {
105
                this(name, // field name
106
                                DataTypes.STRING, // data type
107
                                null, // default value
108
                                true, // persistent
109
                                false // mandatory
110
                );
111
        }
112

    
113
        private DefaultDynField(String name, int dataType) {
114
                this(name, // field name
115
                                dataType, // data type
116
                                null, // default value
117
                                true, // persistent
118
                                false // mandatory
119
                );
120
        }
121

    
122
        public DefaultDynField(String name, int dataType, Object defaultValue,
123
                        boolean persistent, boolean mandatory) {
124
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
125

    
126
                this.name = name;
127
                this.dataType = datamanager.get(dataType);
128
                this.defaultValue = defaultValue;
129
                this.persistent = persistent;
130
                this.mandatory = mandatory;
131
                this.theClass = null;
132
                this.validateElements = false;
133
                this.subtype = this.dataType.getSubtype();
134
                this.groupName = null;
135
                this.order = 0;
136
                this.hidden = false;
137
                this.availableValues = null;
138
        }
139

    
140
        public String toString() {
141
                StringBuffer buffer = new StringBuffer();
142

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

    
159
        public String getName() {
160
                return name;
161
        }
162

    
163
        public DynField setDescription(String description) {
164
                this.description = description;
165
                return this;
166
        }
167

    
168
        public String getDescription() {
169
                return (description == null) ? getName() : description;
170
        }
171

    
172
        public DynField setType(int dataType) {
173
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
174
                return setType(datamanager.get(dataType));
175
        }
176

    
177
        public DynField setType(DataType dataType) {
178
                this.dataType = dataType;
179
                this.theClass = this.dataType.getDefaultClass();
180
                this.subtype = this.dataType.getSubtype();
181
                return this;
182
        }
183

    
184
        public int getType() {
185
                return dataType.getType();
186
        }
187

    
188
        public DataType getDataType() {
189
                return this.dataType;
190
        }
191

    
192
        public DynField setSubtype(String subtype) {
193
                this.subtype = subtype;
194
                if (subtype != null && this.dataType.getType() == DataTypes.LIST
195
                                && this.elementsType != null
196
                                && this.elementsType.getType() == DataTypes.DYNOBJECT) {
197
                        if (ToolsLocator.getDynObjectManager().get(subtype) == null) {
198
                                throw new IllegalArgumentException("DynClass '" + subtype
199
                                                + "' does not exist.");
200
                        }
201
                        this.elementsType.setSubtype(subtype);
202
                } else if (subtype != null
203
                                && this.dataType.getType() == DataTypes.DYNOBJECT) {
204
                        if (ToolsLocator.getDynObjectManager().get(subtype) == null) {
205
                                throw new IllegalArgumentException("DynClass '" + subtype
206
                                                + "' does not exist.");
207
                        }
208
                }
209
                return this;
210
        }
211

    
212
        public String getSubtype() {
213
                return subtype;
214
        }
215

    
216
        public DynField setDefaultDynValue(Object defaultValue) {
217
                this.defaultValue = defaultValue;
218
                return this;
219
        }
220

    
221
        public Object getDefaultValue() {
222
                return defaultValue;
223
        }
224

    
225
        public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
226
                // If type is a list then the available values should be at the elements
227
                // type, not here.
228
                if (this.getType() == DataTypes.LIST) {
229
                        if (this.getElementsType() != null) {
230
                                this.getElementsType().setAvailableValues(availableValues);
231
                                return this;
232
                        }
233
                }
234
                if (availableValues == null || availableValues.length == 0) {
235
                        this.availableValues = null;
236
                } else {
237
                        this.availableValues = availableValues;
238
                }
239
                return this;
240
        }
241

    
242
        public DynField setAvailableValues(List availableValues) {
243
                // If type is a list then the available values should be at the elements
244
                // type, not here.
245
                if (this.getType() == DataTypes.LIST) {
246
                        if (this.getElementsType() != null) {
247
                                this.getElementsType().setAvailableValues(availableValues);
248
                                return this;
249
                        }
250
                }
251
                if (availableValues == null) {
252
                        this.availableValues = null;
253
                } else if (availableValues.isEmpty()) {
254
                        this.availableValues = null;
255
                } else {
256
                        this.availableValues = (DynObjectValueItem[]) availableValues
257
                                        .toArray(new DynObjectValueItem[availableValues.size()]);
258
                }
259
                return this;
260
        }
261

    
262
        public DynObjectValueItem[] getAvailableValues() {
263
                return availableValues;
264
        }
265

    
266
        public DynField setMinValue(Object minValue) {
267
                try {
268
                        this.minValue = this.coerce(minValue);
269
                } catch (CoercionException e) {
270
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
271
                        ex.initCause(e);
272
                        throw ex;
273
                }
274
                return this;
275
        }
276

    
277
        public Object getMinValue() {
278
                return minValue;
279
        }
280

    
281
        public DynField setMaxValue(Object maxValue) {
282
                try {
283
                        this.maxValue = this.coerce(maxValue);
284
                } catch (CoercionException e) {
285
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
286
                        ex.initCause(e);
287
                        throw ex;
288
                }
289
                return this;
290
        }
291

    
292
        public Object getMaxValue() {
293
                return maxValue;
294
        }
295

    
296
        public boolean isMandatory() {
297
                return this.mandatory;
298
        }
299

    
300
        public boolean isPersistent() {
301
                return this.persistent;
302
        }
303

    
304
        public DynField setMandatory(boolean mandatory) {
305
                this.mandatory = mandatory;
306
                return this;
307
        }
308

    
309
        public DynField setPersistent(boolean persistent) {
310
                this.persistent = persistent;
311
                return this;
312
        }
313

    
314
        public DynField setTheTypeOfAvailableValues(int type) {
315
                return this; // FIXME: this method is @deprecated
316
        }
317

    
318
        public int getTheTypeOfAvailableValues() {
319
                return 1; // FIXME: this method is @deprecated
320
        }
321

    
322
        public boolean equals(Object obj) {
323
                if (this == obj) {
324
                        return true;
325
                }
326
                if (obj instanceof DynField) {
327
                        // FIXME: No esta claro que esto sea correcto.
328
                        return name.equals(((DynField) obj).getName());
329
                }
330
                return false;
331
        }
332

    
333
        public Class getClassOfValue() {
334
                return theClass;
335
        }
336

    
337
        public DynField setValidateElements(boolean validate) {
338
                if (!this.dataType.isContainer()) {
339
                        throw new DynFieldIsNotAContainerException(this.name);
340
                }
341
                this.validateElements = validate;
342
                return this;
343
        }
344

    
345
        public boolean getValidateElements() {
346
                return this.validateElements;
347
        }
348

    
349
        public DynField setClassOfValue(Class theClass)
350
                        throws DynFieldIsNotAContainerException {
351
                this.theClass = theClass;
352
                return this;
353
        }
354

    
355
        public DynField setElementsType(int type)
356
                        throws DynFieldIsNotAContainerException {
357
                if (!isContainer()) {
358
                        throw new DynFieldIsNotAContainerException(this.name);
359
                }
360
                this.elementsType = new DefaultDynField(this.name + "-"
361
                                + this.dataType.getName() + "-item", type);
362
                return this;
363
        }
364

    
365
        public DynField setElementsType(DynStruct type)
366
                        throws DynFieldIsNotAContainerException {
367
                // Getter allows null values
368
                if (type != null) {
369
                        this.setElementsType(DataTypes.DYNOBJECT).getElementsType()
370
                                        .setSubtype(type.getFullName());
371
                }
372
                return this;
373
        }
374

    
375
        public boolean isContainer() {
376
                return this.dataType.isContainer();
377
        }
378

    
379
        public DynField getElementsType() {
380
                return this.elementsType;
381
        }
382

    
383
        public void validate(Object value) throws DynFieldValidateException {
384
                Comparable v;
385
                if (value == null) {
386
                        if (this.mandatory) {
387
                                throw new DynFieldRequiredValueException(this, value);
388
                        }
389
                        return;
390
                }
391

    
392
                switch (this.dataType.getType()) {
393
                case DataTypes.BOOLEAN:
394
                        if (!(value instanceof Boolean)) {
395
                                throw new DynFieldValidateException(value, this);
396
                        }
397
                        break;
398

    
399
                case DataTypes.DOUBLE:
400
                        if (!(value instanceof Double)) {
401
                                throw new DynFieldValidateException(value, this);
402
                        }
403
                        break;
404

    
405
                case DataTypes.FLOAT:
406
                        if (!(value instanceof Float)) {
407
                                throw new DynFieldValidateException(value, this);
408
                        }
409
                        break;
410

    
411
                case DataTypes.INT:
412
                        if (!(value instanceof Integer)) {
413
                                throw new DynFieldValidateException(value, this);
414
                        }
415
                        break;
416

    
417
                case DataTypes.LONG:
418
                        if (!(value instanceof Long)) {
419
                                throw new DynFieldValidateException(value, this);
420
                        }
421
                        break;
422

    
423
                case DataTypes.STRING:
424
                        if (!(value instanceof String)) {
425
                                throw new DynFieldValidateException(value, this);
426
                        }
427
                        break;
428

    
429
                case DataTypes.DATE:
430
                        if (!(value instanceof Date)) {
431
                                throw new DynFieldValidateException(value, this);
432
                        }
433
                        break;
434

    
435
                case DataTypes.LIST:
436
                        if (!(value instanceof List)) {
437
                                throw new DynFieldValidateException(value, this);
438
                        }
439
                        if (this.validateElements && this.elementsType != null) {
440
                                Iterator it = ((List) value).iterator();
441
                                while (it.hasNext()) {
442
                                        this.elementsType.validate(it.next());
443
                                }
444
                        }
445
                        break;
446

    
447
                case DataTypes.MAP:
448
                        if (!(value instanceof Map)) {
449
                                throw new DynFieldValidateException(value, this);
450
                        }
451
                        break;
452
                case DataTypes.FILE:
453
                        if (!(value instanceof File)) {
454
                                throw new DynFieldValidateException(value, this);
455
                        }
456
                        break;
457
                case DataTypes.FOLDER:
458
                        if (!(value instanceof File)) {
459
                                throw new DynFieldValidateException(value, this);
460
                        }
461
                        break;
462
                case DataTypes.URI:
463
                        if (!(value instanceof URI)) {
464
                                throw new DynFieldValidateException(value, this);
465
                        }
466
                        break;
467
                case DataTypes.URL:
468
                        if (!(value instanceof URL)) {
469
                                throw new DynFieldValidateException(value, this);
470
                        }
471
                        break;
472
                case DataTypes.SET:
473
                        if (!(value instanceof Set)) {
474
                                throw new DynFieldValidateException(value, this);
475
                        }
476
                        break;
477

    
478
                case DataTypes.DYNOBJECT:
479
                        if (!(value instanceof DynObject)) {
480
                                throw new DynFieldValidateException(value, this);
481
                        }
482
                        DynClass dynClass = ToolsLocator.getDynObjectManager().get(
483
                                        this.getSubtype());
484
                        if (dynClass == null || !dynClass.isInstance((DynObject) value)) {
485
                                throw new DynFieldValidateException(value, this);
486
                        }
487
                        try {
488
                                dynClass.validate((DynObject) value);
489
                        } catch (DynObjectValidateException e) {
490
                                throw new DynFieldValidateException(value, this, e);
491
                        }
492
                        break;
493

    
494
                case DataTypes.ARRAY:
495
                        // TODO: falta verificar que es un array del tipo que toca.
496
                        break;
497

    
498
                default:
499
                        if (this.dataType.isObject()) {
500
                                if (this.theClass != null) {
501
                                        if (!this.theClass.isInstance(value)) {
502
                                                throw new DynFieldValidateException(value, this);
503
                                        }
504
                                }
505
                        } else {
506
                                throw new DynFieldValidateException(value, this);
507
                        }
508
                }
509

    
510
                if (this.getAvailableValues() != null) {
511
                        if (!(value instanceof Comparable)) {
512
                                throw new DynFieldValidateException(value, this);
513
                        }
514
                        v = (Comparable) value;
515
                        boolean ok = false;
516
                        for (int i = 0; i < this.availableValues.length; i++) {
517
                                if (v.compareTo(this.availableValues[i].getValue()) == 0) {
518
                                        ok = true;
519
                                        break;
520
                                }
521
                        }
522
                        if (!ok) {
523
                                throw new DynFieldValidateException(value, this);
524
                        }
525
                } else if (this.getMaxValue() != null && this.getMinValue() != null) {
526
                        if (!(value instanceof Comparable)) {
527
                                throw new DynFieldValidateException(value, this);
528
                        }
529
                        v = (Comparable) value;
530
                        if (v.compareTo(this.minValue) < 0
531
                                        || v.compareTo(this.maxValue) > 0) {
532
                                throw new DynFieldValidateException(value, this);
533
                        }
534
                }
535
                //
536
                // This shouldn't be necessary since any assignment passes through the
537
                // coerce function anyway
538
                //
539
                // //if all the above is correct, then we should check that coercing is
540
                // possible
541
                // try {
542
                // coerce(value);
543
                // } catch (CoercionException e) {
544
                // throw new DynFieldValidateException(value, this);
545
                // }
546

    
547
        }
548

    
549
        public Object coerce(Object value) throws CoercionException {
550
                if (value == null) {
551
                        return value; // O debe devolver this.defaultValue
552
                }
553
                return this.dataType.coerce(value);
554
        }
555

    
556
        public String getGroup() {
557
                return this.groupName;
558
        }
559

    
560
        public DynField setGroup(String groupName) {
561
                this.groupName = groupName;
562
                return this;
563
        }
564

    
565
        public int getOder() {
566
                return this.order;
567
        }
568

    
569
        public DynField setOrder(int order) {
570
                this.order = order;
571
                return this;
572
        }
573

    
574
        public boolean isHidden() {
575
                return this.hidden;
576
        }
577

    
578
        public DynField setHidden(boolean hidden) {
579
                this.hidden = hidden;
580
                return this;
581
        }
582

    
583
        public boolean isReadOnly() {
584
                return this.isReadOnly;
585
        }
586

    
587
        public DynField setReadOnly(boolean isReadOnly) {
588
                this.isReadOnly = isReadOnly;
589
                return this;
590
        }
591

    
592
        public Class getClassOfItems() {
593
                return this.theClassOfItems;
594
        }
595

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

    
607
        public DynField setClassOfItems(Class theClass)
608
                        throws DynFieldIsNotAContainerException {
609
                // Getter allows null values
610
                if (theClass == null) {
611
                        return this;
612
                }
613
                if (!this.dataType.isContainer()) {
614
                        throw new DynFieldIsNotAContainerException(this.name);
615
                }
616
                this.theClassOfItems = theClass;
617
                return this;
618
        }
619

    
620
}