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

History | View | Annotate | Download (16.7 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.INT:
445
                        if (!(value instanceof Integer)) {
446
                                throw new DynFieldValidateException(value, this);
447
                        }
448
                        break;
449

    
450
                case DataTypes.LONG:
451
                        if (!(value instanceof Long)) {
452
                                throw new DynFieldValidateException(value, this);
453
                        }
454
                        break;
455

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

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

    
468
                case DataTypes.LIST:
469
                        if (!(value instanceof List)) {
470
                                throw new DynFieldValidateException(value, this);
471
                        }
472
                        if (this.validateElements && this.elementsType != null) {
473
                                Iterator it = ((List) value).iterator();
474
                                while (it.hasNext()) {
475
                                        this.elementsType.validate(it.next());
476
                                }
477
                        }
478
                        break;
479

    
480
                case DataTypes.MAP:
481
                        if (!(value instanceof Map)) {
482
                                throw new DynFieldValidateException(value, this);
483
                        }
484
                        break;
485
                case DataTypes.FILE:
486
                        if (!(value instanceof File)) {
487
                                throw new DynFieldValidateException(value, this);
488
                        }
489
                        break;
490
                case DataTypes.FOLDER:
491
                        if (!(value instanceof File)) {
492
                                throw new DynFieldValidateException(value, this);
493
                        }
494
                        break;
495
                case DataTypes.URI:
496
                        if (!(value instanceof URI)) {
497
                                throw new DynFieldValidateException(value, this);
498
                        }
499
                        break;
500
                case DataTypes.URL:
501
                        if (!(value instanceof URL)) {
502
                                throw new DynFieldValidateException(value, this);
503
                        }
504
                        break;
505
                case DataTypes.SET:
506
                        if (!(value instanceof Set)) {
507
                                throw new DynFieldValidateException(value, this);
508
                        }
509
                        break;
510

    
511
                case DataTypes.DYNOBJECT:
512
                        if (!(value instanceof DynObject)) {
513
                                throw new DynFieldValidateException(value, this);
514
                        }
515
                        DynClass dynClass = ToolsLocator.getDynObjectManager().get(
516
                                        this.getSubtype());
517
                        if (dynClass == null || !dynClass.isInstance((DynObject) value)) {
518
                                throw new DynFieldValidateException(value, this);
519
                        }
520
                        try {
521
                                dynClass.validate((DynObject) value);
522
                        } catch (DynObjectValidateException e) {
523
                                throw new DynFieldValidateException(value, this, e);
524
                        }
525
                        break;
526

    
527
                case DataTypes.ARRAY:
528
                        // TODO: falta verificar que es un array del tipo que toca.
529
                        break;
530

    
531
                default:
532
                        if (this.dataType.isObject()) {
533
                                if (this.theClass != null) {
534
                                        if (!this.theClass.isInstance(value)) {
535
                                                throw new DynFieldValidateException(value, this);
536
                                        }
537
                                }
538
                        } else {
539
                                throw new DynFieldValidateException(value, this);
540
                        }
541
                }
542

    
543
                if (this.getAvailableValues() != null) {
544
                        if (!(value instanceof Comparable)) {
545
                                throw new DynFieldValidateException(value, this);
546
                        }
547
                        v = (Comparable) value;
548
                        boolean ok = false;
549
                        for (int i = 0; i < this.availableValues.length; i++) {
550
                                if (v.compareTo(this.availableValues[i].getValue()) == 0) {
551
                                        ok = true;
552
                                        break;
553
                                }
554
                        }
555
                        if (!ok) {
556
                                throw new DynFieldValidateException(value, this);
557
                        }
558
                } else if (this.getMaxValue() != null && this.getMinValue() != null) {
559
                        if (!(value instanceof Comparable)) {
560
                                throw new DynFieldValidateException(value, this);
561
                        }
562
                        v = (Comparable) value;
563
                        if (v.compareTo(this.minValue) < 0
564
                                        || v.compareTo(this.maxValue) > 0) {
565
                                throw new DynFieldValidateException(value, this);
566
                        }
567
                }
568
                //
569
                // This shouldn't be necessary since any assignment passes through the
570
                // coerce function anyway
571
                //
572
                // //if all the above is correct, then we should check that coercing is
573
                // possible
574
                // try {
575
                // coerce(value);
576
                // } catch (CoercionException e) {
577
                // throw new DynFieldValidateException(value, this);
578
                // }
579

    
580
        }
581

    
582
        public Object coerce(Object value) throws CoercionException {
583
                if (value == null) {
584
                        return value; // O debe devolver this.defaultValue
585
                }
586
                return this.dataType.coerce(value);
587
        }
588

    
589
        public String getGroup() {
590
                return this.groupName;
591
        }
592

    
593
        public DynField setGroup(String groupName) {
594
                this.groupName = groupName;
595
                return this;
596
        }
597

    
598
        public int getOder() {
599
                return this.order;
600
        }
601

    
602
        public DynField setOrder(int order) {
603
                this.order = order;
604
                return this;
605
        }
606

    
607
        public boolean isHidden() {
608
                return this.hidden;
609
        }
610

    
611
        public DynField setHidden(boolean hidden) {
612
                this.hidden = hidden;
613
                return this;
614
        }
615

    
616
        public boolean isReadOnly() {
617
                return this.isReadOnly;
618
        }
619

    
620
        public DynField setReadOnly(boolean isReadOnly) {
621
                this.isReadOnly = isReadOnly;
622
                return this;
623
        }
624

    
625
        public Class getClassOfItems() {
626
                return this.theClassOfItems;
627
        }
628

    
629
        public DynField setDefaultFieldValue(Object defaultValue) {
630
                try {
631
                        this.defaultValue = this.coerce(defaultValue);
632
                } catch (CoercionException e) {
633
                        IllegalArgumentException ex = new IllegalArgumentException(e.getLocalizedMessage());
634
                        ex.initCause(e);
635
                        throw ex;
636
                }
637
                return this;
638
        }
639

    
640
        public DynField setClassOfItems(Class theClass)
641
                        throws DynFieldIsNotAContainerException {
642
                // Getter allows null values
643
                if (theClass == null) {
644
                        return this;
645
                }
646
                if (!this.dataType.isContainer()) {
647
                        throw new DynFieldIsNotAContainerException(this.name);
648
                }
649
                this.theClassOfItems = theClass;
650
                return this;
651
        }
652

    
653
}