Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libTools / src / org / gvsig / tools / persistence / xml / XMLPersistentStateReader.java @ 30207

History | View | Annotate | Download (12.4 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.util.ArrayList;
35
import java.util.Date;
36
import java.util.HashMap;
37
import java.util.HashSet;
38
import java.util.List;
39
import java.util.Map;
40
import java.util.Set;
41

    
42
import org.gvsig.tools.persistence.PersistenceException;
43
import org.gvsig.tools.persistence.PersistenceRuntimeException;
44
import org.gvsig.tools.persistence.impl.ImplementationPersistentState;
45
import org.gvsig.tools.persistence.impl.ObjectReference;
46
import org.gvsig.tools.persistence.impl.PersistentContext;
47
import org.xmlpull.v1.XmlPullParser;
48
import org.xmlpull.v1.XmlPullParserException;
49

    
50
/**
51
 * @author jmvivo
52
 *
53
 */
54
public class XMLPersistentStateReader implements XMLPersistentConstants {
55
        private XMLPersistenceManager manager;
56
        private XmlPullParser parser;
57
        private PersistentContext context;
58

    
59
        public XMLPersistentStateReader(XMLPersistenceManager persistenceManager) {
60
                this.manager = persistenceManager;
61
        }
62

    
63
        public void read(PersistentContext context, XmlPullParser parser)
64
                        throws PersistenceException {
65
                this.parser = parser;
66
                this.context = context;
67

    
68
                try {
69
                        parser.nextTag();
70
                        parser.require(XmlPullParser.START_TAG, "", ROOT_TAG);
71
                        parser.nextTag();
72
                        this.parser.require(XmlPullParser.START_TAG, null, VERSION_TAG);
73
                        String persistenceVersion = this.parser.nextText();
74
                        if (!persistenceVersion.trim().equals(manager.version().trim())) {
75
                                // TODO handle version
76
                        }
77
                        parser.require(XmlPullParser.END_TAG, "", VERSION_TAG);
78

    
79
                        parser.nextTag();
80
                        parser.require(XmlPullParser.START_TAG, "", ROOTSTATE_TAG);
81

    
82
                        String rootStateIdStr = this.parser.getAttributeValue("",
83
                                        ROOSTATE_ID_ATTR);
84
                        if (rootStateIdStr == null){
85
                                throw new PersistenceRuntimeException(
86
                                                "missing root state id attribute");
87
                        }
88
                        parser.nextTag();
89
                        this.parser.require(XmlPullParser.END_TAG, "", ROOTSTATE_TAG);
90

    
91
                        parser.nextTag();
92
                        this.parser.require(XmlPullParser.START_TAG, "", STATES_TAG);
93
                        parser.nextTag();
94

    
95
                        ImplementationPersistentState state;
96
                        String curTagName, curIdstr, curClassName;
97
                        Integer curId;
98
                        String namespace, stateTagName;
99

    
100
                        while (!(parser.getEventType() == XmlPullParser.END_TAG && parser
101
                                        .getName().equals(STATES_TAG))) {
102
                                checkDocumentEnd();
103
                                parser.require(XmlPullParser.START_TAG, null, null);
104

    
105
                                stateTagName = parser.getName();
106
                                namespace = parser.getNamespace();
107

    
108
                                state = this.manager.createPersistentStateInstance(context);
109
                                curIdstr = parser.getAttributeValue(null, STATE_ID_ATTR);
110
                                if (curIdstr == null){
111
                                        throw new PersistenceRuntimeException(
112
                                                        "missing state "+STATE_ID_ATTR+" attribute (row:"+
113
                                                        parser.getLineNumber()+
114
                                                        " col: "+parser.getColumnNumber()+")");
115
                                }
116
                                try{
117
                                        curId = new Integer(curIdstr);
118
                                } catch (NumberFormatException e) {
119
                                        throw new PersistenceRuntimeException(
120
                                                        "invalid state "+STATE_ID_ATTR+" attribute (row:"+
121
                                                        parser.getLineNumber()+
122
                                                        " col: "+parser.getColumnNumber()+")",e);
123
                                }
124
                                curClassName = stateTagName;
125
                                state.setId(curId);
126
                                state.setTheClassName(curClassName);
127

    
128
                                context.addReference(curId, state);
129

    
130
                                parser.nextTag();
131

    
132
                                parser.require(XmlPullParser.START_TAG, null, null);
133
                                while (!(parser.getEventType() == XmlPullParser.END_TAG && parser
134
                                                .getName().equals(stateTagName))) {
135
                                        curTagName = parser.getName();
136
                                        if (VALUE_ITEM_GENERIC.equals(parser.getName())) {
137
                                                // Load value with name and value within tags
138
                                                loadGenericTagValue(state);
139
                                        } else {
140
                                                loadTagValue(state);
141
                                        }
142
                                        parser.require(XmlPullParser.END_TAG, null, curTagName);
143
                                        parser.nextTag();
144
                                        checkDocumentEnd();
145
                                }
146
                                parser.require(XmlPullParser.END_TAG, namespace, stateTagName);
147
                                parser.nextTag();
148

    
149
                        }
150

    
151
                        context.setRoot(new Integer(rootStateIdStr));
152
                        parser.nextTag();
153
                        this.parser.require(XmlPullParser.END_TAG, "", ROOT_TAG);
154
                        parser.next();
155
                        this.parser.require(XmlPullParser.END_DOCUMENT, null, null);
156
                } catch (PersistenceException e) {
157
                        throw e;
158
                } catch (PersistenceRuntimeException e) {
159
                        throw e;
160
                } catch (Exception e) {
161
                        throw new PersistenceRuntimeException("Exception in parse input", e);
162
                }
163

    
164

    
165
        }
166

    
167
        private void loadTagValue(ImplementationPersistentState state)
168
                        throws XmlPullParserException, IOException, PersistenceException {
169
                String type = parser.getAttributeValue(null, VALUE_TYPE_ATTR);
170
                if (type == null) {
171
                        throw new PersistenceRuntimeException("missing value "
172
                                        + VALUE_TYPE_ATTR + " attribute (row:"
173
                                        + parser.getLineNumber() + " col: "
174
                                        + parser.getColumnNumber() + ")");
175

    
176
                }
177
                String name = parser.getName();
178
                state.setInternal(name, getValue(type));
179
                // position end tag of {name}
180

    
181
        }
182

    
183
        private void loadGenericTagValue(ImplementationPersistentState state)
184
                        throws XmlPullParserException, IOException, PersistenceException {
185
                String type = parser.getAttributeValue(null, VALUE_TYPE_ATTR);
186
                if (type == null) {
187
                        throw new PersistenceRuntimeException("missing value "
188
                                        + VALUE_TYPE_ATTR + " attribute (row:"
189
                                        + parser.getLineNumber() + " col: "
190
                                        + parser.getColumnNumber() + ")");
191

    
192
                }
193
                parser.nextTag();
194
                parser.require(XmlPullParser.START_TAG, "", NAMEVALUE_TAG);
195
                String name = parser.nextText();
196
                parser.require(XmlPullParser.END_TAG, "", NAMEVALUE_TAG);
197
                parser.nextTag();
198
                parser.require(XmlPullParser.START_TAG, "", DATAVALUE_TAG);
199
                state.setInternal(name, getValue(type));
200
                parser.require(XmlPullParser.END_TAG, "", DATAVALUE_TAG);
201
                parser.nextTag();
202
                // position end tag 'value'
203
        }
204

    
205
        private Object getValue(String type) throws XmlPullParserException,
206
                        IOException, PersistenceException {
207
                if (type.equals(TYPE_NULL)) {
208
                        parser.nextTag();
209
                        return null;
210
                } else if (type.equals(TYPE_STRING)) {
211
                        return parser.nextText();
212
                } else if (type.equals(TYPE_BOOLEAN)) {
213
                        return getValueBoolean();
214
                } else if (type.equals(TYPE_DATE)) {
215
                        return getValueDate();
216
                } else if (TYPES_NUMBER.contains(type)) {
217
                        return getValueNumber(type);
218
                } else if (type.equals(TYPE_REFERENCE)) {
219
                        return getValueReference();
220
                } else if (type.equals(TYPE_LIST)) {
221
                        return getValueList();
222
                } else if (type.equals(TYPE_SET)) {
223
                        return getValueSet();
224
                } else if (type.equals(TYPE_MAP)) {
225
                        return getValueMap();
226
                } else {
227
                        throw new PersistenceRuntimeException("invalid value type: " + type
228
                                        + " (row:" + parser.getLineNumber() + " col: "
229
                                        + parser.getColumnNumber() + ")");
230
                }
231

    
232
        }
233

    
234

    
235
        private Boolean getValueBoolean() throws XmlPullParserException,
236
                        IOException {
237
                String value = parser.nextText();
238
                // XXX: do any check for valid values ???
239
                return new Boolean(value);
240
        }
241

    
242
        private Date getValueDate() throws XmlPullParserException,
243
                        IOException {
244
                String value = parser.nextText();
245
                Long time;
246
                try {
247
                        time = new Long(value);
248
                } catch (NumberFormatException e) {
249
                        throw new PersistenceRuntimeException("invalid value for date (row:"
250
                                        + parser.getLineNumber() + " col: "
251
                                        + parser.getColumnNumber() + ")", e);
252
                }
253
                return new Date(time.longValue());
254
        }
255

    
256
        private Number getValueNumber(String type) throws XmlPullParserException,
257
                        IOException {
258
                String valueStr = parser.nextText();
259
                Number value = null;
260
                try {
261
                        if (TYPE_INTEGER.equals(type)){
262
                                value = new Integer(valueStr);
263
                        } else if (TYPE_LONG.equals(type)) {
264
                                value = new Long(valueStr);
265
                        } else if (TYPE_FLOAT.equals(type)) {
266
                                value = new Float(valueStr);
267
                        } else if (TYPE_DOUBLE.equals(type)) {
268
                                value = new Double(valueStr);
269
                        }
270

    
271
                } catch (NumberFormatException e) {
272
                        throw new PersistenceRuntimeException("invalid value for " + type
273
                                        + " (row:"
274
                                        + parser.getLineNumber() + " col: "
275
                                        + parser.getColumnNumber() + ")", e);
276
                }
277

    
278
                return value;
279
        }
280
        private ObjectReference getValueReference() throws XmlPullParserException,
281
                        IOException, PersistenceException {
282
                parser.nextTag();
283
                parser.require(XmlPullParser.START_TAG, "", REFERENCE_TAG);
284
                String idstr = parser.getAttributeValue("", REFERENCE_ID_ATTR);
285
                if (idstr == null) {
286
                        throw new PersistenceRuntimeException("missing object reference "
287
                                        + REFERENCE_ID_ATTR + " attribute (row:"
288
                                        + parser.getLineNumber() + " col: "
289
                                        + parser.getColumnNumber() + ")");
290

    
291
                }
292
                Integer id;
293
                try{
294
                        id = new Integer(idstr);
295
                } catch (NumberFormatException e) {
296
                        throw new PersistenceRuntimeException("invalid object reference "
297
                                        + STATE_ID_ATTR + " attribute (row:"
298
                                        + parser.getLineNumber() + " col: "
299
                                        + parser.getColumnNumber() + ")", e);
300

    
301
                }
302
                parser.nextTag();
303
                parser.require(XmlPullParser.END_TAG, "", REFERENCE_TAG);
304
                parser.nextTag();
305
                return manager.createrObjectReference(id);
306

    
307
        }
308

    
309
        private List getValueList() throws XmlPullParserException, IOException,
310
                        PersistenceException {
311
                parser.nextTag();
312
                List list = new ArrayList();
313
                String type;
314
                while (parser.getEventType() == XmlPullParser.START_TAG
315
                                && LISTITEM_TAG.equals(parser.getName())) {
316

    
317
                        type = parser.getAttributeValue("", VALUE_TYPE_ATTR);
318
                        if (type == null) {
319
                                throw new PersistenceRuntimeException("missing list item "
320
                                                + VALUE_TYPE_ATTR + " attribute (row:"
321
                                                + parser.getLineNumber() + " col: "
322
                                                + parser.getColumnNumber() + ")");
323

    
324
                        }
325

    
326
                        list.add(getValue(type));
327

    
328

    
329
                        parser.require(XmlPullParser.END_TAG, "", LISTITEM_TAG);
330
                        parser.nextTag();
331
                }
332
                return manager.createList(list, context);
333
        }
334

    
335
        private Set getValueSet() throws XmlPullParserException, IOException,
336
                        PersistenceException {
337
                parser.nextTag();
338
                Set set = new HashSet();
339
                String type;
340
                while (parser.getEventType() == XmlPullParser.START_TAG
341
                                && SETITEM_TAG.equals(parser.getName())) {
342

    
343
                        type = parser.getAttributeValue("", VALUE_TYPE_ATTR);
344
                        if (type == null) {
345
                                throw new PersistenceRuntimeException("missing set item "
346
                                                + VALUE_TYPE_ATTR + " attribute (row:"
347
                                                + parser.getLineNumber() + " col: "
348
                                                + parser.getColumnNumber() + ")");
349

    
350
                        }
351

    
352
                        set.add(getValue(type));
353

    
354
                        parser.require(XmlPullParser.END_TAG, "", SETITEM_TAG);
355
                        parser.nextTag();
356
                }
357
                return manager.createSet(set, context);
358

    
359
        }
360

    
361
        private void checkDocumentEnd() throws XmlPullParserException {
362
                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
363
                        throw new PersistenceRuntimeException("Unspected end of document");
364
                }
365

    
366
        }
367

    
368

    
369
        private Map getValueMap() throws XmlPullParserException, IOException,
370
                        PersistenceException {
371
                parser.nextTag();
372
                Map map = new HashMap();
373
                String keyType, valueType;
374
                Object key, value;
375
                while (parser.getEventType() == XmlPullParser.START_TAG
376
                                && MAPITEM_TAG.equals(parser.getName())) {
377

    
378
                        parser.nextTag();
379
                        parser.require(XmlPullParser.START_TAG, "", MAPKEY_TAG);
380
                        keyType = parser.getAttributeValue("", VALUE_TYPE_ATTR);
381
                        if (keyType == null) {
382
                                throw new PersistenceRuntimeException("missing key map item "
383
                                                + VALUE_TYPE_ATTR + " attribute (row:"
384
                                                + parser.getLineNumber() + " col: "
385
                                                + parser.getColumnNumber() + ")");
386

    
387
                        }
388
                        key = getValue(keyType);
389

    
390
                        parser.require(XmlPullParser.END_TAG, "", MAPKEY_TAG);
391
                        parser.nextTag();
392
                        parser.require(XmlPullParser.START_TAG, "", MAPVALUE_TAG);
393

    
394
                        valueType = parser.getAttributeValue("", VALUE_TYPE_ATTR);
395
                        if (valueType == null) {
396
                                throw new PersistenceRuntimeException("missing value map item "
397
                                                + VALUE_TYPE_ATTR + " attribute (row:"
398
                                                + parser.getLineNumber() + " col: "
399
                                                + parser.getColumnNumber() + ")");
400

    
401
                        }
402

    
403
                        value = getValue(valueType);
404

    
405
                        parser.require(XmlPullParser.END_TAG, "", MAPVALUE_TAG);
406
                        parser.nextTag();
407

    
408
                        map.put(key, value);
409

    
410
                        parser.require(XmlPullParser.END_TAG, "", MAPITEM_TAG);
411
                        parser.nextTag();
412
                }
413
                return manager.createMap(map, context);
414
        }
415
}