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

History | View | Annotate | Download (16.3 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.persistence.impl;
25

    
26
import java.io.IOException;
27
import java.io.InputStream;
28
import java.io.OutputStream;
29
import java.util.ArrayList;
30
import java.util.Collections;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.Map;
34
import java.util.Set;
35

    
36
import org.gvsig.tools.ToolsLocator;
37
import org.gvsig.tools.dynobject.DynClass;
38
import org.gvsig.tools.dynobject.DynField;
39
import org.gvsig.tools.dynobject.DynObject;
40
import org.gvsig.tools.dynobject.DynObjectManager;
41
import org.gvsig.tools.dynobject.DynStruct;
42
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
43
import org.gvsig.tools.dynobject.exception.DynMethodException;
44
import org.gvsig.tools.dynobject.exception.DynObjectValidateException;
45
import org.gvsig.tools.dynobject.impl.DefaultDynClassName;
46
import org.gvsig.tools.persistence.PersistenceFactory;
47
import org.gvsig.tools.persistence.PersistenceManager;
48
import org.gvsig.tools.persistence.PersistentState;
49
import org.gvsig.tools.persistence.exception.AddDefinitionException;
50
import org.gvsig.tools.persistence.exception.DuplicatePersistentDefinitionException;
51
import org.gvsig.tools.persistence.exception.FieldNotDeclaredException;
52
import org.gvsig.tools.persistence.exception.PersistenceClassNotRegistered;
53
import org.gvsig.tools.persistence.exception.PersistenceCreateException;
54
import org.gvsig.tools.persistence.exception.PersistenceException;
55
import org.gvsig.tools.persistence.exception.PersistenceTypeNotSupportedException;
56
import org.gvsig.tools.persistence.exception.PersistenceValidateExceptions;
57
import org.gvsig.tools.persistence.exception.PersistenceWriteExeption;
58
import org.gvsig.tools.persistence.impl.exception.CantFindDefinitionInStreamException;
59
import org.gvsig.tools.persistence.impl.exception.PersistenceDomainNotRegisterdException;
60
import org.gvsig.tools.persistence.impl.exception.PersistenceIllegalStateTheClassNameNotSetException;
61
import org.gvsig.tools.persistence.impl.exception.PersistenceInvalidValidateModeException;
62
import org.gvsig.tools.persistence.impl.exception.PersistenceValidateMissingDefinitionException;
63
import org.gvsig.tools.persistence.spi.PersistenceManagerServices;
64
import org.gvsig.tools.persistence.spi.PersistentContextServices;
65
import org.gvsig.tools.persistence.spi.PersistentContextServices.ObjectReference;
66
import org.gvsig.tools.persistence.spi.PersistentStateServices;
67
import org.slf4j.Logger;
68
import org.slf4j.LoggerFactory;
69
import org.xmlpull.v1.XmlPullParserException;
70

    
71

    
72
public abstract  class AbstractPersistenceManager implements
73
                PersistenceManagerServices {
74

    
75
        private static final Logger LOG = LoggerFactory.getLogger(AbstractPersistenceManager.class);
76
        
77
        private DefaultFactories factories;
78
        private Domains domainsURL;
79
        private int autoValidationMode = PersistenceManager.DISABLED;
80

    
81
        
82

    
83
        protected AbstractPersistenceManager() {
84
                domainsURL = new Domains();
85
                factories = new DefaultFactories();
86
        }
87

    
88
        public void addAlias(String name, Class aClass)
89
                        throws PersistenceClassNotRegistered {
90
                PersistenceFactory factory = this.factories.get(aClass.getName());
91
                this.factories.add(factory, aClass.getName());
92
        }
93

    
94
        public Factories getFactories() {
95
                return this.factories;
96
        }
97

    
98
        public PersistentContextServices getNewContext() {
99
                return new DefaultPersistentContext(this);
100
        }
101
        
102
        public Object create(PersistentState state) throws PersistenceException {
103
                String className = state.getTheClassName();
104
                if (className == null) {
105
                        throw new PersistenceIllegalStateTheClassNameNotSetException() ;
106
                }
107
                PersistentContextServices context = getContext(state);
108
                ObjectReference ref = context.get(state);
109
                return ref.getObject();
110
        }
111

    
112
        public Object getObject(InputStream is) {
113
                Object obj = null;
114
                PersistentState state = null;
115
                String theClassName = null;
116
                try {
117
                        state = this.loadState(is);
118
                        theClassName = state.getTheClassName();
119
                        obj = this.create(state);
120
                } catch (PersistenceException e) {
121
                        throw new PersistenceCreateException(theClassName,e);
122
                }
123
                return obj;
124
        }
125
        
126
        public void putObject(OutputStream os, Object obj) {
127
                PersistentState state;
128
                try {
129
                        state = this.getState(obj);
130
                        this.saveState(state, os);
131
                } catch (PersistenceException e) {
132
                        throw new PersistenceWriteExeption(e);
133
                }
134
        }
135
        
136
        public DynStruct getDefinition(Class persistentClass) {
137
                return getDefinition(persistentClass.getName());
138
        }
139

    
140
        public DynStruct getDefinition(String className) {
141
                PersistenceFactory factory = this.factories.get(className);
142
                if( factory== null ) {
143
                        return null;
144
                }
145
                return factory.getDefinition(className);
146
        }
147
        
148
        public DynStruct getDynObjectDefinition(String className) {
149
                DefaultDynClassName dynClassName = new DefaultDynClassName(PERSISTENCE_DYNOBJECT_NAMESPACE, className);
150
                PersistenceFactory factory = this.factories.get(dynClassName.getFullName());
151
                if( factory== null ) {
152
                        return null;
153
                }
154
                return factory.getDefinition(dynClassName.getFullName());
155
        }
156

    
157
        private PersistentContextServices getContext(PersistentState state) {
158
                return (PersistentContextServices) state.getContext();
159
        }
160

    
161
        public void validate(PersistentState state, int mode)
162
                        throws PersistenceValidateExceptions {
163

    
164
                if (mode == PersistenceManager.DISABLED){
165
                        return;
166
                }
167

    
168
                List exceptions = new ArrayList();
169
                DynStruct definition = state.getDefinition();
170
                if( definition == null ) {
171
                        if( mode == PersistenceManager.MANDATORY ) {
172
                                exceptions.add(new PersistenceValidateMissingDefinitionException(state.getTheClassName()));
173
                                throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
174
                        } else {
175
                                return;
176
                        }
177
                }
178

    
179
                PersistentStateServices state2 = (PersistentStateServices) state;
180
                Iterator it = state2.getNames();
181
                while( it.hasNext() ) {
182
                        String name = (String) it.next();
183
                        DynField field = definition.getDynField(name);
184
                        if(  field == null ) {
185
                                exceptions.add( new FieldNotDeclaredException(name,state.getTheClassName()));
186
                        } 
187
                }
188
                DynObjectToPersistentStateAdapter dynAdapter = new DynObjectToPersistentStateAdapter(state, definition);                        
189
                try {
190
                        definition.validate(dynAdapter);
191
                } catch (DynObjectValidateException e) {
192
                        exceptions.add(e);
193
                }
194
                if (exceptions.size() > 0) {
195
                        throw  new PersistenceValidateExceptions(state.getTheClassName(), exceptions);
196
                }
197
        }
198

    
199
        public void validateAll(PersistentState state, int mode)
200
                        throws PersistenceValidateExceptions {
201

    
202
                if (mode == PersistenceManager.DISABLED){
203
                        return;
204
                }
205
                PersistentContextServices context =  getContext(state);
206
                context.validate(this.autoValidationMode);
207
        }
208

    
209
        private class DynObjectToPersistentStateAdapter implements DynObject {
210
                private PersistentState state;
211
                private DynStruct struct;
212

    
213
//                DynObjectToPersistentStateAdapter() {
214
//                        this.state = null;
215
//                        this.struct = null;
216
//                }
217
                DynObjectToPersistentStateAdapter(PersistentState state, DynStruct struct) {
218
                        this.state = state;
219
                        this.struct = struct;
220
                }
221

    
222
//                public void setData(PersistentState state, DynStruct struct) {
223
//                        this.state = state;
224
//                        this.struct = struct;
225
//                }
226

    
227
                public void delegate(DynObject dynObject) {
228
                        // Nothing to do
229

    
230
                }
231

    
232
                public DynClass getDynClass() {
233
                        // Nothing to do
234
                        return null;
235
                }
236

    
237
                public Object getDynValue(String name) throws DynFieldNotFoundException {
238
                        try {
239
                                return state.get(name);
240
                        } catch (PersistenceException e) {
241
                                throw new DynFieldNotFoundException(name, struct.getName());
242
                        }
243
                }
244

    
245
                public boolean hasDynValue(String name) {
246
                        return state.hasValue(name);
247
                }
248

    
249
                public void implement(DynClass dynClass) {
250
                        // Nothing to do
251
                }
252

    
253
                public Object invokeDynMethod(String name, Object[] args)
254
                                throws DynMethodException {
255
                        // Nothing to do
256
                        return null;
257
                }
258

    
259
                public Object invokeDynMethod(int code, Object[] args)
260
                                throws DynMethodException {
261
                        // Nothing to do
262
                        return null;
263
                }
264

    
265
                public void setDynValue(String name, Object value)
266
                                throws DynFieldNotFoundException {
267
                        // Nothing to do
268
                }
269
                public void clear() {
270
                        // Nothing to do
271
                }
272

    
273
        }
274

    
275
        public int getAutoValidation() {
276
                return autoValidationMode;
277
        }
278

    
279
        public void setAutoValidation(int validationMode) throws PersistenceException {
280
                switch (validationMode) {
281
                case DISABLED:
282
                case MANDATORY:
283
                case MANDATORY_IF_DECLARED:
284
                        autoValidationMode = validationMode;
285
                        break;
286
                default:
287
                        throw new PersistenceInvalidValidateModeException(validationMode);
288
                }
289
        }
290

    
291
        public PersistentState getState(Object obj)
292
                        throws PersistenceException, PersistenceValidateExceptions, PersistenceTypeNotSupportedException {
293
                return this.getState(obj, false);
294
        }
295

    
296
        public PersistentState getState(Object obj, boolean collectAllErrors)
297
                        throws PersistenceException {
298
                PersistentStateServices state = null;
299
                if( collectAllErrors ) {
300
                        PersistentContextServices context = this.getNewContext();
301
                        context.setCollectErrors(true);
302
                        try {
303
                                state = createState(obj, context);
304
                                context.setRootId(state.getId());
305
                                if (this.autoValidationMode != PersistenceManager.DISABLED){
306
                                        context.validate(this.autoValidationMode);
307
                                }
308
                        } catch(PersistenceException ex) {
309
                                context.addError(ex);
310
                        }
311
                } else {
312
                        PersistentContextServices context = this.getNewContext();
313
                        state = createState(obj, context);
314
                        context.setRootId(state.getId());
315
                        this.validateAll(state, this.autoValidationMode);
316
                }
317
                return state;
318
        }
319
        
320
        public PersistentStateServices createState(Object object, PersistentContextServices context) throws PersistenceException {
321

    
322
                PersistentStateServices state = createPersistentState(context);
323
                state.setTheClassName(object.getClass().getName());
324
                
325
                context.add(state, object);
326
                
327
                PersistenceFactory factory = this.factories.get(object);
328
                if (factory == null) {
329
                        throw new PersistenceTypeNotSupportedException(object
330
                                        .getClass());
331
                }
332
                state.setFactory(factory);
333
                state.setTheClassName(factory.getManagedClassName(object));
334
                factory.saveToState(state, object);
335
                return state;
336
        }
337

    
338
        public List getWrappedList(List list, PersistentContextServices context) {
339
                return new DelegatedList(list, this, context);
340
        }
341

    
342
        public Map getWrappedMap(Map map, PersistentContextServices context) {
343
                return new DelegatedMap(map, this, context);
344
        }
345

    
346
        public Set getWrappedSet(Set set, PersistentContextServices context) {
347
                return new DelegatedSet(set, this, context);
348
        }
349

    
350

    
351
        public Map getDomains() {
352
                return Collections.unmodifiableMap(domainsURL);
353
        }
354

    
355
        public List getDomainDefinitions(String domainName) {
356
                if (!domainsURL.containsKey(domainName)) {
357
                        throw new PersistenceDomainNotRegisterdException(domainName);
358
                }
359
                List definitions = new ArrayList();
360
                Iterator it = this.factories.iterator();
361
                while( it.hasNext() ) {
362
                        PersistenceFactory factory = (PersistenceFactory) it.next();
363
                        if( factory.getDomainName().equals(domainName)) {
364
                                List factDefinitions = factory.getDefinitions();
365
                                if(factDefinitions != null){
366
                                        definitions.addAll(factDefinitions);
367
                                }
368
                        }
369
                }
370
                return definitions;
371
        }
372

    
373
                        
374
        public DynStruct addDefinition(Class theClass, String name, String description,
375
                        String domainName, String domainUrl) {
376
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
377

    
378
                DynClass definition = dynman.createDynClass(PERSISTENCE_NAMESPACE, name, description);
379
                return addDefinition(theClass, definition, domainName, domainUrl);
380
        }
381

    
382
        public DynStruct addDefinition(Class theClass, String name, InputStream definitions, ClassLoader loader,
383
                        String domainName, String domainUrl) {
384
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
385
                Map x;
386
                try {
387
                        x = dynman.importDynClassDefinitions(definitions, loader, PersistenceManager.PERSISTENCE_NAMESPACE);
388
                } catch (XmlPullParserException e) {
389
                        throw new AddDefinitionException(e);
390
                } catch (IOException e) {
391
                        throw new AddDefinitionException(e);
392
                }
393
                DynClass definition = (DynClass) x.get(name);
394
                if( definition == null ) {
395
                        throw new CantFindDefinitionInStreamException(name, getKeys(x));
396
                }
397
                return addDefinition(theClass, definition, domainName, domainUrl);
398
        }
399

    
400
        private String getKeys(Map theMap) {
401
                List l = new ArrayList(theMap.keySet());
402
                return l.toString();
403
        }
404
        
405

    
406
        public DynStruct addDefinition(Class theClass, String name, Map definitions,
407
                        String domainName, String domainUrl) {
408
                DynClass definition = (DynClass) definitions.get(name);
409
                return addDefinition(theClass, definition, domainName, domainUrl);
410
                
411
        }
412

    
413
        protected  DynStruct addDefinition(Class theClass, DynClass definition,
414
                String domainName, String domainUrl) {
415
                if(theClass == DynObject.class){
416
                        return this.addDefinition(definition, domainName, domainUrl);
417
                }
418
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
419
                
420
                if(theClass.equals(DynObject.class)){
421
                        definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
422
                } else {
423
                        definition.setNamespace(PERSISTENCE_NAMESPACE);
424
                }
425
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
426
                        throw new DuplicatePersistentDefinitionException(definition.getName());
427
                }
428
                dynman.add(definition);
429
                
430
                PersistenceFactory factory = new SimplePersistenceFactory(
431
                                theClass, 
432
                                definition,
433
                                domainName, 
434
                                domainUrl
435
                        );
436
                this.factories.add(factory);
437
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
438
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
439
                return definition;
440
        }
441
        
442
        public DynStruct addDefinition(DynStruct definition, String domainName,
443
                        String domainUrl) throws AddDefinitionException {
444
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
445
                
446
                definition.setNamespace(PERSISTENCE_DYNOBJECT_NAMESPACE);
447
                if( dynman.get(definition.getNamespace(),definition.getName())!=null ) {
448
                        throw new DuplicatePersistentDefinitionException(definition.getFullName());
449
                }
450
                dynman.add((DynClass) definition);
451
                
452
                PersistenceFactory factory = this.factories.get(definition.getFullName());
453
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
454
                LOG.trace("Add persistence definition {}.", new Object[] { definition.getFullName() });
455
                return definition;
456
        }
457
        
458
        public void registerFactory(PersistenceFactory factory) {
459
                this.factories.add(factory);
460
                this.domainsURL.add(factory.getDomainName(), factory.getDomainURL());
461
                LOG.trace("Add persistence factory {}.", new Object[] { factory.getClass().getName() });
462
        }
463

    
464
        public void unregisterClass(Class theClass) {
465
                PersistenceFactory factory = this.factories.get(theClass.getName());
466
                if( factory == null ) {
467
                        return ;
468
                }
469
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
470
                DynStruct definition = factory.getDefinition(theClass.getName());
471

    
472
                dynman.remove(definition);
473
                this.factories.remove( factory);
474
                this.domainsURL.remove(factory.getDomainName());
475
        }
476

    
477
        public void unregisterClass(String name) {
478
                PersistenceFactory factory = this.factories.get(name);
479
                if( factory == null ) {
480
                        return ;
481
                }
482
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
483

    
484
                this.factories.remove( factory);
485
                this.domainsURL.remove(factory.getDomainName());
486

    
487
                DynStruct definition = factory.getDefinition(name);
488
                dynman.remove(definition);
489
        }
490

    
491
        public void unregisterFactory(PersistenceFactory factory) {
492
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
493

    
494
                this.factories.remove(factory);
495
                this.domainsURL.remove(factory.getDomainName());
496

    
497
                List definitions = factory.getDefinitions();
498
                if (definitions != null){
499
                        Iterator it = definitions.iterator();
500
                        while( it.hasNext() ) {
501
                                DynStruct definition = (DynStruct) it.next();
502
                                dynman.remove(definition);
503
                        }
504
                }
505
        }
506
        
507
        public PersistentStateServices createPersistentState(        PersistentContextServices context) {
508
                return this.createPersistentState(context, context.getNewIdentifier());
509
        }
510

    
511
}