Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / persistence / xml / ZipXMLPersistenceManager.java @ 628

History | View | Annotate | Download (10.6 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
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
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.tools.persistence.xml;
32

    
33
import java.io.IOException;
34
import java.io.InputStream;
35
import java.io.OutputStream;
36
import java.io.PrintWriter;
37
import java.text.MessageFormat;
38
import java.util.ArrayList;
39
import java.util.Iterator;
40
import java.util.List;
41
import java.util.Map;
42
import java.util.Map.Entry;
43
import java.util.zip.ZipEntry;
44
import java.util.zip.ZipInputStream;
45
import java.util.zip.ZipOutputStream;
46

    
47
import org.gvsig.tools.dataTypes.DataTypes;
48
import org.gvsig.tools.dynobject.DynField;
49
import org.gvsig.tools.dynobject.DynStruct;
50
import org.gvsig.tools.persistence.PersistentState;
51
import org.gvsig.tools.persistence.exception.PersistenceException;
52
import org.gvsig.tools.persistence.exception.PersistenceValidateExceptions;
53
import org.gvsig.tools.persistence.spi.PersistentContextServices;
54
import org.gvsig.tools.persistence.spi.PersistentStateServices;
55
import org.gvsig.tools.persistence.xml.exception.PersistenceMissingEntryInZIPException;
56
import org.gvsig.tools.persistence.xml.exception.PersistenceUnssuportedDefinitionTypeException;
57

    
58
/**
59
 * @author jmvivo
60
 *
61
 */
62
public class ZipXMLPersistenceManager extends XMLPersistenceManager {
63

    
64
        private static final String PERSISTENT_ZIP_ENTRY_NAME =
65
                        "state.xml";
66
        private static final String BASE_SCHEMA_ENTRY_NAME = "state_base.xsd";
67

    
68
        public PersistentState loadState(InputStream in)
69
                        throws PersistenceException {
70

    
71
                ZipInputStream zIn = new ZipInputStream(in);
72
                
73
                ZipEntry zEntry;
74
                try {
75
                        while ((zEntry = zIn.getNextEntry()) != null) {
76

    
77
                                if (zEntry.getName().equals(PERSISTENT_ZIP_ENTRY_NAME)) {
78
                                        return super.loadState(zIn);
79
                                }
80
                        }
81
                } catch (IOException e) {
82
                        throw new PersistenceException(e);
83
                }
84
                throw new PersistenceMissingEntryInZIPException(PERSISTENT_ZIP_ENTRY_NAME);
85
        }
86

    
87
        public void saveState(PersistentState state, OutputStream out)
88
                        throws PersistenceException, PersistenceValidateExceptions {
89

    
90
                ZipOutputStream zOut = new ZipOutputStream(out);
91
                List exceptions = new ArrayList();
92

    
93

    
94
                PersistentContextServices context = (PersistentContextServices) state.getContext();
95
                try{
96
                        // insert data
97
                        if( this.getAutoValidation() != DISABLED ) {
98
                                try {
99
                                        context.validate(this.getAutoValidation());
100
                                } catch(PersistenceValidateExceptions ex) {
101
                                        exceptions.add(ex);
102
                                }
103
                        }
104
                        zOut.putNextEntry(new ZipEntry(PERSISTENT_ZIP_ENTRY_NAME));
105
                        XMLPersistentStateWriter xmlWriter = getWriterInstance();
106

    
107
                        xmlWriter.write((PersistentStateServices) state, zOut, this
108
                                        .getDomains());
109

    
110
                        zOut.putNextEntry(new ZipEntry(BASE_SCHEMA_ENTRY_NAME));
111

    
112

    
113
                        // insert base schema
114
                        InputStream baseSchemaIs = ZipXMLPersistenceManager.class
115
                                        .getResourceAsStream("persistentState_base.xsd");
116
                        byte[] buff = new byte[1024*5];
117
                        int readed;
118
                        while ((readed = baseSchemaIs.read(buff)) > 0) {
119
                                zOut.write(buff, 0, readed);
120
                        }
121
                        baseSchemaIs.close();
122

    
123
                        // insert registered schemas
124
                        Map domains = this.getDomains();
125
                        Entry entry;
126
                        Iterator iterDomainsEntry = domains.entrySet().iterator();
127
                        while (iterDomainsEntry.hasNext()) {
128
                                entry = (Entry) iterDomainsEntry.next();
129
                                zOut.putNextEntry(new ZipEntry(entry.getKey()+".xsd"));
130
                                try {
131
                                writeSchema(zOut, (String) entry.getKey(), (String) entry
132
                                                .getValue());
133
                                } catch(CantGenerateXMLSchemaForDomainException ex) {
134
                                        exceptions.add(ex);
135
                                }
136
                        }
137

    
138
                        zOut.finish();
139

    
140
                } catch (Exception e) {
141
                        exceptions.add(e);
142
                }
143
                if( exceptions.size()>0 ) {
144
                        if( context.getCollectErrors() ) {
145
                                context.addError(new CantSaveStateException(exceptions));
146
                        } else {
147
                                throw new CantSaveStateException(exceptions);
148
                        }
149
                }
150

    
151
        }
152

    
153
        private void writeSchema(OutputStream out, String domainName,
154
                        String domainURL) throws PersistenceException  {
155
                PrintWriter printer = new PrintWriter(out);
156
                printer.println(MessageFormat.format(
157
                                ZipXMLSchemaConstants.XSD_HEAD_VALUE,
158
                                new Object[] {
159
                                                domainName, domainURL }));
160

    
161

    
162
                List exceptions = new ArrayList();
163

    
164
                List domainDefinitions = getDomainDefinitions(domainName);
165
                Iterator iter = domainDefinitions.iterator();
166
                while (iter.hasNext()) {
167
                        DynStruct definition = (DynStruct) iter.next();
168
                        try {
169
                                writeClassDefinitionSchema(printer, definition.getName(), definition);
170
                        } catch(CantGenerateXMLSchemaForDefinitionException ex) {
171
                                exceptions.add(ex);
172
                        }
173
                }
174

    
175
                printer.println(ZipXMLSchemaConstants.XSD_END);
176
                printer.flush();
177
                if( exceptions.size()>0 ) {
178
                        throw new CantGenerateXMLSchemaForDomainException(domainName, exceptions);
179
                }
180

    
181
        }
182

    
183
        private void writeClassDefinitionSchema(PrintWriter printer,
184
                        String className, DynStruct definition) throws PersistenceException {
185

    
186
                List exceptions = new ArrayList();
187
                
188
                printer.print(MessageFormat.format(
189
                                ZipXMLSchemaConstants.XSD_START_CLASS_VALUE,
190
                                new Object[] { className }));
191

    
192
                DynField[] fields = definition.getDynFields();
193
                DynField field;
194
                String typeId = "";
195

    
196
                boolean allowNull;
197

    
198
                for (int i = 0; i < fields.length; i++) {
199
                        field = fields[i];
200
                        if (!field.isPersistent()) {
201
                                continue;
202
                        }
203
                        allowNull = field.isMandatory() && field.getDefaultValue() == null;
204
                        
205
                        if (field.getDataType().isObject()
206
                                        || field.getDataType().isDynObject()) {
207
                                if (allowNull) {
208
                                        typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_OBJECT;
209
                                } else {
210
                                        typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_OBJECT_NOTNULL;
211
                                }
212
                        } else {
213
                                switch (field.getType()) {
214
                                case DataTypes.STRING:
215
                                case DataTypes.FILE:
216
                                case DataTypes.FOLDER:
217
                                case DataTypes.URL:
218
                                case DataTypes.URI:
219
                                        if (allowNull) {
220
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_STRING;
221
                                        } else {
222
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_STRING_NOTNULL;
223
                                        }
224
                                        break;
225
                                case DataTypes.BOOLEAN:
226
                                        if (allowNull) {
227
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_BOOLEAN;
228
                                        } else {
229
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_BOOLEAN_NOTNULL;
230
                                        }
231
                                        break;
232
                                case DataTypes.INT:
233
                                        if (allowNull) {
234
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_INTEGER;
235
                                        } else {
236
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_INTEGER_NOTNULL;
237
                                        }
238
                                        break;
239
        
240
                                case DataTypes.LONG:
241
                                        if (allowNull) {
242
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_LONG;
243
                                        } else {
244
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_LONG_NOTNULL;
245
                                        }
246
                                        break;
247
        
248
                                case DataTypes.FLOAT:
249
                                        if (allowNull) {
250
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_FLOAT;
251
                                        } else {
252
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_FLOAT_NOTNULL;
253
                                        }
254
                                        break;
255
        
256
                                case DataTypes.DOUBLE:
257
                                        if (allowNull) {
258
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_FLOAT;
259
                                        } else {
260
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_FLOAT_NOTNULL;
261
                                        }
262
                                        break;
263
        
264
                                case DataTypes.SET:
265
                                        if (allowNull) {
266
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_SET;
267
                                        } else {
268
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_SET_NOTNULL;
269
                                        }
270
                                        break;
271
        
272
                                case DataTypes.LIST:
273
                                        if (allowNull) {
274
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_LIST;
275
                                        } else {
276
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_LIST_NOTNULL;
277
                                        }
278
                                        break;
279
        
280
                                case DataTypes.ARRAY:
281
                                        if (allowNull) {
282
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_ARRAY;
283
                                        } else {
284
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_ARRAY_NOTNULL;
285
                                        }
286
                                        break;
287
        
288
                                case DataTypes.MAP:
289
                                        if (allowNull) {
290
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_MAP;
291
                                        } else {
292
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_MAP_NOTNULL;
293
                                        }
294
                                        break;
295
        
296
                                case DataTypes.DATE:
297
                                        if (allowNull) {
298
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_DATE;
299
                                        } else {
300
                                                typeId = ZipXMLSchemaConstants.XSD_ATTRUBUTE_TYPE_DATE_NOTNULL;
301
                                        }
302
                                        break;
303
        
304
                                default:
305
                                        exceptions.add(new PersistenceUnssuportedDefinitionTypeException(className, definition, field));
306
                                }
307
                        }
308
                        
309
                        if (field.isMandatory()) {
310
                                printer.print(MessageFormat.format(
311
                                                ZipXMLSchemaConstants.XSD_ATTRUBUTE_MANDATORY_VALUE,
312
                                                new String[] { field.getName(), typeId }));
313
                        } else {
314
                                printer.print(MessageFormat.format(
315
                                                ZipXMLSchemaConstants.XSD_ATTRUBUTE_VALUE,
316
                                                new String[] { field.getName(), typeId }));
317
                        }
318
                }
319

    
320
                printer.println(ZipXMLSchemaConstants.XSD_END_CLASS);
321
                if( exceptions.size()>0 ) {
322
                        throw new CantGenerateXMLSchemaForDefinitionException(className, exceptions);
323
                }
324
        }
325

    
326
        public class CantGenerateXMLSchemaForDefinitionException extends PersistenceException {
327

    
328
                /**
329
                 * 
330
                 */
331
                private static final long serialVersionUID = 2828756207089264709L;
332
                
333
                CantGenerateXMLSchemaForDefinitionException(String className, List exceptions) {
334
                        super(
335
                                        "Can't generate xml schema definition for the class %(classname).",
336
                                        "_Cant_generate_xml_schema_definition_for_the_class_XclassnameX",
337
                                        serialVersionUID
338
                        );
339
                        this.addAll(exceptions);
340
                        setValue("classname",className);
341
                }
342
        }
343
        public class CantGenerateXMLSchemaForDomainException extends PersistenceException {
344

    
345
                /**
346
                 * 
347
                 */
348
                private static final long serialVersionUID = 2828756207089264709L;
349
                
350
                CantGenerateXMLSchemaForDomainException(String domainName, List exceptions) {
351
                        super(
352
                                        "Can't generate xml schema definition for domain '%(domain).",
353
                                        "_Cant_generate_xml_schema_definition_for_domain_XdomainX",
354
                                        serialVersionUID
355
                        );
356
                        this.addAll(exceptions);
357
                        setValue("domain",domainName);
358
                }
359
        }
360
        public class CantSaveStateException extends PersistenceException {
361

    
362
                /**
363
                 * 
364
                 */
365
                private static final long serialVersionUID = 7255882015705477288L;
366

    
367
                CantSaveStateException(List exceptions) {
368
                        super(
369
                                        "Can't save state.",
370
                                        "_Cant_save_state",
371
                                        serialVersionUID
372
                        );
373
                        this.addAll(exceptions);
374
                }
375
        }
376
}