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

History | View | Annotate | Download (14.7 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, "name", name);
57
                }
58
                if( exceptions!= null ) {
59
                        throw exceptions;
60
                }
61
        }
62
        
63
        public static class CheckDynFieldListException extends ListBaseException {  
64
        
65
                public static class CheckDynFieldException extends DynObjectException {
66
                        
67
                        /**
68
                         * 
69
                         */
70
                        private static final long serialVersionUID = 2486744641818117262L;
71

    
72
                        public CheckDynFieldException(String attrname, Object attrvalue) {
73
                                super(
74
                                                "Wrong value %(value) for attribute %(name).",
75
                                                "Wrong_value_XvalueX_for_attribute_XnameX",
76
                                                serialVersionUID
77
                                );
78
                        }
79
                }
80
                
81
                /**
82
                 * 
83
                 */
84
                private static final long serialVersionUID = 1L;
85

    
86
                public CheckDynFieldListException(String name) {
87
                        super(
88
                                "Inconsistent field %(name) definition.",
89
                                "_Inconsistent_field_XnameX_definition",
90
                                serialVersionUID
91
                        );
92
                        if( name == null ) {
93
                                name = "[unknow]";
94
                        }
95
                        setValue("name",name);
96
                }
97
                
98
                public static ListBaseException add(ListBaseException exceptions, String name, String attrname, Object attrvalue) {
99
                        if( exceptions == null ) {
100
                                exceptions = new CheckDynFieldListException(name);
101
                        }
102
                        exceptions.add( new CheckDynFieldException(attrname, attrvalue) );
103
                        return exceptions;
104
                }
105
        }
106
        
107
        public DefaultDynField(String name) {
108
                this(name, // field name
109
                                DataTypes.STRING, // data type
110
                                null, // default value
111
                                true, // persistent
112
                                false // mandatory
113
                );
114
        }
115
        
116
        private DefaultDynField(String name, int dataType) {
117
                this(name, // field name
118
                                dataType, // data type
119
                                null, // default value
120
                                true, // persistent
121
                                false // mandatory
122
                );
123
        }
124

    
125
        public DefaultDynField(String name, int dataType, Object defaultValue,
126
                        boolean persistent, boolean mandatory) {
127
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
128

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

    
143
        public String toString() {
144
                StringBuffer buffer = new StringBuffer();
145

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

    
162
        public String getName() {
163
                return name;
164
        }
165

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

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

    
175
        public DynField setType(int dataType) {
176
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
177
                return setType( datamanager.get(dataType) );
178
        }
179

    
180
        public DynField setType(DataType dataType) {
181
                this.dataType = dataType;
182
                this.theClass = this.dataType.getDefaultClass();
183
                this.subtype = this.dataType.getSubtype();
184
                return this;
185
        }
186

    
187
        public int getType() {
188
                return dataType.getType();
189
        }
190

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

    
214
        public String getSubtype() {
215
                return subtype;
216
        }
217

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

    
223
        public Object getDefaultValue() {
224
                return defaultValue;
225
        }
226

    
227
        public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
228
                if (availableValues == null || availableValues.length == 0) {
229
                        this.availableValues = null;
230
                } else {
231
                        this.availableValues = availableValues;
232
                }
233
                return this;
234
        }
235

    
236
        public DynField setAvailableValues(List availableValues) {
237
                if( availableValues == null ) {
238
                        this.availableValues = null;
239
                } else if( availableValues.isEmpty() ) {
240
                        this.availableValues = null;
241
                } else {
242
                        this.availableValues = (DynObjectValueItem[]) availableValues
243
                                        .toArray(new DynObjectValueItem[availableValues.size()]);
244
                }
245
                return this;
246
        }
247

    
248
        public DynObjectValueItem[] getAvailableValues() {
249
                return availableValues;
250
        }
251

    
252
        public DynField setMinValue(Object minValue) {
253
                this.minValue = minValue;
254
                return this;
255
        }
256

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

    
261
        public DynField setMaxValue(Object maxValue) {
262
                this.maxValue = maxValue;
263
                return this;
264
        }
265

    
266
        public Object getMaxValue() {
267
                return maxValue;
268
        }
269

    
270
        public boolean isMandatory() {
271
                return this.mandatory;
272
        }
273

    
274
        public boolean isPersistent() {
275
                return this.persistent;
276
        }
277

    
278
        public DynField setMandatory(boolean mandatory) {
279
                this.mandatory = mandatory;
280
                return this;
281
        }
282

    
283
        public DynField setPersistent(boolean persistent) {
284
                this.persistent = persistent;
285
                return this;
286
        }
287

    
288
        public DynField setTheTypeOfAvailableValues(int type) {
289
                return this; // FIXME: this method is @deprecated
290
        }
291

    
292
        public int getTheTypeOfAvailableValues() {
293
                return 1; // FIXME: this method is @deprecated
294
        }
295

    
296
        public boolean equals(Object obj) {
297
                if (this == obj) {
298
                        return true;
299
                }
300
                if (obj instanceof DynField) {
301
                        // FIXME: No esta claro que esto sea correcto.
302
                        return name.equals(((DynField) obj).getName());
303
                }
304
                return false;
305
        }
306

    
307
        public Class getClassOfValue() {
308
                return theClass;
309
        }
310

    
311
        public DynField setValidateElements(boolean validate) {
312
                if ( !this.dataType.isContainer()) {
313
                        throw new DynFieldIsNotAContainerException(this.name);
314
                }
315
                this.validateElements = validate;
316
                return this;
317
        }
318

    
319
        public boolean getValidateElements() {
320
                return this.validateElements;
321
        }
322

    
323
        public DynField setClassOfValue(Class theClass)
324
                        throws DynFieldIsNotAContainerException {
325
                this.theClass = theClass;
326
                return this;
327
        }
328

    
329
        public DynField setElementsType(int type)
330
                        throws DynFieldIsNotAContainerException {
331
                if (!isContainer()) {
332
                        throw new DynFieldIsNotAContainerException(this.name);
333
                }
334
                this.elementsType = new DefaultDynField(this.name + "-"
335
                                + this.dataType.getName()
336
                                + "-item",type);
337
                return this;
338
        }
339

    
340

    
341
        public DynField setElementsType(DynStruct type)
342
                        throws DynFieldIsNotAContainerException {
343
                // Getter allows null values
344
                if (type != null) {
345
                        this.setElementsType(DataTypes.DYNOBJECT).getElementsType().setSubtype(type.getFullName());
346
                }
347
                return this;
348
        }
349

    
350
        public boolean isContainer(){
351
            return this.dataType.isContainer();
352
        }
353

    
354
        public DynField getElementsType() {
355
                return this.elementsType;
356
        }
357

    
358
        public void validate(Object value) throws DynFieldValidateException {
359
                Comparable v;
360
                if (value == null) {
361
                        if (this.mandatory) {
362
                                throw new DynFieldRequiredValueException(this, value);
363
                        }
364
                        return;
365
                }
366

    
367
                switch (this.dataType.getType()) {
368
                case DataTypes.BOOLEAN:
369
                        if (!(value instanceof Boolean)) {
370
                                throw new DynFieldValidateException(value, this);
371
                        }
372
                        break;
373

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

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

    
386
                case DataTypes.INT:
387
                        if (!(value instanceof Integer)) {
388
                                throw new DynFieldValidateException(value, this);
389
                        }
390
                        break;
391

    
392
                case DataTypes.LONG:
393
                        if (!(value instanceof Long)) {
394
                                throw new DynFieldValidateException(value, this);
395
                        }
396
                        break;
397

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

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

    
410
                case DataTypes.LIST:
411
                        if (!(value instanceof List)) {
412
                                throw new DynFieldValidateException(value, this);
413
                        }
414
                        if (this.validateElements && this.elementsType != null) {
415
                                Iterator it = ((List) value).iterator();
416
                                while (it.hasNext()) {
417
                                        this.elementsType.validate(it.next());
418
                                }
419
                        }
420
                        break;
421

    
422
                case DataTypes.MAP:
423
                        if (!(value instanceof Map)) {
424
                                throw new DynFieldValidateException(value, this);
425
                        }
426
                        break;
427
                case DataTypes.FILE:
428
                    if (!(value instanceof File)) {
429
                            throw new DynFieldValidateException(value, this);
430
                    }
431
                    break;
432
                case DataTypes.FOLDER:
433
                    if (!(value instanceof File)) {
434
                            throw new DynFieldValidateException(value, this);
435
                    }
436
                    break;
437
                case DataTypes.URI:
438
                    if (!(value instanceof URI)) {
439
                            throw new DynFieldValidateException(value, this);
440
                    }
441
                    break;
442
                case DataTypes.URL:
443
                    if (!(value instanceof URL)) {
444
                            throw new DynFieldValidateException(value, this);
445
                    }
446
                    break;
447
                case DataTypes.SET:
448
                        if (!(value instanceof Set)) {
449
                                throw new DynFieldValidateException(value, this);
450
                        }
451
                        break;
452

    
453
                case DataTypes.DYNOBJECT:
454
                        if (!(value instanceof DynObject)) {
455
                                throw new DynFieldValidateException(value, this);
456
                        }
457
                        DynClass dynClass = ToolsLocator.getDynObjectManager().get(
458
                                        this.getSubtype());
459
                        if ( dynClass==null || !dynClass.isInstance((DynObject) value)) {
460
                                throw new DynFieldValidateException(value, this);
461
                        }
462
                        try {
463
                                dynClass.validate((DynObject) value);
464
                        } catch (DynObjectValidateException e) {
465
                                throw new DynFieldValidateException(value, this, e);
466
                        }
467
                        break;
468

    
469
                case DataTypes.ARRAY:
470
                        // TODO: falta verificar que es un array del tipo que toca.
471
                        break;
472

    
473
                default:
474
                        if( this.dataType.isObject() ) {
475
                                if (this.theClass != null) {
476
                                        if (!this.theClass.isInstance(value)) {
477
                                                throw new DynFieldValidateException(value, this);
478
                                        }
479
                                }
480
                        } else {
481
                                throw new DynFieldValidateException(value, this);
482
                        }
483
                }
484

    
485
                if (this.getAvailableValues() != null) {
486
                        if (!(value instanceof Comparable)) {
487
                                throw new DynFieldValidateException(value, this);
488
                        }
489
                        v = (Comparable) value;
490
                        boolean ok = false;
491
                        for (int i = 0; i < this.availableValues.length; i++) {
492
                                if (v.compareTo(this.availableValues[i].getValue()) == 0) {
493
                                        ok = true;
494
                                        break;
495
                                }
496
                        }
497
                        if (!ok) {
498
                                throw new DynFieldValidateException(value, this);
499
                        }
500
                } else if (this.getMaxValue() != null && this.getMinValue() != null) {
501
                        if (!(value instanceof Comparable)) {
502
                                throw new DynFieldValidateException(value, this);
503
                        }
504
                        v = (Comparable) value;
505
                        if (v.compareTo(this.minValue) < 0
506
                                        || v.compareTo(this.maxValue) > 0) {
507
                                throw new DynFieldValidateException(value, this);
508
                        }
509
                }
510
//
511
//                This shouldn't be necessary since any assignment passes through the coerce function anyway
512
//
513
//                //if all the above is correct, then we should check that coercing is possible
514
//                try {
515
//                        coerce(value);
516
//                } catch (CoercionException e) {
517
//                        throw new DynFieldValidateException(value, this);
518
//                }
519
                
520
        }
521

    
522
        public Object coerce(Object value) throws CoercionException {
523
                if (value == null) {
524
                        return value; // O debe devolver this.defaultValue
525
                }
526
                return this.dataType.coerce(value);
527
        }
528

    
529

    
530
        public String getGroup() {
531
                return this.groupName;
532
        }
533

    
534
        public DynField setGroup(String groupName) {
535
                this.groupName = groupName;
536
                return this;
537
        }
538

    
539
        public int getOder() {
540
                return this.order;
541
        }
542

    
543
        public DynField setOrder(int order) {
544
                this.order = order;
545
                return this;
546
        }
547

    
548
        public boolean isHidden() {
549
                return this.hidden;
550
        }
551

    
552
        public DynField setHidden(boolean hidden) {
553
                this.hidden = hidden;
554
                return this;
555
        }
556
        
557
        public boolean isReadOnly() {
558
            return this.isReadOnly;
559
        }
560

    
561
        
562
        public DynField setReadOnly(boolean isReadOnly) {
563
            this.isReadOnly = isReadOnly;
564
            return this;
565
        }
566

    
567
        public Class getClassOfItems() {
568
                return this.theClassOfItems;
569
        }
570

    
571
        public DynField setDefaultFieldValue(Object defaultValue) {
572
                this.defaultValue = defaultValue;
573
                return this;
574
        }
575

    
576
        public DynField setClassOfItems(Class theClass)
577
                        throws DynFieldIsNotAContainerException {
578
                // Getter allows null values
579
                if (theClass == null) {
580
                        return this;
581
                }
582
                if (! this.dataType.isContainer() ) {
583
                        throw new DynFieldIsNotAContainerException(this.name);
584
                }
585
                this.theClassOfItems = theClass;
586
                return this;
587
        }
588

    
589

    
590
}