Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / dynobject / impl / DefaultDynClass.java @ 112

History | View | Annotate | Download (15.2 KB)

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

    
3
import java.util.Collection;
4
import java.util.HashMap;
5
import java.util.Iterator;
6
import java.util.LinkedHashMap;
7
import java.util.LinkedHashSet;
8
import java.util.Map;
9
import java.util.Set;
10

    
11
import org.gvsig.tools.dataTypes.DataTypes;
12
import org.gvsig.tools.dynobject.DynClass;
13
import org.gvsig.tools.dynobject.DynField;
14
import org.gvsig.tools.dynobject.DynMethod;
15
import org.gvsig.tools.dynobject.DynObject;
16
import org.gvsig.tools.dynobject.DynObjectManager;
17
import org.gvsig.tools.dynobject.DynObjectValueItem;
18
import org.gvsig.tools.dynobject.DynStruct;
19
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
20
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
21
import org.gvsig.tools.dynobject.exception.DynMethodException;
22
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
23

    
24
public class DefaultDynClass implements DynClass {
25

    
26
        public class FieldAndIndex {
27
                DefaultDynField field;
28
                int index;
29

    
30
                FieldAndIndex(DynField field, int index) {
31
                        this.field = (DefaultDynField) field;
32
                        this.index = index;
33
                }
34
                public int getIndex() {
35
                        return this.index;
36
                }
37
                public DefaultDynField getDynField() {
38
                        return this.field;
39
                }
40
        }
41

    
42
        public class MethodAndIndex {
43
                DynMethod method;
44
                int index;
45

    
46
                MethodAndIndex(DynMethod method, int index) {
47
                        this.method = method;
48
                        this.index = index;
49
                }
50
                public int getIndex() {
51
                        return this.index;
52
                }
53
                public DynMethod getDynMethod() {
54
                        return this.method;
55
                }
56
        }
57

    
58
    DynObjectManager manager;
59

    
60
    private String name;
61
    private String description;
62

    
63
    private boolean isAnonymous;
64

    
65
    private Map classes;
66
    private Map declaredFieldsMap;
67
    private Map declaredMethodsMap;
68

    
69
    // This attributes are calculated by consolide method
70
    private DefaultDynClass[] superClasses;
71
        private Map superClassesMap;
72
    private DynField[] declaredFields;
73
        private Map fieldsMap;
74
        private DynField[] fields;
75
    private DynMethod[] declaredMethods;
76
        private Map methodsMap;
77
        private DynMethod[] methods;
78
        private String namespace;
79

    
80
        public DefaultDynClass(DynObjectManager manager, String name, String description) {
81
                this(manager, null, name, description);
82
        }
83

    
84
    public DefaultDynClass(DynObjectManager manager, String namespace, String name, String description) {
85
            this.isAnonymous = false;
86
            this.classes = new LinkedHashMap();
87
            this.declaredFieldsMap = new HashMap();
88
            this.declaredMethodsMap = new HashMap();
89

    
90
            this.forceConsolide();
91

    
92
            this.manager = manager;
93
            this.namespace = namespace;
94
            this.name = name;
95
            this.description = description;
96
    }
97

    
98
    public String getNamespace() {
99
            return this.namespace;
100
    }
101
    
102
    public String getFullName() {
103
            if( this.namespace == null ) {
104
                    return this.name;
105
            }
106
            return this.namespace + ":" + this.name;
107
    }
108
    
109
    public String toString() {
110
            StringBuffer buffer = new StringBuffer();
111
            
112
            buffer.append("DynClass").append("[").append(this.hashCode()).append("]").append("( ")
113
                    .append("name='").append(this.getFullName()).append("', ")
114
                    .append("fields='").append(this.declaredFieldsMap.toString())
115
                    .append(" )");
116
            return buffer.toString();
117
    }
118
    
119
    public DefaultDynClass(DynObjectManager manager, String name, String description, DynClass[] superClases) {
120
            this(manager,name,description);
121
            for( int i=0; i<superClases.length; i++ ) {
122
                    DynClass dynClass = superClases[i];
123
                    if( ! this.classes.containsKey(dynClass.getName()) ) {
124
                            this.classes.put(dynClass.getName(), dynClass);
125
                    }
126
            }
127
    }
128

    
129
           public DynObjectManager getManager() {
130
            return this.manager;
131
    }
132

    
133
    public void consolide() {
134
            // Use classes and decalredFieldsMap to update all.
135

    
136
            // Actualize superClasses array
137
            this.superClasses = (DefaultDynClass[]) buildSuperDynClassSet()
138
                                .toArray(new DefaultDynClass[] {});
139

    
140
            // Actualize declaredFields array
141
            this.declaredFields = (DynField[]) this.declaredFieldsMap.values()
142
                .toArray(new DynField[] {});
143

    
144
            // Actualize declaredMethods array
145
            this.declaredMethods = (DynMethod[]) this.declaredMethodsMap.values()
146
                .toArray(new DynMethod[] {});
147

    
148
            // Actualize fieldsMap
149
            this.fieldsMap = new LinkedHashMap();
150
            int index = 0;
151
            for( int i=0; i<this.declaredFields.length; i++) {
152
                    this.fieldsMap.put(this.declaredFields[i].getName(), new FieldAndIndex(this.declaredFields[i],index++));
153
            }
154
            for( int i=0; i<this.superClasses.length ; i++ ) {
155
                Iterator it = this.superClasses[i].declaredFieldsMap.values().iterator();
156
                while( it.hasNext() ) {
157
                        DynField field = (DynField) it.next();
158
                            if( !this.fieldsMap.containsKey(field.getName()) ) {
159
                                    this.fieldsMap.put(field.getName(), new FieldAndIndex(field,index++));
160
                            }
161
                }
162
            }
163

    
164
            // Actualize methodsMap
165
            this.methodsMap = new LinkedHashMap();
166
            index = 0;
167
            for( int i=0; i<this.declaredMethods.length; i++) {
168
                    this.methodsMap.put(this.declaredMethods[i].getName(), new MethodAndIndex(this.declaredMethods[i],index++));
169
            }
170
            for( int i=0; i<this.superClasses.length ; i++ ) {
171
                Iterator it = this.superClasses[i].declaredMethodsMap.values().iterator();
172
                while( it.hasNext() ) {
173
                        DynMethod method = (DynMethod) it.next();
174
                            if( !this.methodsMap.containsKey(method.getName()) ) {
175
                                    this.methodsMap.put(method.getName(), new MethodAndIndex(method,index++));
176
                            }
177
                }
178
            }
179

    
180

    
181
                // Actualize fields array
182
                this.fields = new DynField[ this.fieldsMap.size() ];
183
                int i=0;
184
                Iterator it = this.fieldsMap.values().iterator();
185
                while( it.hasNext() ) {
186
                    FieldAndIndex findex = (FieldAndIndex) it.next();
187
            DynField field = findex.getDynField();
188
                        fields[i++] = field;
189
                }
190

    
191
                // Actualize methods array
192
                this.methods = new DynMethod[ this.methodsMap.size() ];
193
                i=0;
194
                it = this.methodsMap.values().iterator();
195
                while( it.hasNext() ) {
196
                    MethodAndIndex mindex = (MethodAndIndex) it.next();
197
            DynMethod method = mindex.getDynMethod();
198
                        methods[i++] = method;
199
                }
200

    
201
                // Actualize superClassesMap
202
                this.superClassesMap = new HashMap();
203
                for( i=0 ; i<this.superClasses.length ; i++) {
204
                        this.superClassesMap.put(this.superClasses[i].getName(), this.superClasses[i]);
205
                }
206
    }
207

    
208
    private void forceConsolide() {
209
        this.superClasses = null;
210
        this.superClassesMap = null;
211
        this.declaredFields = null;
212
        this.fieldsMap = null;
213
        this.fields = null;
214
        this.declaredMethods = null;
215
        this.methodsMap = null;
216
        this.methods = null;
217
    }
218

    
219
    private Set buildSuperDynClassSet() {
220
        Set dynClassParents = new LinkedHashSet();
221
        buildSuperDynClassList(this, dynClassParents);
222
        return dynClassParents;
223
    }
224

    
225
    private void buildSuperDynClassList(DefaultDynClass dynClass, Set allParents) {
226
            Collection values = dynClass.classes.values();
227
        Iterator it = values.iterator();
228
        while( it.hasNext() ) {
229
                DynClass dc = (DynClass) it.next();
230
                allParents.add(dc);
231
        }
232
        it = values.iterator();
233
        while( it.hasNext() ) {
234
                DefaultDynClass dc = (DefaultDynClass) it.next();
235
                buildSuperDynClassList(dc, allParents);
236
        }
237
    }
238

    
239
    public Object[] createValues(Object[] oldvalues) {
240
            if( this.fields == null ) {
241
                    consolide();
242
            }
243
            if (oldvalues != null && oldvalues.length >= this.fields.length) {
244
                    return oldvalues;
245
            }
246
            Object[] extended = new Object[ this.fields.length ];
247
            if( oldvalues != null ) {
248
                    System.arraycopy(oldvalues, 0, extended, 0, oldvalues.length);
249
            }
250
            return extended;
251
    }
252

    
253
        public void extend(DynStruct dynStruct) {
254
                if( this.classes.containsKey(dynStruct.getName()) ) {
255
                        return;
256
                }
257
                this.classes.put(dynStruct.getName(), dynStruct);
258
                this.forceConsolide();
259
        }
260

    
261
        public void extend(String structame) {
262
                DynClass dynClass = manager.get(structame);
263
                extend(dynClass);
264
        }
265

    
266
    public int getFieldIndex(String name) {
267
            if( this.fieldsMap == null ) {
268
                    consolide();
269
            }
270
            FieldAndIndex f = (FieldAndIndex) this.fieldsMap.get(name);
271
            if( f == null ) {
272
                    return -1;
273
            }
274
            return f.index;
275
    }
276

    
277
        public DynField getDeclaredDynField(String name) {
278
                return (DynField)this.declaredFieldsMap.get(name);
279
        }
280

    
281
        public DynField[] getDeclaredDynFields() {
282
                return this.declaredFields;
283
        }
284

    
285
        public String getDescription() {
286
                return this.description;
287
        }
288

    
289
        public DynField getDynField(String name) {
290
            if( this.fieldsMap == null ) {
291
                    consolide();
292
            }
293
            FieldAndIndex findex = (FieldAndIndex) fieldsMap.get(name);
294
        return findex == null ? null : findex.getDynField();
295
        }
296

    
297
        public FieldAndIndex getDynFieldAndIndex(String name) {
298
            if( this.fieldsMap == null ) {
299
                    consolide();
300
            }
301
                return (FieldAndIndex) this.fieldsMap.get(name);
302
        }
303

    
304
        public DynField[] getDynFields() {
305
            if( this.fields == null ) {
306
                    consolide();
307
            }
308
                return this.fields;
309
        }
310

    
311
        public String getName() {
312
                return this.name;
313
        }
314

    
315
        public DynField addDynField(String name) {
316
                DynField field = new DefaultDynField(name);
317
                return this.addDynField(field);
318
        }
319
        
320
        public DynField addDynField(DynField field) {
321
                declaredFieldsMap.put(field.getName(), field);
322
                this.forceConsolide();
323
                return field;
324
        }
325

    
326
        public DynClass[] getSuperDynClasses() {
327
            if( this.superClasses == null ) {
328
                    consolide();
329
            }
330
                return this.superClasses;
331
        }
332

    
333
        public DynStruct[] getSuperDynStructs() {
334
                return this.getSuperDynClasses();
335
        }
336
        
337
        public DynObject newInstance() {
338
                return this.manager.createDynObject(this);
339
        }
340

    
341
        public boolean isInstance(DynObject dynObject) {
342
            if( this.superClassesMap == null ) {
343
                    consolide();
344
            }
345
                DefaultDynClass objClass = (DefaultDynClass) dynObject.getDynClass();
346
                if( this.superClassesMap.containsKey(objClass.getName()) ) {
347
                        return true;
348
                }
349
                if(objClass.isAnonymous ) {
350
                        Iterator it = objClass.classes.values().iterator();
351
                        while( it.hasNext() ) {
352
                                DynClass dc = (DynClass) it.next();
353
                                if( this.superClassesMap.containsKey(dc.getName()) ) {
354
                                        return true;
355
                                }
356
                        }
357
                }
358
                return false;
359
        }
360

    
361
        public void removeDynField(String name) {
362
                this.declaredFieldsMap.remove(name);
363
                this.forceConsolide();
364
        }
365

    
366
        public void setAnonymous(boolean isAnonymous) {
367
                this.isAnonymous = isAnonymous;
368
        }
369

    
370
        public boolean isAnonymous() {
371
                return isAnonymous;
372
        }
373

    
374
        public int hashCode() {
375
        return name.hashCode();
376
    }
377

    
378
    public boolean equals(Object obj) {
379
        if (this == obj) {
380
            return true;
381
        }
382
        if (obj instanceof DynClass) {
383
            return name.equals(((DynClass) obj).getName());
384
        }
385
        return false;
386
    }
387

    
388
        public void addDynMethod(DynMethod dynMethod) {
389
                this.manager.registerDynMethod(this, dynMethod);
390
        }
391

    
392
        void addMethod(DynMethod dynMethod) {
393
                declaredMethodsMap.put(dynMethod.getName(), dynMethod);
394
                this.forceConsolide();
395
        }
396

    
397
        public DynMethod getDeclaredDynMethod(String name) {
398
                return (DynMethod)this.declaredMethodsMap.get(name);
399
        }
400

    
401
        public DynMethod[] getDeclaredDynMethods() {
402
            if (this.declaredMethods == null) {
403
                        consolide();
404
                }
405
                return this.declaredMethods;
406
        }
407

    
408
        public DynMethod getDynMethod(String name) throws DynMethodException {
409
            if( this.methodsMap == null ) {
410
                    consolide();
411
            }
412
            MethodAndIndex mindex = (MethodAndIndex) methodsMap.get(name);
413
        return mindex == null ? null : mindex.getDynMethod();
414
        }
415

    
416
        public DynMethod getDynMethod(int code) throws DynMethodException {
417
                return this.manager.getDynMethod(code);
418
        }
419

    
420
        public DynMethod[] getDynMethods() {
421
            if( this.methods == null ) {
422
                    consolide();
423
            }
424
                return this.methods;
425
        }
426

    
427
        public void removeDynMethod(String name) {
428
                // TODO Auto-generated method stub
429

    
430
        }
431

    
432
        public void validate(DynObject object) throws DynObjectValidateException {
433
                DynField fields[] = this.getDynFields();
434
                DynObjectValidateException exceptions = new DynObjectValidateException(this.getName());
435
                for( int i=0; i<fields.length; i++) {
436
                        DynField field = fields[i];
437
                        try {
438
                                field.validate( object.getDynValue( field.getName() ));
439
                        } catch (DynFieldValidateException e) {
440
                                exceptions.add(e);
441
                        } catch (DynFieldNotFoundException e) {
442
                                exceptions.add(e);
443
                        }                        
444
                }
445
                if( exceptions.size()>0 ) {
446
                        throw exceptions;
447
                }
448
        }
449
        
450
//        private DynField addDynFieldSingle(String name) {
451
//                return addDynField(name).setTheTypeOfAvailableValues(DynField.ANY);
452
//        }
453

    
454
        public DynField addDynFieldString(String name) {
455
                return addDynField(name).setType(DataTypes.STRING);
456
        }
457

    
458
        public DynField addDynFieldDate(String name) {
459
                return addDynField(name).setType(DataTypes.DATE);
460
        }
461

    
462
        public DynField addDynFieldInt(String name) {
463
                return addDynField(name).setType(DataTypes.INT);
464
        }
465

    
466
        public DynField addDynFieldLong(String name) {
467
                return addDynField(name).setType(DataTypes.LONG);
468
        }
469

    
470
        public DynField addDynFieldDouble(String name) {
471
                return addDynField(name).setType(DataTypes.DOUBLE);
472
        }
473
        
474
        public DynField addDynFieldFloat(String name) {
475
                return addDynField(name).setType(DataTypes.FLOAT);
476
        }
477

    
478
        public DynField addDynFieldBoolean(String name) {
479
                return addDynField(name).setType(DataTypes.BOOLEAN);
480
        }
481

    
482
        public DynField addDynFieldObject(String name) {
483
                return addDynField(name).setType(DataTypes.OBJECT);
484
        }
485

    
486
        public DynField addDynFieldArray(String name) {
487
                return addDynField(name).setType(DataTypes.ARRAY);
488
        }
489

    
490
        public DynField addDynFieldList(String name) {
491
                return addDynField(name).setType(DataTypes.LIST);
492
        }
493

    
494
        public DynField addDynFieldMap(String name) {
495
                return addDynField(name).setType(DataTypes.MAP);
496
        }
497

    
498
        public DynField addDynFieldSet(String name) {
499
                return addDynField(name).setType(DataTypes.SET);
500
        }
501

    
502
        public DynField addDynFieldChoice(String name, int type,
503
                        Object defaultValue, DynObjectValueItem[] values) {
504
                return addDynFieldChoice(name, type, defaultValue, values, false, true);
505
        }
506

    
507
        public DynField addDynFieldChoice(String name, int type,
508
                        Object defaultValue, DynObjectValueItem[] values,
509
                        boolean mandatory, boolean persistent) {
510
                return addDynField(name)
511
                                .setType(type)
512
                                .setDefaultDynValue(defaultValue)
513
                                .setMandatory(mandatory)
514
                                .setPersistent(persistent)
515
                                .setAvailableValues(values)
516
                                .setDescription(description);
517
        }
518

    
519
        public DynField addDynFieldRange(String name, int type,
520
                        Object defaultValue, Object min, Object max) {
521
                return addDynFieldRange(name, type, defaultValue, min, max, false, true);
522
        }
523

    
524
        public DynField addDynFieldRange(String name, int type,
525
                        Object defaultValue, Object min, Object max, boolean mandatory,
526
                        boolean persistent) {
527
                return addDynField(name)
528
                                .setType(type)
529
                                .setDefaultDynValue(defaultValue)
530
                                .setMandatory(mandatory)
531
                                .setPersistent(persistent)
532
                                .setMinValue(min)
533
                                .setMaxValue(max);
534
        }
535

    
536
        public DynField addDynFieldSingle(String name, int type, Object defaultValue) {
537
                return addDynFieldSingle(name, type, defaultValue, false, true);
538
        }
539

    
540
        public DynField addDynFieldSingle(String name, int type,
541
                        Object defaultValue, boolean mandatory, boolean persistent) {
542
                return addDynField(name)
543
                                .setType(type)
544
                                .setDefaultDynValue(defaultValue)
545
                                .setMandatory(mandatory)
546
                                .setPersistent(persistent);
547
        }
548

    
549
        public void setDescription(String description) {
550
                this.description = description;
551
        }
552

    
553
        public void setNamespace(String namespace) {
554
                this.namespace = namespace;
555
        }
556

    
557
}