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

History | View | Annotate | Download (15.4 KB)

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

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

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

    
48

    
49
public abstract  class AbstractPersistenceManager implements
50
                PersistenceManagerServices {
51

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

    
58
        
59

    
60
        protected AbstractPersistenceManager() {
61
                domainsURL = new Domains();
62
                factories = new DefaultFactories();
63
        }
64

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

    
71
        public Factories getFactories() {
72
                return this.factories;
73
        }
74

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

    
89
        public Object getObject(InputStream is) {
90
                Object obj = null;
91
                PersistentState state = null;
92
                String theClassName = null;
93
                try {
94
                        state = this.loadState(is);
95
                        theClassName = state.getTheClassName();
96
                        obj = this.create(state);
97
                } catch (PersistenceException e) {
98
                        throw new PersistenceCreateException(theClassName,e);
99
                }
100
                return obj;
101
        }
102
        
103
        public void putObject(OutputStream os, Object obj) {
104
                PersistentState state;
105
                try {
106
                        state = this.getState(obj);
107
                        this.saveState(state, os);
108
                } catch (PersistenceException e) {
109
                        throw new PersistenceWriteExeption(e);
110
                }
111
        }
112
        
113
        public DynStruct getDefinition(Class persistentClass) {
114
                return getDefinition(persistentClass.getName());
115
        }
116

    
117
        public DynStruct getDefinition(String className) {
118
                PersistenceFactory factory = this.factories.get(className);
119
                if( factory== null ) {
120
                        return null;
121
                }
122
                return factory.getDefinition(className);
123
        }
124
        
125
        public DynStruct getDynObjectDefinition(String className) {
126
                DefaultDynClassName dynClassName = new DefaultDynClassName(PERSISTENCE_DYNOBJECT_NAMESPACE, className);
127
                PersistenceFactory factory = this.factories.get(dynClassName.getFullName());
128
                if( factory== null ) {
129
                        return null;
130
                }
131
                return factory.getDefinition(dynClassName.getFullName());
132
        }
133

    
134
        private PersistentContextServices getContext(PersistentState state) {
135
                return (PersistentContextServices) state.getContext();
136
        }
137

    
138
        public void validate(PersistentState state, int mode)
139
                        throws PersistenceValidateExceptions {
140

    
141
                if (mode == PersistenceManager.DISABLED){
142
                        return;
143
                }
144

    
145
                List exceptions = new ArrayList();
146
                DynStruct definition = state.getDefinition();
147
                if( definition == null ) {
148
                        if( mode == PersistenceManager.MANDATORY ) {
149
                                exceptions.add(new PersistenceValidateMissingDefinitionException(state.getTheClassName()));
150
                                throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
151
                        } else {
152
                                return;
153
                        }
154
                }
155

    
156
                PersistentStateServices state2 = (PersistentStateServices) state;
157
                Iterator it = state2.getNames();
158
                while( it.hasNext() ) {
159
                        String name = (String) it.next();
160
                        DynField field = definition.getDynField(name);
161
                        if(  field == null ) {
162
                                exceptions.add( new FieldNotDeclaredException(name,state.getTheClassName()));
163
                        } 
164
                }
165
                DynObjectToPersistentStateAdapter dynAdapter = new DynObjectToPersistentStateAdapter(state, definition);                        
166
                try {
167
                        definition.validate(dynAdapter);
168
                } catch (DynObjectValidateException e) {
169
                        exceptions.add(e);
170
                }
171
                if (exceptions.size() > 0) {
172
                        throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
173
                }
174
        }
175

    
176
        public void validateAll(PersistentState state, int mode)
177
                        throws PersistenceValidateExceptions {
178

    
179
                if (mode == PersistenceManager.DISABLED){
180
                        return;
181
                }
182
                PersistentContextServices context =  getContext(state);
183
                context.validate(this.autoValidationMode);
184
        }
185

    
186
        private class DynObjectToPersistentStateAdapter implements DynObject {
187
                private PersistentState state;
188
                private DynStruct struct;
189

    
190
//                DynObjectToPersistentStateAdapter() {
191
//                        this.state = null;
192
//                        this.struct = null;
193
//                }
194
                DynObjectToPersistentStateAdapter(PersistentState state, DynStruct struct) {
195
                        this.state = state;
196
                        this.struct = struct;
197
                }
198

    
199
//                public void setData(PersistentState state, DynStruct struct) {
200
//                        this.state = state;
201
//                        this.struct = struct;
202
//                }
203

    
204
                public void delegate(DynObject dynObject) {
205
                        // Nothing to do
206

    
207
                }
208

    
209
                public DynClass getDynClass() {
210
                        // Nothing to do
211
                        return null;
212
                }
213

    
214
                public Object getDynValue(String name) throws DynFieldNotFoundException {
215
                        try {
216
                                return state.get(name);
217
                        } catch (PersistenceException e) {
218
                                throw new DynFieldNotFoundException(name, struct.getName());
219
                        }
220
                }
221

    
222
                public boolean hasDynValue(String name) {
223
                        return state.hasValue(name);
224
                }
225

    
226
                public void implement(DynClass dynClass) {
227
                        // Nothing to do
228
                }
229

    
230
                public Object invokeDynMethod(String name, DynObject context)
231
                                throws DynMethodException {
232
                        // Nothing to do
233
                        return null;
234
                }
235

    
236
                public Object invokeDynMethod(int code, DynObject context)
237
                                throws DynMethodException {
238
                        // Nothing to do
239
                        return null;
240
                }
241

    
242
                public void setDynValue(String name, Object value)
243
                                throws DynFieldNotFoundException {
244
                        // Nothing to do
245
                }
246
                public void clear() {
247
                        // Nothing to do
248
                }
249

    
250
        }
251

    
252
        public int getAutoValidation() {
253
                return autoValidationMode;
254
        }
255

    
256
        public void setAutoValidation(int validationMode) throws PersistenceException {
257
                switch (validationMode) {
258
                case DISABLED:
259
                case MANDATORY:
260
                case MANDATORY_IF_DECLARED:
261
                        autoValidationMode = validationMode;
262
                        break;
263
                default:
264
                        throw new PersistenceInvalidValidateModeException(validationMode);
265
                }
266
        }
267

    
268
        public PersistentState getState(Object obj)
269
                        throws PersistenceException, PersistenceValidateExceptions, PersistenceTypeNotSupportedException {
270
                return this.getState(obj, false);
271
        }
272

    
273
        public PersistentState getState(Object obj, boolean collectAllErrors)
274
                        throws PersistenceException {
275
                PersistentStateServices state = null;
276
                if( collectAllErrors ) {
277
                        PersistentContextServices context = this.getNewContext();
278
                        context.setCollectErrors(true);
279
                        try {
280
                                state = createState(obj, context);
281
                                context.setRootId(state.getId());
282
                                if (this.autoValidationMode != PersistenceManager.DISABLED){
283
                                        context.validate(this.autoValidationMode);
284
                                }
285
                        } catch(PersistenceException ex) {
286
                                context.addError(ex);
287
                        }
288
                } else {
289
                        PersistentContextServices context = this.getNewContext();
290
                        state = createState(obj, context);
291
                        context.setRootId(state.getId());
292
                        this.validateAll(state, this.autoValidationMode);
293
                }
294
                return state;
295
        }
296
        
297
        public PersistentStateServices createState(Object object, PersistentContextServices context) throws PersistenceException {
298

    
299
                PersistentStateServices state = createPersistentState(context);
300
                state.setTheClassName(object.getClass().getName());
301
                
302
                context.add(state, object);
303
                
304
                PersistenceFactory factory = this.factories.get(object);
305
                if (factory == null) {
306
                        throw new PersistenceTypeNotSupportedException(object
307
                                        .getClass());
308
                }
309
                state.setFactory(factory);
310
                state.setTheClassName(factory.getManagedClassName(object));
311
                factory.saveToState(state, object);
312
                return state;
313
        }
314

    
315
        public List getWrappedList(List list, PersistentContextServices context) {
316
                return new DelegatedList(list, this, context);
317
        }
318

    
319
        public Map getWrappedMap(Map map, PersistentContextServices context) {
320
                return new DelegatedMap(map, this, context);
321
        }
322

    
323
        public Set getWrappedSet(Set set, PersistentContextServices context) {
324
                return new DelegatedSet(set, this, context);
325
        }
326

    
327

    
328
        public Map getDomains() {
329
                return Collections.unmodifiableMap(domainsURL);
330
        }
331

    
332
        public List getDomainDefinitions(String domainName) {
333
                if (!domainsURL.containsKey(domainName)) {
334
                        throw new PersistenceDomainNotRegisterdException(domainName);
335
                }
336
                List definitions = new ArrayList();
337
                Iterator it = this.factories.iterator();
338
                while( it.hasNext() ) {
339
                        PersistenceFactory factory = (PersistenceFactory) it.next();
340
                        if( factory.getDomainName().equals(domainName)) {
341
                                List factDefinitions = factory.getDefinitions();
342
                                if(factDefinitions != null){
343
                                        definitions.addAll(factDefinitions);
344
                                }
345
                        }
346
                }
347
                return definitions;
348
        }
349

    
350
                        
351
        public DynStruct addDefinition(Class theClass, String name, String description,
352
                        String domainName, String domainUrl) {
353
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
354

    
355
                DynClass definition = dynman.createDynClass(PERSISTENCE_NAMESPACE, name, description);
356
                return addDefinition(theClass, definition, domainName, domainUrl);
357
        }
358

    
359
        public DynStruct addDefinition(Class theClass, String name, InputStream definitions, ClassLoader loader,
360
                        String domainName, String domainUrl) {
361
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
362
                Map x;
363
                try {
364
                        x = dynman.importDynClassDefinitions(definitions, loader, PersistenceManager.PERSISTENCE_NAMESPACE);
365
                } catch (XmlPullParserException e) {
366
                        throw new AddDefinitionException(e);
367
                } catch (IOException e) {
368
                        throw new AddDefinitionException(e);
369
                }
370
                DynClass definition = (DynClass) x.get(name);
371
                if( definition == null ) {
372
                        throw new CantFindDefinitionInStreamException(name, getKeys(x));
373
                }
374
                return addDefinition(theClass, definition, domainName, domainUrl);
375
        }
376

    
377
        private String getKeys(Map theMap) {
378
                List l = new ArrayList(theMap.keySet());
379
                return l.toString();
380
        }
381
        
382

    
383
        public DynStruct addDefinition(Class theClass, String name, Map definitions,
384
                        String domainName, String domainUrl) {
385
                DynClass definition = (DynClass) definitions.get(name);
386
                return addDefinition(theClass, definition, domainName, domainUrl);
387
                
388
        }
389

    
390
        protected  DynStruct addDefinition(Class theClass, DynClass definition,
391
                String domainName, String domainUrl) {
392
                if(theClass == DynObject.class){
393
                        return this.addDefinition(definition, domainName, domainUrl);
394
                }
395
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
396
                
397
                if(theClass.equals(DynObject.class)){
398
                        definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
399
                } else {
400
                        definition.setNamespace(PERSISTENCE_NAMESPACE);
401
                }
402
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
403
                        throw new DuplicatePersistentDefinitionException(definition.getName());
404
                }
405
                dynman.add(definition);
406
                
407
                PersistenceFactory factory = new SimplePersistenceFactory(
408
                                theClass, 
409
                                definition,
410
                                domainName, 
411
                                domainUrl
412
                        );
413
                this.factories.add(factory);
414
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
415
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
416
                return definition;
417
        }
418
        
419
        public DynStruct addDefinition(DynStruct definition, String domainName,
420
                        String domainUrl) throws AddDefinitionException {
421
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
422
                
423
                definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
424
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
425
                        throw new DuplicatePersistentDefinitionException(definition.getFullName());
426
                }
427
                dynman.add((DynClass) definition);
428
                
429
                PersistenceFactory factory = this.factories.get(definition.getFullName());
430
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
431
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
432
                return definition;
433
        }
434
        
435
        public void registerFactory(PersistenceFactory factory) {
436
                this.factories.add(factory);
437
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
438
                LOG.trace("Add persistence factory {}.", new Object[] { factory.getClass().getName() });
439
        }
440

    
441
        public void unregisterClass(Class theClass) {
442
                PersistenceFactory factory = this.factories.get(theClass.getName());
443
                if( factory == null ) {
444
                        return ;
445
                }
446
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
447
                DynStruct definition = factory.getDefinition(theClass.getName());
448

    
449
                dynman.remove(definition);
450
                this.factories.remove( factory);
451
                this.domainsURL.remove(factory.getDomainName());
452
        }
453

    
454
        public void unregisterClass(String name) {
455
                PersistenceFactory factory = this.factories.get(name);
456
                if( factory == null ) {
457
                        return ;
458
                }
459
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
460

    
461
                this.factories.remove( factory);
462
                this.domainsURL.remove(factory.getDomainName());
463

    
464
                DynStruct definition = factory.getDefinition(name);
465
                dynman.remove(definition);
466
        }
467

    
468
        public void unregisterFactory(PersistenceFactory factory) {
469
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
470

    
471
                this.factories.remove(factory);
472
                this.domainsURL.remove(factory.getDomainName());
473

    
474
                List definitions = factory.getDefinitions();
475
                if (definitions != null){
476
                        Iterator it = definitions.iterator();
477
                        while( it.hasNext() ) {
478
                                DynStruct definition = (DynStruct) it.next();
479
                                dynman.remove(definition);
480
                        }
481
                }
482
        }
483
        
484
        public PersistentStateServices createPersistentState(        PersistentContextServices context) {
485
                return this.createPersistentState(context, context.getNewIdentifier());
486
        }
487

    
488
}