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

History | View | Annotate | Download (17.4 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.DynObject;
43
import org.gvsig.tools.dynobject.DynObjectException;
44
import org.gvsig.tools.dynobject.DynObjectValueItem;
45
import org.gvsig.tools.dynobject.DynStruct;
46
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
47
import org.gvsig.tools.dynobject.exception.DynFieldRequiredValueException;
48
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
49
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
50
import org.gvsig.tools.exception.ListBaseException;
51

    
52
public class DefaultDynField implements DynField {
53
        private String name;
54
        private String description;
55

    
56
        private DataType dataType;
57
        private String subtype;
58

    
59
        private Object defaultValue;
60

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

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

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

    
88
        public static class CheckDynFieldListException extends ListBaseException {
89

    
90
                public static class CheckDynFieldException extends DynObjectException {
91

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
609
        }
610

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

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

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

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

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

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

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

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

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

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

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

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

    
682
}