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

History | View | Annotate | Download (25.1 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.util.Collection;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.LinkedHashMap;
30
import java.util.LinkedHashSet;
31
import java.util.Map;
32
import java.util.Set;
33

    
34
import org.gvsig.tools.ToolsLocator;
35
import org.gvsig.tools.dataTypes.DataTypes;
36
import org.gvsig.tools.dataTypes.DataTypesManager;
37
import org.gvsig.tools.dynobject.DynClass;
38
import org.gvsig.tools.dynobject.DynClassName;
39
import org.gvsig.tools.dynobject.DynField;
40
import org.gvsig.tools.dynobject.DynMethod;
41
import org.gvsig.tools.dynobject.DynObject;
42
import org.gvsig.tools.dynobject.DynObjectException;
43
import org.gvsig.tools.dynobject.DynObjectManager;
44
import org.gvsig.tools.dynobject.DynObjectValueItem;
45
import org.gvsig.tools.dynobject.DynStruct;
46
import org.gvsig.tools.dynobject.exception.DynClassNotFoundException;
47
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
48
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
49
import org.gvsig.tools.dynobject.exception.DynMethodException;
50
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
51
import org.gvsig.tools.exception.ListBaseException;
52

    
53
public class DefaultDynClass implements DynClass {
54

    
55
    public class FieldAndIndex {
56

    
57
        DefaultDynField field;
58
        int index;
59

    
60
        FieldAndIndex(DynField field, int index) {
61
            this.field = (DefaultDynField) field;
62
            this.index = index;
63
        }
64

    
65
        public int getIndex() {
66
            return this.index;
67
        }
68

    
69
        public DefaultDynField getDynField() {
70
            return this.field;
71
        }
72
    }
73

    
74
    public class MethodAndIndex {
75

    
76
        DynMethod method;
77
        int index;
78

    
79
        MethodAndIndex(DynMethod method, int index) {
80
            this.method = method;
81
            this.index = index;
82
        }
83

    
84
        public int getIndex() {
85
            return this.index;
86
        }
87

    
88
        public DynMethod getDynMethod() {
89
            return this.method;
90
        }
91
    }
92

    
93
    DynObjectManager manager;
94

    
95
    private DynClassName name;
96
    private String description;
97

    
98
    private boolean isAnonymous;
99

    
100
    private Map classes;
101
    private Map declaredFieldsMap;
102
    private Map declaredMethodsMap;
103

    
104
    // This attributes are calculated by consolide method
105
    private DefaultDynClass[] superClasses;
106
    private Map superClassesMap;
107
    private DynField[] declaredFields;
108
    private Map fieldsMap;
109
    private DynField[] fields;
110
    private DynMethod[] declaredMethods;
111
    private Map methodsMap;
112
    private DynMethod[] methods;
113

    
114
    public DefaultDynClass(DynObjectManager manager, String name,
115
        String description) {
116
        this(manager, null, name, description);
117
    }
118

    
119
    public DefaultDynClass(DynObjectManager manager, String namespace,
120
        String name, String description) {
121
        this(manager, manager.createDynClassName(namespace, name), description);
122
    }
123

    
124
    public DefaultDynClass(DynObjectManager manager, DynClassName name,
125
        String description) {
126
        this.isAnonymous = false;
127
        this.classes = new LinkedHashMap();
128
        this.declaredFieldsMap = new HashMap();
129
        this.declaredMethodsMap = new HashMap();
130

    
131
        this.forceConsolide();
132

    
133
        this.manager = manager;
134
        this.name = name;
135
        this.description = description;
136
    }
137

    
138
    public String getName() {
139
        return this.name.getName();
140
    }
141

    
142
    public String getNamespace() {
143
        return this.name.getNamespace();
144
    }
145

    
146
    public String getFullName() {
147
        return this.name.getFullName();
148
    }
149

    
150
    public String toString() {
151
        StringBuffer buffer = new StringBuffer();
152

    
153
        buffer.append("DynClass").append("[").append(this.hashCode())
154
            .append("]").append("( ").append("name='")
155
            .append(this.getFullName()).append("', ").append("fields='")
156
            .append(this.declaredFieldsMap.toString()).append(" )");
157
        return buffer.toString();
158
    }
159

    
160
    public DefaultDynClass(DynObjectManager manager, String name,
161
        String description, DynClass[] superClases) {
162
        this(manager, name, description);
163
        for (int i = 0; i < superClases.length; i++) {
164
            DynClass dynClass = superClases[i];
165
            if (!this.classes.containsKey(dynClass.getFullName())) {
166
                this.classes.put(dynClass.getFullName(), dynClass);
167
            }
168
        }
169
    }
170

    
171
    public DynObjectManager getManager() {
172
        return this.manager;
173
    }
174

    
175
    public void consolide() {
176
        // Use classes and decalredFieldsMap to update all.
177

    
178
        // Updates superClasses array
179
        this.superClasses =
180
            (DefaultDynClass[]) buildSuperDynClassSet().toArray(
181
                new DefaultDynClass[] {});
182

    
183
        // Updates declaredFields array
184
        this.declaredFields =
185
            (DynField[]) this.declaredFieldsMap.values().toArray(
186
                new DynField[] {});
187

    
188
        // Updates declaredMethods array
189
        this.declaredMethods =
190
            (DynMethod[]) this.declaredMethodsMap.values().toArray(
191
                new DynMethod[] {});
192

    
193
        // Updates fieldsMap
194
        this.fieldsMap = new LinkedHashMap();
195
        int index = 0;
196
        for (int i = 0; i < this.declaredFields.length; i++) {
197
            this.fieldsMap.put(this.declaredFields[i].getName().toLowerCase(),
198
                new FieldAndIndex(this.declaredFields[i], index++));
199
        }
200
        for (int i = 0; i < this.superClasses.length; i++) {
201
            Iterator it =
202
                this.superClasses[i].declaredFieldsMap.values().iterator();
203
            while (it.hasNext()) {
204
                DynField field = (DynField) it.next();
205
                if (!this.fieldsMap.containsKey(field.getName().toLowerCase())) {
206
                    this.fieldsMap.put(field.getName().toLowerCase(),
207
                        new FieldAndIndex(field, index++));
208
                }
209
            }
210
        }
211

    
212
        // Updates methodsMap
213
        this.methodsMap = new LinkedHashMap();
214
        index = 0;
215
        for (int i = 0; i < this.declaredMethods.length; i++) {
216
            this.methodsMap.put(this.declaredMethods[i].getName(),
217
                new MethodAndIndex(this.declaredMethods[i], index++));
218
        }
219
        for (int i = 0; i < this.superClasses.length; i++) {
220
            Iterator it =
221
                this.superClasses[i].declaredMethodsMap.values().iterator();
222
            while (it.hasNext()) {
223
                DynMethod method = (DynMethod) it.next();
224
                if (!this.methodsMap.containsKey(method.getName())) {
225
                    this.methodsMap.put(method.getName(), new MethodAndIndex(
226
                        method, index++));
227
                }
228
            }
229
        }
230

    
231
        // Updates fields array
232
        this.fields = new DynField[this.fieldsMap.size()];
233
        int i = 0;
234
        Iterator it = this.fieldsMap.values().iterator();
235
        while (it.hasNext()) {
236
            FieldAndIndex findex = (FieldAndIndex) it.next();
237
            DynField field = findex.getDynField();
238
            fields[i++] = field;
239
        }
240

    
241
        // Updates methods array
242
        this.methods = new DynMethod[this.methodsMap.size()];
243
        i = 0;
244
        it = this.methodsMap.values().iterator();
245
        while (it.hasNext()) {
246
            MethodAndIndex mindex = (MethodAndIndex) it.next();
247
            DynMethod method = mindex.getDynMethod();
248
            methods[i++] = method;
249
        }
250

    
251
        // Updates superClassesMap
252
        this.superClassesMap = new HashMap();
253
        for (i = 0; i < this.superClasses.length; i++) {
254
            this.superClassesMap.put(this.superClasses[i].getFullName(),
255
                this.superClasses[i]);
256
        }
257
    }
258

    
259
    private void forceConsolide() {
260
        this.superClasses = null;
261
        this.superClassesMap = null;
262
        this.declaredFields = null;
263
        this.fieldsMap = null;
264
        this.fields = null;
265
        this.declaredMethods = null;
266
        this.methodsMap = null;
267
        this.methods = null;
268
    }
269

    
270
    private Set buildSuperDynClassSet() {
271
        Set dynClassParents = new LinkedHashSet();
272
        buildSuperDynClassList(this, dynClassParents);
273
        return dynClassParents;
274
    }
275

    
276
    private void buildSuperDynClassList(DefaultDynClass dynClass, Set allParents) {
277
        Collection values = dynClass.classes.values();
278
        Iterator it = values.iterator();
279
        while (it.hasNext()) {
280
            DynClass dc = (DynClass) it.next();
281
            allParents.add(dc);
282
        }
283
        it = values.iterator();
284
        while (it.hasNext()) {
285
            DefaultDynClass dc = (DefaultDynClass) it.next();
286
            buildSuperDynClassList(dc, allParents);
287
        }
288
    }
289

    
290
    // public Object[] createValues(Object[] oldvalues) {
291
    // if (this.fields == null) {
292
    // consolide();
293
    // }
294
    // if (oldvalues != null && oldvalues.length >= this.fields.length) {
295
    // return oldvalues;
296
    // }
297
    // Object[] extended = new Object[this.fields.length];
298
    // if (oldvalues != null) {
299
    // System.arraycopy(oldvalues, 0, extended, 0, oldvalues.length);
300
    // }
301
    // return extended;
302
    // }
303

    
304
    public Map createValues(Map oldValues) {
305
        if (this.fields == null) {
306
            consolide();
307
        }
308
        HashMap extended = new HashMap();
309
        if (oldValues != null) {
310
            extended.putAll(oldValues);
311
        }
312
        return extended;
313
    }
314

    
315
    public void extendAll(String[] structNames) {
316
        if (structNames == null)
317
            return;
318

    
319
        for (int i = 0; i < structNames.length; i++) {
320
            DynStruct dynStruct = manager.get(structNames[i]);
321
            if (dynStruct == null) {
322
                throw new DynClassNotFoundException(structNames[i]);
323
            }
324
            if (this.classes.containsKey(dynStruct.getFullName())) {
325
                continue;
326
            }
327
            this.classes.put(dynStruct.getFullName(), dynStruct);
328
        }
329

    
330
        this.forceConsolide();
331
    }
332

    
333
    public void extend(DynStruct dynStruct) {
334
        if (this.classes.containsKey(dynStruct.getFullName())) {
335
            return;
336
        }
337
        this.classes.put(dynStruct.getFullName(), dynStruct);
338
        this.forceConsolide();
339
    }
340

    
341
    public void extend(String structName) {
342
        DynClass dynClass = manager.get(structName);
343
        if (dynClass == null) {
344
            throw new DynClassNotFoundException(structName);
345
        }
346
        extend(dynClass);
347
    }
348

    
349
    public void extend(String namespace, String structame) {
350
        DynClass dynClass = manager.get(namespace, structame);
351
        if (dynClass == null) {
352
            throw new DynClassNotFoundException(new DefaultDynClassName(
353
                structame).getFullName());
354
        }
355
        extend(dynClass);
356
    }
357

    
358
    public int getFieldIndex(String name) {
359
        if (this.fieldsMap == null) {
360
            consolide();
361
        }
362
        FieldAndIndex f =
363
            (FieldAndIndex) this.fieldsMap.get(name.toLowerCase());
364
        if (f == null) {
365
            return -1;
366
        }
367
        return f.index;
368
    }
369

    
370
    public DynField getDeclaredDynField(String name) {
371
        return (DynField) this.declaredFieldsMap.get(name.toLowerCase());
372
    }
373

    
374
    public DynField[] getDeclaredDynFields() {
375
        return this.declaredFields;
376
    }
377

    
378
    public String getDescription() {
379
        return this.description;
380
    }
381

    
382
    public DynField getDynField(String name) {
383
        if (this.fieldsMap == null) {
384
            consolide();
385
        }
386
        FieldAndIndex findex =
387
            (FieldAndIndex) fieldsMap.get(name.toLowerCase());
388
        return findex == null ? null : findex.getDynField();
389
    }
390

    
391
    public FieldAndIndex getDynFieldAndIndex(String name) {
392
        if (this.fieldsMap == null) {
393
            consolide();
394
        }
395
        return (FieldAndIndex) this.fieldsMap.get(name.toLowerCase());
396
    }
397

    
398
    public DynField[] getDynFields() {
399
        if (this.fields == null) {
400
            consolide();
401
        }
402
        return this.fields;
403
    }
404

    
405
    public DynField addDynField(String name) {
406
        DynField field = new DefaultDynField(name);
407
        return this.addDynField(field);
408
    }
409

    
410
    public DynField addDynField(DynField field) {
411
        declaredFieldsMap.put(field.getName().toLowerCase(), field);
412
        try {
413
                if( field.getOder() == 0 ) {
414
                        field.setOrder(declaredFieldsMap.size()+1 );
415
                }
416
        } catch(Exception ex) {
417
                // Ignore errors when try to add an automated order
418
        }
419
        this.forceConsolide();
420
        return field;
421
    }
422

    
423
    public DynClass[] getSuperDynClasses() {
424
        if (this.superClasses == null) {
425
            consolide();
426
        }
427
        return this.superClasses;
428
    }
429

    
430
    public DynStruct[] getSuperDynStructs() {
431
        return this.getSuperDynClasses();
432
    }
433

    
434
    public DynObject newInstance() {
435
        return this.manager.createDynObject(this);
436
    }
437

    
438
    public boolean isInstance(DynObject dynObject) {
439
        if (this.superClassesMap == null) {
440
            consolide();
441
        }
442
        DefaultDynClass objClass = (DefaultDynClass) dynObject.getDynClass();
443
        if (this.superClassesMap.containsKey(objClass.getFullName())) {
444
            return true;
445
        }
446
                if (this.getFullName().equals(objClass.getFullName())) {
447
                        return true;
448
                }
449
        if (objClass.isAnonymous) {
450
            Iterator it = objClass.classes.values().iterator();
451
            while (it.hasNext()) {
452
                DynClass dc = (DynClass) it.next();
453
                if (this.superClassesMap.containsKey(dc.getFullName())) {
454
                    return true;
455
                }
456
            }
457
        }
458
        return false;
459
    }
460

    
461
    public void removeDynField(String name) {
462
        this.declaredFieldsMap.remove(name.toLowerCase());
463
        this.forceConsolide();
464
    }
465

    
466
    public void setAnonymous(boolean isAnonymous) {
467
        this.isAnonymous = isAnonymous;
468
    }
469

    
470
    public boolean isAnonymous() {
471
        return isAnonymous;
472
    }
473

    
474
    public int hashCode() {
475
        return name.hashCode();
476
    }
477

    
478
    public boolean equals(Object obj) {
479
        if (this == obj) {
480
            return true;
481
        }
482
        if (obj instanceof DynClass) {
483
            return this.getFullName().equals(((DynClass) obj).getFullName());
484
        }
485
        return false;
486
    }
487

    
488
    public void addDynMethod(DynMethod dynMethod) {
489
        this.manager.registerDynMethod(this, dynMethod);
490
    }
491

    
492
    void addMethod(DynMethod dynMethod) {
493
        declaredMethodsMap.put(dynMethod.getName(), dynMethod);
494
        this.forceConsolide();
495
    }
496

    
497
    public DynMethod getDeclaredDynMethod(String name) {
498
        return (DynMethod) this.declaredMethodsMap.get(name);
499
    }
500

    
501
    public DynMethod[] getDeclaredDynMethods() {
502
        if (this.declaredMethods == null) {
503
            consolide();
504
        }
505
        return this.declaredMethods;
506
    }
507

    
508
    public DynMethod getDynMethod(String name) throws DynMethodException {
509
        if (this.methodsMap == null) {
510
            consolide();
511
        }
512
        MethodAndIndex mindex = (MethodAndIndex) methodsMap.get(name);
513
        return mindex == null ? null : mindex.getDynMethod();
514
    }
515

    
516
    public DynMethod getDynMethod(int code) throws DynMethodException {
517
        return this.manager.getDynMethod(code);
518
    }
519

    
520
    public DynMethod[] getDynMethods() {
521
        if (this.methods == null) {
522
            consolide();
523
        }
524
        return this.methods;
525
    }
526

    
527
    public void removeDynMethod(String name) {
528
        // TODO Auto-generated method stub
529
    }
530

    
531
    public void validate(DynObject object) throws DynObjectValidateException {
532
        DynField fields[] = this.getDynFields();
533
        DynObjectValidateException exceptions =
534
            new DynObjectValidateException(this.getFullName());
535
        for (int i = 0; i < fields.length; i++) {
536
            DynField field = fields[i];
537
            try {
538
                field.validate(object.getDynValue(field.getName()));
539
            } catch (DynFieldValidateException e) {
540
                exceptions.add(e);
541
            } catch (DynFieldNotFoundException e) {
542
                exceptions.add(e);
543
            }
544
        }
545
        if (exceptions.size() > 0) {
546
            throw exceptions;
547
        }
548
    }
549

    
550
    public DynField addDynFieldString(String name) {
551
        return addDynField(name).setType(DataTypes.STRING);
552
    }
553

    
554
    public DynField addDynFieldDate(String name) {
555
        return addDynField(name).setType(DataTypes.DATE);
556
    }
557

    
558
    public DynField addDynFieldInt(String name) {
559
        return addDynField(name).setType(DataTypes.INT);
560
    }
561

    
562
    public DynField addDynFieldLong(String name) {
563
        return addDynField(name).setType(DataTypes.LONG);
564
    }
565

    
566
    public DynField addDynFieldDouble(String name) {
567
        return addDynField(name).setType(DataTypes.DOUBLE);
568
    }
569

    
570
    public DynField addDynFieldFloat(String name) {
571
        return addDynField(name).setType(DataTypes.FLOAT);
572
    }
573

    
574
    public DynField addDynFieldBoolean(String name) {
575
        return addDynField(name).setType(DataTypes.BOOLEAN);
576
    }
577

    
578
    public DynField addDynFieldFolder(String name) {
579
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
580
        return addDynField(name).setType(datamanager.get(DataTypes.FOLDER));
581
    }
582

    
583
    public DynField addDynFieldFile(String name) {
584
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
585
        return addDynField(name).setType(datamanager.get(DataTypes.FILE));
586
    }
587

    
588
    public DynField addDynFieldURL(String name) {
589
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
590
        return addDynField(name).setType(datamanager.get(DataTypes.URL));
591
    }
592

    
593
    public DynField addDynFieldURI(String name) {
594
        DataTypesManager datamanager = ToolsLocator.getDataTypesManager();
595
        return addDynField(name).setType(datamanager.get(DataTypes.URI));
596
    }
597

    
598
    public DynField addDynFieldObject(String name) {
599
        return addDynField(name).setType(DataTypes.OBJECT);
600
    }
601
    
602
    public DynField addDynFieldObject(String name, String dynObjectFullName) {
603
        return addDynField(name).setType(DataTypes.DYNOBJECT).setSubtype(dynObjectFullName);
604
    }
605

    
606
    public DynField addDynFieldObjectList(String name, String fullDynObjectName) {
607
        DynField listDynField = this.addDynFieldList(name)
608
            .setElementsType(DataTypes.DYNOBJECT)
609
            .setSubtype(fullDynObjectName);
610
        return listDynField;
611
    }
612

    
613
    public DynField addDynFieldArray(String name) {
614
        return addDynField(name).setType(DataTypes.ARRAY);
615
    }
616

    
617
    public DynField addDynFieldList(String name) {
618
        return addDynField(name).setType(DataTypes.LIST);
619
    }
620

    
621
    public DynField addDynFieldMap(String name) {
622
        return addDynField(name).setType(DataTypes.MAP);
623
    }
624

    
625
    public DynField addDynFieldSet(String name) {
626
        return addDynField(name).setType(DataTypes.SET);
627
    }
628

    
629
    public DynField addDynFieldChoice(String name, int type,
630
        Object defaultValue, DynObjectValueItem[] values) {
631
        return addDynFieldChoice(name, type, defaultValue, values, false, true);
632
    }
633

    
634
    public DynField addDynFieldChoice(String name, int type,
635
        Object defaultValue, DynObjectValueItem[] values, boolean mandatory,
636
        boolean persistent) {
637
        return addDynField(name).setType(type)
638
            .setDefaultFieldValue(defaultValue).setMandatory(mandatory)
639
            .setPersistent(persistent).setAvailableValues(values)
640
            .setDescription(description);
641
    }
642

    
643
    public DynField addDynFieldRange(String name, int type,
644
        Object defaultValue, Object min, Object max) {
645
        return addDynFieldRange(name, type, defaultValue, min, max, false, true);
646
    }
647

    
648
    public DynField addDynFieldRange(String name, int type,
649
        Object defaultValue, Object min, Object max, boolean mandatory,
650
        boolean persistent) {
651
        return addDynField(name).setType(type)
652
            .setDefaultFieldValue(defaultValue).setMandatory(mandatory)
653
            .setPersistent(persistent).setMinValue(min).setMaxValue(max);
654
    }
655

    
656
    public DynField addDynFieldSingle(String name, int type, Object defaultValue) {
657
        return addDynFieldSingle(name, type, defaultValue, false, true);
658
    }
659

    
660
    public DynField addDynFieldSingle(String name, int type,
661
        Object defaultValue, boolean mandatory, boolean persistent) {
662
        return addDynField(name).setType(type)
663
            .setDefaultFieldValue(defaultValue).setMandatory(mandatory)
664
            .setPersistent(persistent);
665
    }
666

    
667
    public void setDescription(String description) {
668
        this.description = description;
669
    }
670

    
671
    public void setNamespace(String namespace) {
672
        this.name.setNamespace(namespace);
673
    }
674

    
675
    public void check() throws ListBaseException {
676
        ListBaseException exceptions = null;
677

    
678
        if (name == null) {
679
            exceptions =
680
                CheckDynClassListException.add(exceptions, name, "name", name);
681
        }
682
        DynField[] fields = this.getDynFields();
683
        for (int i = 0; i < fields.length; i++) {
684
            try {
685
                DefaultDynField field = (DefaultDynField) fields[i];
686
                field.check();
687
            } catch (Exception ex) {
688
                exceptions =
689
                    CheckDynClassListException.add(exceptions, name, ex);
690
            }
691
        }
692
        if (exceptions != null) {
693
            throw exceptions;
694
        }
695
    }
696

    
697
    public static class CheckDynClassListException extends ListBaseException {
698

    
699
        /**
700
                 * 
701
                 */
702
        private static final long serialVersionUID = 9042601577056507657L;
703

    
704
        public static class CheckDynClassException extends DynObjectException {
705

    
706
            /**
707
                         * 
708
                         */
709
            private static final long serialVersionUID = -1447120375445458639L;
710

    
711
            public CheckDynClassException(String attrname, Object attrvalue) {
712
                super("Wrong value %(value) for attribute %(name).",
713
                    "Wrong_value_XvalueX_for_attribute_XnameX",
714
                    serialVersionUID);
715
            }
716
        }
717

    
718
        public CheckDynClassListException(DynClassName name) {
719
            super("Inconsistent DynClass %(name) definition.",
720
                "_Inconsistent_DynClass_XnameX_definition", serialVersionUID);
721
            String s;
722
            if (name == null) {
723
                s = "[unknow]";
724
            } else {
725
                s = name.getFullName();
726
            }
727
            setValue("name", s);
728
        }
729

    
730
        public static ListBaseException add(ListBaseException exceptions,
731
            DynClassName name, String attrname, Object attrvalue) {
732
            if (exceptions == null) {
733
                exceptions = new CheckDynClassListException(name);
734
            }
735
            exceptions.add(new CheckDynClassException(attrname, attrvalue));
736
            return exceptions;
737
        }
738

    
739
        public static ListBaseException add(ListBaseException exceptions,
740
            DynClassName name, Exception ex) {
741
            if (exceptions == null) {
742
                exceptions = new CheckDynClassListException(name);
743
            }
744
            exceptions.add(ex);
745
            return exceptions;
746
        }
747
    }
748

    
749
    private boolean isExtendable(Set superClassesSet, DynStruct dynStruct) {
750

    
751
        if ((superClassesSet == null) || (superClassesSet.isEmpty())) {
752
            return true;
753
        }
754

    
755
        if (superClassesSet.contains(dynStruct)) {
756
            return false;
757
        }
758

    
759
        return true;
760
    }
761

    
762
    public boolean isExtendable(DynStruct dynStruct) {
763

    
764
        if (dynStruct == null) {
765
            return false;
766
        }
767

    
768
        if (this.fieldsMap == null) {
769
            consolide();
770
        }
771
        Set superClassesSet = buildSuperDynClassSet();
772
        return isExtendable(superClassesSet, dynStruct);
773
    }
774

    
775
    private void removeDynStruct(DynStruct superDynStruct) {
776
        if (this.classes.containsKey(superDynStruct.getFullName())) {
777
            this.classes.remove(superDynStruct.getFullName());
778
        }
779
    }
780

    
781
    public void remove(DynStruct superDynStruct) {
782
        if (superDynStruct != null) {
783
            this.removeDynStruct(superDynStruct);
784
            this.forceConsolide();
785
        }
786
    }
787

    
788
    public void removeAll(DynStruct[] superDynStruct) {
789
        if (superDynStruct != null) {
790
            for (int i = 0; i < superDynStruct.length; i++) {
791
                removeDynStruct(superDynStruct[i]);
792
            }
793
            this.consolide();
794
        }
795
    }
796

    
797
    public void extend(DynStruct[] structs) {
798
        if (structs != null) {
799
            for (int i = 0; i < structs.length; i++) {
800
                extend(structs[i]);
801
            }
802
            this.consolide();
803
        }
804
    }
805
}