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

History | View | Annotate | Download (17.5 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.Date;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Set;
34

    
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dataTypes.CoercionException;
37
import org.gvsig.tools.dataTypes.DataType;
38
import org.gvsig.tools.dataTypes.DataTypes;
39
import org.gvsig.tools.dataTypes.DataTypesManager;
40
import org.gvsig.tools.dynobject.DynClass;
41
import org.gvsig.tools.dynobject.DynField;
42
import org.gvsig.tools.dynobject.DynField_LabelAttribute;
43
import org.gvsig.tools.dynobject.DynObject;
44
import org.gvsig.tools.dynobject.DynObjectException;
45
import org.gvsig.tools.dynobject.DynObjectValueItem;
46
import org.gvsig.tools.dynobject.DynStruct;
47
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
48
import org.gvsig.tools.dynobject.exception.DynFieldRequiredValueException;
49
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
50
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
51
import org.gvsig.tools.exception.ListBaseException;
52

    
53
public class DefaultDynField implements DynField, DynField_LabelAttribute {
54
        private String name;
55
        private String description;
56

    
57
        private DataType dataType;
58
        private String subtype;
59

    
60
        private Object defaultValue;
61

    
62
        private int order;
63
        private boolean hidden;
64
        private String groupName;
65
        private DynObjectValueItem[] availableValues;
66
        private Object minValue;
67
        private Object maxValue;
68
        private boolean mandatory;
69
        private boolean persistent;
70
        private Class theClass;
71
        private DynField elementsType;
72
        private boolean validateElements;
73
        private boolean isReadOnly;
74
        private Class theClassOfItems = null;
75
        private String label = null;
76

    
77
        public void check() throws ListBaseException {
78
                ListBaseException exceptions = null;
79

    
80
                if (name == null) {
81
                        exceptions = CheckDynFieldListException.add(exceptions, name,
82
                                        "name", name);
83
                }
84
                if (exceptions != null) {
85
                        throw exceptions;
86
                }
87
        }
88

    
89
        public static class CheckDynFieldListException extends ListBaseException {
90

    
91
                public static class CheckDynFieldException extends DynObjectException {
92

    
93
                        /**
94
                         * 
95
                         */
96
                        private static final long serialVersionUID = 2486744641818117262L;
97

    
98
                        public CheckDynFieldException(String attrname, Object attrvalue) {
99
                                super("Wrong value %(value) for attribute %(name).",
100
                                                "Wrong_value_XvalueX_for_attribute_XnameX",
101
                                                serialVersionUID);
102
                        }
103
                }
104

    
105
                /**
106
                 * 
107
                 */
108
                private static final long serialVersionUID = 1L;
109

    
110
                public CheckDynFieldListException(String name) {
111
                        super("Inconsistent field %(name) definition.",
112
                                        "_Inconsistent_field_XnameX_definition", serialVersionUID);
113
                        if (name == null) {
114
                                name = "[unknow]";
115
                        }
116
                        setValue("name", name);
117
                }
118

    
119
                public static ListBaseException add(ListBaseException exceptions,
120
                                String name, String attrname, Object attrvalue) {
121
                        if (exceptions == null) {
122
                                exceptions = new CheckDynFieldListException(name);
123
                        }
124
                        exceptions.add(new CheckDynFieldException(attrname, attrvalue));
125
                        return exceptions;
126
                }
127
        }
128

    
129
        public DefaultDynField(String name) {
130
                this(name, // field name
131
                                DataTypes.STRING, // data type
132
                                null, // default value
133
                                true, // persistent
134
                                false // mandatory
135
                );
136
        }
137

    
138
        private DefaultDynField(String name, int dataType) {
139
                this(name, // field name
140
                                dataType, // data type
141
                                null, // default value
142
                                true, // persistent
143
                                false // mandatory
144
                );
145
        }
146

    
147
        public DefaultDynField(String name, int dataType, Object defaultValue,
148
                        boolean persistent, boolean mandatory) {
149
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
150

    
151
                this.name = name;
152
                this.dataType = datamanager.get(dataType);
153
                this.defaultValue = defaultValue;
154
                this.persistent = persistent;
155
                this.mandatory = mandatory;
156
                this.theClass = null;
157
                this.validateElements = false;
158
                this.subtype = this.dataType.getSubtype();
159
                this.groupName = null;
160
                this.order = 0;
161
                this.hidden = false;
162
                this.availableValues = null;
163
        }
164

    
165
        public String toString() {
166
                StringBuffer buffer = new StringBuffer();
167

    
168
                buffer.append("DynField").append("[").append(this.hashCode())
169
                                .append("]").append("( ").append("name='").append(this.name)
170
                                .append("', ").append("description='").append(this.description)
171
                                .append("', ").append("type='").append(this.dataType.getName())
172
                                .append("', ").append("subType='").append(this.subtype)
173
                                .append("', ").append("mandatory='").append(this.isMandatory())
174
                                .append("', ").append("defaultValue='")
175
                                .append(this.getDefaultValue()).append("', ")
176
                                .append("dataType=[").append(this.dataType).append("], ")
177
                                .append("minValue='").append(this.minValue).append("', ")
178
                                .append("maxValue='").append(this.maxValue).append("', ")
179
                                .append("persistent='").append(this.isPersistent())
180
                                .append(" )");
181
                return buffer.toString();
182
        }
183

    
184
        public String getName() {
185
                return name;
186
        }
187

    
188
        public DynField setDescription(String description) {
189
                this.description = description;
190
                return this;
191
        }
192

    
193
        public String getDescription() {
194
                return (description == null) ? getLabel() : description;
195
        }
196

    
197
        public DynField setLabel(String label) {
198
                this.label = label;
199
                return this;
200
        }
201

    
202
        public String getLabel() {
203
                return (label == null) ? getName() : label;
204
        }
205
        
206
        public DynField setType(int dataType) {
207
                DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
208
                return setType(datamanager.get(dataType));
209
        }
210

    
211
        public DynField setType(DataType dataType) {
212
                this.dataType = dataType;
213
                this.theClass = this.dataType.getDefaultClass();
214
                this.subtype = this.dataType.getSubtype();
215
                return this;
216
        }
217

    
218
        public int getType() {
219
                return dataType.getType();
220
        }
221

    
222
        public DataType getDataType() {
223
                return this.dataType;
224
        }
225

    
226
        public DynField setSubtype(String subtype) {
227
                this.subtype = subtype;
228
                if (subtype != null && this.dataType.getType() == DataTypes.LIST
229
                                && this.elementsType != null
230
                                && this.elementsType.getType() == DataTypes.DYNOBJECT) {
231
                        if (ToolsLocator.getDynObjectManager().get(subtype) == null) {
232
                                throw new IllegalArgumentException("DynClass '" + subtype
233
                                                + "' does not exist.");
234
                        }
235
                        this.elementsType.setSubtype(subtype);
236
                } else if (subtype != null
237
                                && this.dataType.getType() == DataTypes.DYNOBJECT) {
238
                        if (ToolsLocator.getDynObjectManager().get(subtype) == null) {
239
                                throw new IllegalArgumentException("DynClass '" + subtype
240
                                                + "' does not exist.");
241
                        }
242
                }
243
                return this;
244
        }
245

    
246
        public String getSubtype() {
247
                return subtype;
248
        }
249

    
250
        public DynField setDefaultDynValue(Object defaultValue) {
251
                this.defaultValue = defaultValue;
252
                return this;
253
        }
254

    
255
        public Object getDefaultValue() {
256
                return defaultValue;
257
        }
258

    
259
        public DynField setAvailableValues(DynObjectValueItem[] availableValues) {
260
                // If type is a list then the available values should be at the elements
261
                // type, not here.
262
                if (this.getType() == DataTypes.LIST) {
263
                        if (this.getElementsType() != null) {
264
                                this.getElementsType().setAvailableValues(availableValues);
265
                                return this;
266
                        }
267
                }
268
                if (availableValues == null || availableValues.length == 0) {
269
                        this.availableValues = null;
270
                } else {
271
                        this.availableValues = availableValues;
272
                }
273
                return this;
274
        }
275

    
276
        public DynField setAvailableValues(List availableValues) {
277
                // If type is a list then the available values should be at the elements
278
                // type, not here.
279
                if (this.getType() == DataTypes.LIST) {
280
                        if (this.getElementsType() != null) {
281
                                this.getElementsType().setAvailableValues(availableValues);
282
                                return this;
283
                        }
284
                }
285
                if (availableValues == null) {
286
                        this.availableValues = null;
287
                } else if (availableValues.isEmpty()) {
288
                        this.availableValues = null;
289
                } else {
290
                        this.availableValues = (DynObjectValueItem[]) availableValues
291
                                        .toArray(new DynObjectValueItem[availableValues.size()]);
292
                }
293
                return this;
294
        }
295

    
296
        public DynObjectValueItem[] getAvailableValues() {
297
                return availableValues;
298
        }
299

    
300
        public DynField setMinValue(Object minValue) {
301
                try {
302
                        this.minValue = this.coerce(minValue);
303
                } catch (CoercionException e) {
304
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
305
                        ex.initCause(e);
306
                        throw ex;
307
                }
308
                return this;
309
        }
310

    
311
        public Object getMinValue() {
312
                return minValue;
313
        }
314

    
315
        public DynField setMaxValue(Object maxValue) {
316
                try {
317
                        this.maxValue = this.coerce(maxValue);
318
                } catch (CoercionException e) {
319
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
320
                        ex.initCause(e);
321
                        throw ex;
322
                }
323
                return this;
324
        }
325

    
326
        public Object getMaxValue() {
327
                return maxValue;
328
        }
329

    
330
        public boolean isMandatory() {
331
                return this.mandatory;
332
        }
333

    
334
        public boolean isPersistent() {
335
                return this.persistent;
336
        }
337

    
338
        public DynField setMandatory(boolean mandatory) {
339
                this.mandatory = mandatory;
340
                return this;
341
        }
342

    
343
        public DynField setPersistent(boolean persistent) {
344
                this.persistent = persistent;
345
                return this;
346
        }
347

    
348
        public DynField setTheTypeOfAvailableValues(int type) {
349
                return this; // FIXME: this method is @deprecated
350
        }
351

    
352
        public int getTheTypeOfAvailableValues() {
353
                return 1; // FIXME: this method is @deprecated
354
        }
355

    
356
        public boolean equals(Object obj) {
357
                if (this == obj) {
358
                        return true;
359
                }
360
                if (obj instanceof DynField) {
361
                        // FIXME: No esta claro que esto sea correcto.
362
                        return name.equals(((DynField) obj).getName());
363
                }
364
                return false;
365
        }
366

    
367
        public Class getClassOfValue() {
368
                return theClass;
369
        }
370

    
371
        public DynField setValidateElements(boolean validate) {
372
                if (!this.dataType.isContainer()) {
373
                        throw new DynFieldIsNotAContainerException(this.name);
374
                }
375
                this.validateElements = validate;
376
                return this;
377
        }
378

    
379
        public boolean getValidateElements() {
380
                return this.validateElements;
381
        }
382

    
383
        public DynField setClassOfValue(Class theClass)
384
                        throws DynFieldIsNotAContainerException {
385
                this.theClass = theClass;
386
                return this;
387
        }
388

    
389
        public DynField setElementsType(int type)
390
                        throws DynFieldIsNotAContainerException {
391
                if (!isContainer()) {
392
                        throw new DynFieldIsNotAContainerException(this.name);
393
                }
394
                this.elementsType = new DefaultDynField(this.name + "-"
395
                                + this.dataType.getName() + "-item", type);
396
                return this;
397
        }
398

    
399
        public DynField setElementsType(DynStruct type)
400
                        throws DynFieldIsNotAContainerException {
401
                // Getter allows null values
402
                if (type != null) {
403
                        this.setElementsType(DataTypes.DYNOBJECT).getElementsType()
404
                                        .setSubtype(type.getFullName());
405
                }
406
                return this;
407
        }
408

    
409
        public boolean isContainer() {
410
                return this.dataType.isContainer();
411
        }
412

    
413
        public DynField getElementsType() {
414
                return this.elementsType;
415
        }
416

    
417
        public void validate(Object value) throws DynFieldValidateException {
418
                Comparable v;
419
                if (value == null) {
420
                        if (this.mandatory) {
421
                                throw new DynFieldRequiredValueException(this, value);
422
                        }
423
                        return;
424
                }
425

    
426
                switch (this.dataType.getType()) {
427
                case DataTypes.BOOLEAN:
428
                        if (!(value instanceof Boolean)) {
429
                                throw new DynFieldValidateException(value, this);
430
                        }
431
                        break;
432

    
433
                case DataTypes.DOUBLE:
434
                        if (!(value instanceof Double)) {
435
                                throw new DynFieldValidateException(value, this);
436
                        }
437
                        break;
438

    
439
                case DataTypes.FLOAT:
440
                        if (!(value instanceof Float)) {
441
                                throw new DynFieldValidateException(value, this);
442
                        }
443
                        break;
444

    
445
                case DataTypes.BYTE:
446
                        if (!(value instanceof Byte)) {
447
                                throw new DynFieldValidateException(value, this);
448
                        }
449
                        break;
450
                        
451
                case DataTypes.INT:
452
                        if (!(value instanceof Integer)) {
453
                                throw new DynFieldValidateException(value, this);
454
                        }
455
                        break;
456

    
457
                case DataTypes.LONG:
458
                        if (!(value instanceof Long)) {
459
                                throw new DynFieldValidateException(value, this);
460
                        }
461
                        break;
462

    
463
                case DataTypes.STRING:
464
                        if (!(value instanceof String)) {
465
                                throw new DynFieldValidateException(value, this);
466
                        }
467
                        break;
468

    
469
                case DataTypes.CHAR:
470
                        if (!(value instanceof String)) {
471
                                throw new DynFieldValidateException(value, this);
472
                        }
473
                        if( ((String)value).length()>1 ) {
474
                                throw new DynFieldValidateException(value, this);
475
                        }
476
                        break;
477

    
478
                case DataTypes.DATE:
479
                        if (!(value instanceof Date)) {
480
                                throw new DynFieldValidateException(value, this);
481
                        }
482
                        break;
483

    
484
                case DataTypes.TIMESTAMP:
485
                        if (!(value instanceof Date)) {
486
                                throw new DynFieldValidateException(value, this);
487
                        }
488
                        break;
489

    
490
                case DataTypes.TIME:
491
                        if (!(value instanceof Date)) {
492
                                throw new DynFieldValidateException(value, this);
493
                        }
494
                        break;
495

    
496
                case DataTypes.LIST:
497
                        if (!(value instanceof List)) {
498
                                throw new DynFieldValidateException(value, this);
499
                        }
500
                        if (this.validateElements && this.elementsType != null) {
501
                                Iterator it = ((List) value).iterator();
502
                                while (it.hasNext()) {
503
                                        this.elementsType.validate(it.next());
504
                                }
505
                        }
506
                        break;
507

    
508
                case DataTypes.MAP:
509
                        if (!(value instanceof Map)) {
510
                                throw new DynFieldValidateException(value, this);
511
                        }
512
                        break;
513
                case DataTypes.FILE:
514
                        if (!(value instanceof File)) {
515
                                throw new DynFieldValidateException(value, this);
516
                        }
517
                        break;
518
                case DataTypes.FOLDER:
519
                        if (!(value instanceof File)) {
520
                                throw new DynFieldValidateException(value, this);
521
                        }
522
                        break;
523
                case DataTypes.URI:
524
                        if (!(value instanceof URI)) {
525
                                throw new DynFieldValidateException(value, this);
526
                        }
527
                        break;
528
                case DataTypes.URL:
529
                        if (!(value instanceof URL)) {
530
                                throw new DynFieldValidateException(value, this);
531
                        }
532
                        break;
533
                case DataTypes.SET:
534
                        if (!(value instanceof Set)) {
535
                                throw new DynFieldValidateException(value, this);
536
                        }
537
                        break;
538

    
539
                case DataTypes.DYNOBJECT:
540
                        if (!(value instanceof DynObject)) {
541
                                throw new DynFieldValidateException(value, this);
542
                        }
543
                        DynClass dynClass = ToolsLocator.getDynObjectManager().get(
544
                                        this.getSubtype());
545
                        if (dynClass == null || !dynClass.isInstance((DynObject) value)) {
546
                                throw new DynFieldValidateException(value, this);
547
                        }
548
                        try {
549
                                dynClass.validate((DynObject) value);
550
                        } catch (DynObjectValidateException e) {
551
                                throw new DynFieldValidateException(value, this, e);
552
                        }
553
                        break;
554

    
555
                case DataTypes.ARRAY:
556
                        // TODO: falta verificar que es un array del tipo que toca.
557
                        break;
558

    
559
                default:
560
                        if (this.dataType.isObject()) {
561
                                if (this.theClass != null) {
562
                                        if (!this.theClass.isInstance(value)) {
563
                                                throw new DynFieldValidateException(value, this);
564
                                        }
565
                                }
566
                        } else {
567
                                if( this.dataType.getClass()==null && ! this.dataType.getClass().isInstance(value) ) {
568
                                        throw new DynFieldValidateException(value, this);
569
                                }
570
                        }
571
                }
572

    
573
                if (this.getAvailableValues() != null) {
574
                        if (!(value instanceof Comparable)) {
575
                                throw new DynFieldValidateException(value, this);
576
                        }
577
                        v = (Comparable) value;
578
                        boolean ok = false;
579
                        for (int i = 0; i < this.availableValues.length; i++) {
580
                                if (v.compareTo(this.availableValues[i].getValue()) == 0) {
581
                                        ok = true;
582
                                        break;
583
                                }
584
                        }
585
                        if (!ok) {
586
                                throw new DynFieldValidateException(value, this);
587
                        }
588
                } else if (this.getMaxValue() != null && this.getMinValue() != null) {
589
                        if (!(value instanceof Comparable)) {
590
                                throw new DynFieldValidateException(value, this);
591
                        }
592
                        v = (Comparable) value;
593
                        if (v.compareTo(this.minValue) < 0
594
                                        || v.compareTo(this.maxValue) > 0) {
595
                                throw new DynFieldValidateException(value, this);
596
                        }
597
                }
598
                //
599
                // This shouldn't be necessary since any assignment passes through the
600
                // coerce function anyway
601
                //
602
                // //if all the above is correct, then we should check that coercing is
603
                // possible
604
                // try {
605
                // coerce(value);
606
                // } catch (CoercionException e) {
607
                // throw new DynFieldValidateException(value, this);
608
                // }
609

    
610
        }
611

    
612
        public Object coerce(Object value) throws CoercionException {
613
                if (value == null) {
614
                        return value; // O debe devolver this.defaultValue
615
                }
616
                return this.dataType.coerce(value);
617
        }
618

    
619
        public String getGroup() {
620
                return this.groupName;
621
        }
622

    
623
        public DynField setGroup(String groupName) {
624
                this.groupName = groupName;
625
                return this;
626
        }
627

    
628
        public int getOder() {
629
                return this.order;
630
        }
631

    
632
        public DynField setOrder(int order) {
633
                this.order = order;
634
                return this;
635
        }
636

    
637
        public boolean isHidden() {
638
                return this.hidden;
639
        }
640

    
641
        public DynField setHidden(boolean hidden) {
642
                this.hidden = hidden;
643
                return this;
644
        }
645

    
646
        public boolean isReadOnly() {
647
                return this.isReadOnly;
648
        }
649

    
650
        public DynField setReadOnly(boolean isReadOnly) {
651
                this.isReadOnly = isReadOnly;
652
                return this;
653
        }
654

    
655
        public Class getClassOfItems() {
656
                return this.theClassOfItems;
657
        }
658

    
659
        public DynField setDefaultFieldValue(Object defaultValue) {
660
                try {
661
                        this.defaultValue = this.coerce(defaultValue);
662
                } catch (CoercionException e) {
663
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
664
                        ex.initCause(e);
665
                        throw ex;
666
                }
667
                return this;
668
        }
669

    
670
        public DynField setClassOfItems(Class theClass)
671
                        throws DynFieldIsNotAContainerException {
672
                // Getter allows null values
673
                if (theClass == null) {
674
                        return this;
675
                }
676
                if (!this.dataType.isContainer()) {
677
                        throw new DynFieldIsNotAContainerException(this.name);
678
                }
679
                this.theClassOfItems = theClass;
680
                return this;
681
        }
682

    
683
}