Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / persistence / impl / AbstractPersistenceManager.java @ 477

History | View | Annotate | Download (14.6 KB)

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

    
3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.util.ArrayList;
6
import java.util.Collections;
7
import java.util.Iterator;
8
import java.util.List;
9
import java.util.Map;
10
import java.util.Set;
11

    
12
import org.gvsig.tools.ToolsLocator;
13
import org.gvsig.tools.dynobject.DynClass;
14
import org.gvsig.tools.dynobject.DynField;
15
import org.gvsig.tools.dynobject.DynObject;
16
import org.gvsig.tools.dynobject.DynObjectManager;
17
import org.gvsig.tools.dynobject.DynStruct;
18
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
19
import org.gvsig.tools.dynobject.exception.DynMethodException;
20
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
21
import org.gvsig.tools.dynobject.impl.DefaultDynClassName;
22
import org.gvsig.tools.persistence.PersistenceFactory;
23
import org.gvsig.tools.persistence.PersistenceManager;
24
import org.gvsig.tools.persistence.PersistentState;
25
import org.gvsig.tools.persistence.exception.AddDefinitionException;
26
import org.gvsig.tools.persistence.exception.DuplicatePersistentDefinitionException;
27
import org.gvsig.tools.persistence.exception.FieldNotDeclaredException;
28
import org.gvsig.tools.persistence.exception.PersistenceClassNotRegistered;
29
import org.gvsig.tools.persistence.exception.PersistenceException;
30
import org.gvsig.tools.persistence.exception.PersistenceTypeNotSupportedException;
31
import org.gvsig.tools.persistence.exception.PersistenceValidateExceptions;
32
import org.gvsig.tools.persistence.impl.exception.CantFindDefinitionInStreamException;
33
import org.gvsig.tools.persistence.impl.exception.PersistenceDomainNotRegisterdException;
34
import org.gvsig.tools.persistence.impl.exception.PersistenceIllegalStateTheClassNameNotSetException;
35
import org.gvsig.tools.persistence.impl.exception.PersistenceInvalidValidateModeException;
36
import org.gvsig.tools.persistence.impl.exception.PersistenceValidateMissingDefinitionException;
37
import org.gvsig.tools.persistence.spi.PersistenceManagerServices;
38
import org.gvsig.tools.persistence.spi.PersistentContextServices;
39
import org.gvsig.tools.persistence.spi.PersistentContextServices.ObjectReference;
40
import org.gvsig.tools.persistence.spi.PersistentStateServices;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43
import org.xmlpull.v1.XmlPullParserException;
44

    
45

    
46
public abstract  class AbstractPersistenceManager implements
47
                PersistenceManagerServices {
48

    
49
        private static final Logger LOG = LoggerFactory.getLogger(AbstractPersistenceManager.class);
50
        
51
        private DefaultFactories factories;
52
        private Domains domainsURL;
53
        private int autoValidationMode = PersistenceManager.DISABLED;
54

    
55
        
56

    
57
        protected AbstractPersistenceManager() {
58
                domainsURL = new Domains();
59
                factories = new DefaultFactories();
60
        }
61

    
62
        public void addAlias(String name, Class aClass)
63
                        throws PersistenceClassNotRegistered {
64
                PersistenceFactory factory = this.factories.get(aClass.getName());
65
                this.factories.add(factory, aClass.getName());
66
        }
67

    
68
        public Factories getFactories() {
69
                return this.factories;
70
        }
71

    
72
        public PersistentContextServices getNewContext() {
73
                return new DefaultPersistentContext(this);
74
        }
75
        
76
        public Object create(PersistentState state) throws PersistenceException {
77
                String className = state.getTheClassName();
78
                if (className == null) {
79
                        throw new PersistenceIllegalStateTheClassNameNotSetException() ;
80
                }
81
                PersistentContextServices context = getContext(state);
82
                ObjectReference ref = context.get(state);
83
                return ref.getObject();
84
        }
85

    
86
        public DynStruct getDefinition(Class persistentClass) {
87
                return getDefinition(persistentClass.getName());
88
        }
89

    
90
        public DynStruct getDefinition(String className) {
91
                PersistenceFactory factory = this.factories.get(className);
92
                if( factory== null ) {
93
                        return null;
94
                }
95
                return factory.getDefinition(className);
96
        }
97
        
98
        public DynStruct getDynObjectDefinition(String className) {
99
                DefaultDynClassName dynClassName = new DefaultDynClassName(PERSISTENCE_DYNOBJECT_NAMESPACE, className);
100
                PersistenceFactory factory = this.factories.get(dynClassName.getFullName());
101
                if( factory== null ) {
102
                        return null;
103
                }
104
                return factory.getDefinition(dynClassName.getFullName());
105
        }
106

    
107
        private PersistentContextServices getContext(PersistentState state) {
108
                return (PersistentContextServices) state.getContext();
109
        }
110

    
111
        public void validate(PersistentState state, int mode)
112
                        throws PersistenceValidateExceptions {
113

    
114
                if (mode == PersistenceManager.DISABLED){
115
                        return;
116
                }
117

    
118
                List exceptions = new ArrayList();
119
                DynStruct definition = state.getDefinition();
120
                if( definition == null ) {
121
                        if( mode == PersistenceManager.MANDATORY ) {
122
                                exceptions.add(new PersistenceValidateMissingDefinitionException(state.getTheClassName()));
123
                                throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
124
                        } else {
125
                                return;
126
                        }
127
                }
128

    
129
                PersistentStateServices state2 = (PersistentStateServices) state;
130
                Iterator it = state2.getNames();
131
                while( it.hasNext() ) {
132
                        String name = (String) it.next();
133
                        DynField field = definition.getDynField(name);
134
                        if(  field == null ) {
135
                                exceptions.add( new FieldNotDeclaredException(name,state.getTheClassName()));
136
                        } 
137
                }
138
                DynObjectToPersistentStateAdapter dynAdapter = new DynObjectToPersistentStateAdapter(state, definition);                        
139
                try {
140
                        definition.validate(dynAdapter);
141
                } catch (DynObjectValidateException e) {
142
                        exceptions.add(e);
143
                }
144
                if (exceptions.size() > 0) {
145
                        throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
146
                }
147
        }
148

    
149
        public void validateAll(PersistentState state, int mode)
150
                        throws PersistenceValidateExceptions {
151

    
152
                if (mode == PersistenceManager.DISABLED){
153
                        return;
154
                }
155
                PersistentContextServices context =  getContext(state);
156
                context.validate(this.autoValidationMode);
157
        }
158

    
159
        private class DynObjectToPersistentStateAdapter implements DynObject {
160
                private PersistentState state;
161
                private DynStruct struct;
162

    
163
//                DynObjectToPersistentStateAdapter() {
164
//                        this.state = null;
165
//                        this.struct = null;
166
//                }
167
                DynObjectToPersistentStateAdapter(PersistentState state, DynStruct struct) {
168
                        this.state = state;
169
                        this.struct = struct;
170
                }
171

    
172
//                public void setData(PersistentState state, DynStruct struct) {
173
//                        this.state = state;
174
//                        this.struct = struct;
175
//                }
176

    
177
                public void delegate(DynObject dynObject) {
178
                        // Nothing to do
179

    
180
                }
181

    
182
                public DynClass getDynClass() {
183
                        // Nothing to do
184
                        return null;
185
                }
186

    
187
                public Object getDynValue(String name) throws DynFieldNotFoundException {
188
                        try {
189
                                return state.get(name);
190
                        } catch (PersistenceException e) {
191
                                throw new DynFieldNotFoundException(name, struct.getName());
192
                        }
193
                }
194

    
195
                public boolean hasDynValue(String name) {
196
                        return state.hasValue(name);
197
                }
198

    
199
                public void implement(DynClass dynClass) {
200
                        // Nothing to do
201
                }
202

    
203
                public Object invokeDynMethod(String name, DynObject context)
204
                                throws DynMethodException {
205
                        // Nothing to do
206
                        return null;
207
                }
208

    
209
                public Object invokeDynMethod(int code, DynObject context)
210
                                throws DynMethodException {
211
                        // Nothing to do
212
                        return null;
213
                }
214

    
215
                public void setDynValue(String name, Object value)
216
                                throws DynFieldNotFoundException {
217
                        // Nothing to do
218
                }
219
                public void clear() {
220
                        // Nothing to do
221
                }
222

    
223
        }
224

    
225
        public int getAutoValidation() {
226
                return autoValidationMode;
227
        }
228

    
229
        public void setAutoValidation(int validationMode) throws PersistenceException {
230
                switch (validationMode) {
231
                case DISABLED:
232
                case MANDATORY:
233
                case MANDATORY_IF_DECLARED:
234
                        autoValidationMode = validationMode;
235
                        break;
236
                default:
237
                        throw new PersistenceInvalidValidateModeException(validationMode);
238
                }
239
        }
240

    
241
        public PersistentState getState(Object obj)
242
                        throws PersistenceException, PersistenceValidateExceptions, PersistenceTypeNotSupportedException {
243
                return this.getState(obj, false);
244
        }
245

    
246
        public PersistentState getState(Object obj, boolean collectAllErrors)
247
                        throws PersistenceException {
248
                PersistentStateServices state = null;
249
                if( collectAllErrors ) {
250
                        PersistentContextServices context = this.getNewContext();
251
                        context.setCollectErrors(true);
252
                        try {
253
                                state = createState(obj, context);
254
                                context.setRootId(state.getId());
255
                                if (this.autoValidationMode != PersistenceManager.DISABLED){
256
                                        context.validate(this.autoValidationMode);
257
                                }
258
                        } catch(PersistenceException ex) {
259
                                context.addError(ex);
260
                        }
261
                } else {
262
                        PersistentContextServices context = this.getNewContext();
263
                        state = createState(obj, context);
264
                        context.setRootId(state.getId());
265
                        this.validateAll(state, this.autoValidationMode);
266
                }
267
                return state;
268
        }
269
        
270
        public PersistentStateServices createState(Object object, PersistentContextServices context) throws PersistenceException {
271

    
272
                PersistentStateServices state = createPersistentState(context);
273
                state.setTheClassName(object.getClass().getName());
274
                
275
                context.add(state, object);
276
                
277
                PersistenceFactory factory = this.factories.get(object);
278
                if (factory == null) {
279
                        throw new PersistenceTypeNotSupportedException(object
280
                                        .getClass());
281
                }
282
                state.setFactory(factory);
283
                state.setTheClassName(factory.getManagedClassName(object));
284
                factory.saveToState(state, object);
285
                return state;
286
        }
287

    
288
        public List getWrappedList(List list, PersistentContextServices context) {
289
                return new DelegatedList(list, this, context);
290
        }
291

    
292
        public Map getWrappedMap(Map map, PersistentContextServices context) {
293
                return new DelegatedMap(map, this, context);
294
        }
295

    
296
        public Set getWrappedSet(Set set, PersistentContextServices context) {
297
                return new DelegatedSet(set, this, context);
298
        }
299

    
300

    
301
        public Map getDomains() {
302
                return Collections.unmodifiableMap(domainsURL);
303
        }
304

    
305
        public List getDomainDefinitions(String domainName) {
306
                if (!domainsURL.containsKey(domainName)) {
307
                        throw new PersistenceDomainNotRegisterdException(domainName);
308
                }
309
                List definitions = new ArrayList();
310
                Iterator it = this.factories.iterator();
311
                while( it.hasNext() ) {
312
                        PersistenceFactory factory = (PersistenceFactory) it.next();
313
                        if( factory.getDomainName().equals(domainName)) {
314
                                List factDefinitions = factory.getDefinitions();
315
                                if(factDefinitions != null){
316
                                        definitions.addAll(factDefinitions);
317
                                }
318
                        }
319
                }
320
                return definitions;
321
        }
322

    
323
                        
324
        public DynStruct addDefinition(Class theClass, String name, String description,
325
                        String domainName, String domainUrl) {
326
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
327

    
328
                DynClass definition = dynman.createDynClass(PERSISTENCE_NAMESPACE, name, description);
329
                return addDefinition(theClass, definition, domainName, domainUrl);
330
        }
331

    
332
        public DynStruct addDefinition(Class theClass, String name, InputStream definitions, ClassLoader loader,
333
                        String domainName, String domainUrl) {
334
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
335
                Map x;
336
                try {
337
                        x = dynman.importDynClassDefinitions(definitions, loader, PersistenceManager.PERSISTENCE_NAMESPACE);
338
                } catch (XmlPullParserException e) {
339
                        throw new AddDefinitionException(e);
340
                } catch (IOException e) {
341
                        throw new AddDefinitionException(e);
342
                }
343
                DynClass definition = (DynClass) x.get(name);
344
                if( definition == null ) {
345
                        throw new CantFindDefinitionInStreamException(name, getKeys(x));
346
                }
347
                return addDefinition(theClass, definition, domainName, domainUrl);
348
        }
349

    
350
        private String getKeys(Map theMap) {
351
                List l = new ArrayList(theMap.keySet());
352
                return l.toString();
353
        }
354
        
355

    
356
        public DynStruct addDefinition(Class theClass, String name, Map definitions,
357
                        String domainName, String domainUrl) {
358
                DynClass definition = (DynClass) definitions.get(name);
359
                return addDefinition(theClass, definition, domainName, domainUrl);
360
                
361
        }
362

    
363
        protected  DynStruct addDefinition(Class theClass, DynClass definition,
364
                String domainName, String domainUrl) {
365
                if(theClass == DynObject.class){
366
                        return this.addDefinition(definition, domainName, domainUrl);
367
                }
368
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
369
                
370
                if(theClass.equals(DynObject.class)){
371
                        definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
372
                } else {
373
                        definition.setNamespace(PERSISTENCE_NAMESPACE);
374
                }
375
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
376
                        throw new DuplicatePersistentDefinitionException(definition.getName());
377
                }
378
                dynman.add(definition);
379
                
380
                PersistenceFactory factory = new SimplePersistenceFactory(
381
                                theClass, 
382
                                definition,
383
                                domainName, 
384
                                domainUrl
385
                        );
386
                this.factories.add(factory);
387
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
388
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
389
                return definition;
390
        }
391
        
392
        public DynStruct addDefinition(DynStruct definition, String domainName,
393
                        String domainUrl) throws AddDefinitionException {
394
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
395
                
396
                definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
397
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
398
                        throw new DuplicatePersistentDefinitionException(definition.getFullName());
399
                }
400
                dynman.add((DynClass) definition);
401
                
402
                PersistenceFactory factory = this.factories.get(definition.getFullName());
403
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
404
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
405
                return definition;
406
        }
407
        
408
        public void registerFactory(PersistenceFactory factory) {
409
                this.factories.add(factory);
410
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
411
                LOG.trace("Add persistence factory {}.", new Object[] { factory.getClass().getName() });
412
        }
413

    
414
        public void unregisterClass(Class theClass) {
415
                PersistenceFactory factory = this.factories.get(theClass.getName());
416
                if( factory == null ) {
417
                        return ;
418
                }
419
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
420
                DynStruct definition = factory.getDefinition(theClass.getName());
421

    
422
                dynman.remove(definition);
423
                this.factories.remove( factory);
424
                this.domainsURL.remove(factory.getDomainName());
425
        }
426

    
427
        public void unregisterClass(String name) {
428
                PersistenceFactory factory = this.factories.get(name);
429
                if( factory == null ) {
430
                        return ;
431
                }
432
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
433

    
434
                this.factories.remove( factory);
435
                this.domainsURL.remove(factory.getDomainName());
436

    
437
                DynStruct definition = factory.getDefinition(name);
438
                dynman.remove(definition);
439
        }
440

    
441
        public void unregisterFactory(PersistenceFactory factory) {
442
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
443

    
444
                this.factories.remove(factory);
445
                this.domainsURL.remove(factory.getDomainName());
446

    
447
                List definitions = factory.getDefinitions();
448
                if (definitions != null){
449
                        Iterator it = definitions.iterator();
450
                        while( it.hasNext() ) {
451
                                DynStruct definition = (DynStruct) it.next();
452
                                dynman.remove(definition);
453
                        }
454
                }
455
        }
456
        
457
        public PersistentStateServices createPersistentState(        PersistentContextServices context) {
458
                return this.createPersistentState(context, context.getNewIdentifier());
459
        }
460

    
461
}