Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libTools / src / org / gvsig / tools / dynobject / impl / DefaultDynClass.java @ 25791

History | View | Annotate | Download (10.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.dynobject.DynClass;
12
import org.gvsig.tools.dynobject.DynField;
13
import org.gvsig.tools.dynobject.DynMethod;
14
import org.gvsig.tools.dynobject.DynObject;
15
import org.gvsig.tools.dynobject.DynObjectManager;
16
import org.gvsig.tools.dynobject.exception.DynMethodException;
17

    
18
public class DefaultDynClass implements DynClass {
19

    
20
        public class FieldAndIndex {
21
                DefaultDynField field;
22
                int index;
23

    
24
                FieldAndIndex(DynField field, int index) {
25
                        this.field = (DefaultDynField) field;
26
                        this.index = index;
27
                }
28
                public int getIndex() {
29
                        return this.index;
30
                }
31
                public DefaultDynField getDynField() {
32
                        return this.field;
33
                }
34
        }
35

    
36
        public class MethodAndIndex {
37
                DynMethod method;
38
                int index;
39

    
40
                MethodAndIndex(DynMethod method, int index) {
41
                        this.method = method;
42
                        this.index = index;
43
                }
44
                public int getIndex() {
45
                        return this.index;
46
                }
47
                public DynMethod getDynMethod() {
48
                        return this.method;
49
                }
50
        }
51

    
52
    DynObjectManager manager;
53

    
54
    private String name;
55
    private String description;
56

    
57
    private boolean isAnonymous;
58

    
59
    private Map classes;
60
    private Map declaredFieldsMap;
61
    private Map declaredMethodsMap;
62

    
63
    // This attributes are calculated by consolide method
64
    private DefaultDynClass[] superClasses;
65
        private Map superClassesMap;
66
    private DynField[] declaredFields;
67
        private Map fieldsMap;
68
        private DynField[] fields;
69
    private DynMethod[] declaredMethods;
70
        private Map methodsMap;
71
        private DynMethod[] methods;
72

    
73

    
74
    public DefaultDynClass(DynObjectManager manager, String name, String description) {
75
            this.isAnonymous = false;
76
            this.classes = new LinkedHashMap();
77
            this.declaredFieldsMap = new HashMap();
78
            this.declaredMethodsMap = new HashMap();
79

    
80
            this.forceConsolide();
81

    
82
            this.manager = manager;
83
            this.name = name;
84
            this.description = description;
85
    }
86

    
87
    public DefaultDynClass(DynObjectManager manager, String name, String description, DynClass[] superClases) {
88
            this(manager,name,description);
89
            for( int i=0; i<superClases.length; i++ ) {
90
                    DynClass dynClass = superClases[i];
91
                    if( ! this.classes.containsKey(dynClass.getName()) ) {
92
                            this.classes.put(dynClass.getName(), dynClass);
93
                    }
94
            }
95
    }
96

    
97
           public DynObjectManager getManager() {
98
            return this.manager;
99
    }
100

    
101
    public void consolide() {
102
            // Use classes and decalredFieldsMap to update all.
103

    
104
            // Actualize superClasses array
105
            this.superClasses = (DefaultDynClass[]) buildSuperDynClassSet()
106
                                .toArray(new DefaultDynClass[] {});
107

    
108
            // Actualize declaredFields array
109
            this.declaredFields = (DynField[]) this.declaredFieldsMap.values()
110
                .toArray(new DynField[] {});
111

    
112
            // Actualize declaredMethods array
113
            this.declaredMethods = (DynMethod[]) this.declaredMethodsMap.values()
114
                .toArray(new DynMethod[] {});
115

    
116
            // Actualize fieldsMap
117
            this.fieldsMap = new LinkedHashMap();
118
            int index = 0;
119
            for( int i=0; i<this.declaredFields.length; i++) {
120
                    this.fieldsMap.put(this.declaredFields[i].getName(), new FieldAndIndex(this.declaredFields[i],index++));
121
            }
122
            for( int i=0; i<this.superClasses.length ; i++ ) {
123
                Iterator it = this.superClasses[i].declaredFieldsMap.values().iterator();
124
                while( it.hasNext() ) {
125
                        DynField field = (DynField) it.next();
126
                            if( !this.fieldsMap.containsKey(field.getName()) ) {
127
                                    this.fieldsMap.put(field.getName(), new FieldAndIndex(field,index++));
128
                            }
129
                }
130
            }
131

    
132
            // Actualize methodsMap
133
            this.methodsMap = new LinkedHashMap();
134
            index = 0;
135
            for( int i=0; i<this.declaredMethods.length; i++) {
136
                    this.methodsMap.put(this.declaredMethods[i].getName(), new MethodAndIndex(this.declaredMethods[i],index++));
137
            }
138
            for( int i=0; i<this.superClasses.length ; i++ ) {
139
                Iterator it = this.superClasses[i].declaredMethodsMap.values().iterator();
140
                while( it.hasNext() ) {
141
                        DynMethod method = (DynMethod) it.next();
142
                            if( !this.methodsMap.containsKey(method.getName()) ) {
143
                                    this.methodsMap.put(method.getName(), new MethodAndIndex(method,index++));
144
                            }
145
                }
146
            }
147

    
148

    
149
                // Actualize fields array
150
                this.fields = new DynField[ this.fieldsMap.size() ];
151
                int i=0;
152
                Iterator it = this.fieldsMap.values().iterator();
153
                while( it.hasNext() ) {
154
                    FieldAndIndex findex = (FieldAndIndex) it.next();
155
            DynField field = findex.getDynField();
156
                        fields[i++] = field;
157
                }
158

    
159
                // Actualize methods array
160
                this.methods = new DynMethod[ this.methodsMap.size() ];
161
                i=0;
162
                it = this.methodsMap.values().iterator();
163
                while( it.hasNext() ) {
164
                    MethodAndIndex mindex = (MethodAndIndex) it.next();
165
            DynMethod method = mindex.getDynMethod();
166
                        methods[i++] = method;
167
                }
168

    
169
                // Actualize superClassesMap
170
                this.superClassesMap = new HashMap();
171
                for( i=0 ; i<this.superClasses.length ; i++) {
172
                        this.superClassesMap.put(this.superClasses[i].getName(), this.superClasses[i]);
173
                }
174
    }
175

    
176
    private void forceConsolide() {
177
        this.superClasses = null;
178
        this.superClassesMap = null;
179
        this.declaredFields = null;
180
        this.fieldsMap = null;
181
        this.fields = null;
182
        this.declaredMethods = null;
183
        this.methodsMap = null;
184
        this.methods = null;
185
    }
186

    
187
    private Set buildSuperDynClassSet() {
188
        Set dynClassParents = new LinkedHashSet();
189
        buildSuperDynClassList(this, dynClassParents);
190
        return dynClassParents;
191
    }
192

    
193
    private void buildSuperDynClassList(DefaultDynClass dynClass, Set allParents) {
194
            Collection values = dynClass.classes.values();
195
        Iterator it = values.iterator();
196
        while( it.hasNext() ) {
197
                DynClass dc = (DynClass) it.next();
198
                allParents.add(dc);
199
        }
200
        it = values.iterator();
201
        while( it.hasNext() ) {
202
                DefaultDynClass dc = (DefaultDynClass) it.next();
203
                buildSuperDynClassList(dc, allParents);
204
        }
205
    }
206

    
207
    public Object[] createValues(Object[] oldvalues) {
208
            if( this.fields == null ) {
209
                    consolide();
210
            }
211
            if (oldvalues != null && oldvalues.length >= this.fields.length) {
212
                    return oldvalues;
213
            }
214
            Object[] extended = new Object[ this.fields.length ];
215
            if( oldvalues != null ) {
216
                    System.arraycopy(oldvalues, 0, extended, 0, oldvalues.length);
217
            }
218
            return extended;
219
    }
220

    
221
        public void extend(DynClass dynClass) {
222
                if( this.classes.containsKey(dynClass.getName()) ) {
223
                        return;
224
                }
225
                this.classes.put(dynClass.getName(), dynClass);
226
                this.forceConsolide();
227
        }
228

    
229
        public void extend(String dynClassName) {
230
                DynClass dynClass = manager.get(dynClassName);
231
                extend(dynClass);
232
        }
233

    
234
    int getFieldIndex(String name) {
235
            if( this.fieldsMap == null ) {
236
                    consolide();
237
            }
238
            FieldAndIndex f = (FieldAndIndex) this.fieldsMap.get(name);
239
            if( f == null ) {
240
                    return -1;
241
            }
242
            return f.index;
243
    }
244

    
245
        public DynField getDeclaredDynField(String name) {
246
                return (DynField)this.declaredFieldsMap.get(name);
247
        }
248

    
249
        public DynField[] getDeclaredDynFields() {
250
                return this.declaredFields;
251
        }
252

    
253
        public String getDescription() {
254
                return this.description;
255
        }
256

    
257
        public DynField getDynField(String name) {
258
            if( this.fieldsMap == null ) {
259
                    consolide();
260
            }
261
            FieldAndIndex findex = (FieldAndIndex) fieldsMap.get(name);
262
        return findex == null ? null : findex.getDynField();
263
        }
264

    
265
        public FieldAndIndex getDynFieldAndIndex(String name) {
266
            if( this.fieldsMap == null ) {
267
                    consolide();
268
            }
269
                return (FieldAndIndex) this.fieldsMap.get(name);
270
        }
271

    
272
        public DynField[] getDynFields() {
273
            if( this.fields == null ) {
274
                    consolide();
275
            }
276
                return this.fields;
277
        }
278

    
279
        public String getName() {
280
                return this.name;
281
        }
282

    
283
        public DynField addDynField(String name) {
284
                DynField field = new DefaultDynField(name);
285
                declaredFieldsMap.put(name, field);
286
                this.forceConsolide();
287
                return field;
288
        }
289

    
290
        public DynClass[] getSuperDynClasses() {
291
            if( this.superClasses == null ) {
292
                    consolide();
293
            }
294
                return this.superClasses;
295
        }
296

    
297
        public DynObject newInstance() {
298
                return this.manager.createDynObject(this);
299
        }
300

    
301
        public boolean isInstance(DynObject dynObject) {
302
            if( this.superClassesMap == null ) {
303
                    consolide();
304
            }
305
                DefaultDynClass objClass = (DefaultDynClass) dynObject.getDynClass();
306
                if( this.superClassesMap.containsKey(objClass.getName()) ) {
307
                        return true;
308
                }
309
                if(objClass.isAnonymous ) {
310
                        Iterator it = objClass.classes.values().iterator();
311
                        while( it.hasNext() ) {
312
                                DynClass dc = (DynClass) it.next();
313
                                if( this.superClassesMap.containsKey(dc.getName()) ) {
314
                                        return true;
315
                                }
316
                        }
317
                }
318
                return false;
319
        }
320

    
321
        public void removeDynField(String name) {
322
                this.declaredFieldsMap.remove(name);
323
                this.forceConsolide();
324
        }
325

    
326
        public void setAnonymous(boolean isAnonymous) {
327
                this.isAnonymous = isAnonymous;
328
        }
329

    
330
        public boolean isAnonymous() {
331
                return isAnonymous;
332
        }
333

    
334
        public int hashCode() {
335
        return name.hashCode();
336
    }
337

    
338
    public boolean equals(Object obj) {
339
        if (this == obj) {
340
            return true;
341
        }
342
        if (obj instanceof DynClass) {
343
            return name.equals(((DynClass) obj).getName());
344
        }
345
        return false;
346
    }
347

    
348
        public void addDynMethod(DynMethod dynMethod) {
349
                this.manager.registerDynMethod(this, dynMethod);
350
        }
351

    
352
        void addMethod(DynMethod dynMethod) {
353
                declaredMethodsMap.put(name, dynMethod);
354
                this.forceConsolide();
355
        }
356

    
357
        public DynMethod getDeclaredDynMethod(String name) {
358
                return (DynMethod)this.declaredMethodsMap.get(name);
359
        }
360

    
361
        public DynMethod[] getDeclaredDynMethods() {
362
                return this.declaredMethods;
363
        }
364

    
365
        public DynMethod getDynMethod(String name) throws DynMethodException {
366
            if( this.methodsMap == null ) {
367
                    consolide();
368
            }
369
            MethodAndIndex mindex = (MethodAndIndex) methodsMap.get(name);
370
        return mindex == null ? null : mindex.getDynMethod();
371
        }
372

    
373
        public DynMethod getDynMethod(int code) throws DynMethodException {
374
                return this.manager.getDynMethod(code);
375
        }
376

    
377
        public DynMethod[] getDynMethods() {
378
            if( this.methods == null ) {
379
                    consolide();
380
            }
381
                return this.methods;
382
        }
383

    
384
        public void removeDynMethod(String name) {
385
                // TODO Auto-generated method stub
386

    
387
        }
388

    
389
}