Statistics
| Revision:

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

History | View | Annotate | Download (12.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.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, null, 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 = getClassNameFromTag(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 String getClassNameFromTag(String stateTagName) {
168
                int index = stateTagName.indexOf(":");
169
                if (index < 1) {
170
                        return stateTagName;
171
                }
172
                return stateTagName.substring(index + 1);
173
        }
174

    
175
        private void loadTagValue(ImplementationPersistentState state)
176
                        throws XmlPullParserException, IOException, PersistenceException {
177
                String type = parser.getAttributeValue(null, VALUE_TYPE_ATTR);
178
                if (type == null) {
179
                        throw new PersistenceRuntimeException("missing value "
180
                                        + VALUE_TYPE_ATTR + " attribute (row:"
181
                                        + parser.getLineNumber() + " col: "
182
                                        + parser.getColumnNumber() + ")");
183

    
184
                }
185
                String name = parser.getName();
186
                state.setInternal(name, getValue(type));
187
                // position end tag of {name}
188

    
189
        }
190

    
191
        private void loadGenericTagValue(ImplementationPersistentState state)
192
                        throws XmlPullParserException, IOException, PersistenceException {
193
                String type = parser.getAttributeValue(null, VALUE_TYPE_ATTR);
194
                if (type == null) {
195
                        throw new PersistenceRuntimeException("missing value "
196
                                        + VALUE_TYPE_ATTR + " attribute (row:"
197
                                        + parser.getLineNumber() + " col: "
198
                                        + parser.getColumnNumber() + ")");
199

    
200
                }
201
                parser.nextTag();
202
                parser.require(XmlPullParser.START_TAG, "", NAMEVALUE_TAG);
203
                String name = parser.nextText();
204
                parser.require(XmlPullParser.END_TAG, "", NAMEVALUE_TAG);
205
                parser.nextTag();
206
                parser.require(XmlPullParser.START_TAG, "", DATAVALUE_TAG);
207
                state.setInternal(name, getValue(type));
208
                parser.require(XmlPullParser.END_TAG, "", DATAVALUE_TAG);
209
                parser.nextTag();
210
                // position end tag 'value'
211
        }
212

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

    
240
        }
241

    
242

    
243
        private Boolean getValueBoolean() throws XmlPullParserException,
244
                        IOException {
245
                String value = parser.nextText();
246
                // XXX: do any check for valid values ???
247
                return new Boolean(value);
248
        }
249

    
250
        private Date getValueDate() throws XmlPullParserException,
251
                        IOException {
252
                String value = parser.nextText();
253
                Long time;
254
                try {
255
                        time = new Long(value);
256
                } catch (NumberFormatException e) {
257
                        throw new PersistenceRuntimeException("invalid value for date (row:"
258
                                        + parser.getLineNumber() + " col: "
259
                                        + parser.getColumnNumber() + ")", e);
260
                }
261
                return new Date(time.longValue());
262
        }
263

    
264
        private Number getValueNumber(String type) throws XmlPullParserException,
265
                        IOException {
266
                String valueStr = parser.nextText();
267
                Number value = null;
268
                try {
269
                        if (TYPE_INTEGER.equals(type)){
270
                                value = new Integer(valueStr);
271
                        } else if (TYPE_LONG.equals(type)) {
272
                                value = new Long(valueStr);
273
                        } else if (TYPE_FLOAT.equals(type)) {
274
                                value = new Float(valueStr);
275
                        } else if (TYPE_DOUBLE.equals(type)) {
276
                                value = new Double(valueStr);
277
                        }
278

    
279
                } catch (NumberFormatException e) {
280
                        throw new PersistenceRuntimeException("invalid value for " + type
281
                                        + " (row:"
282
                                        + parser.getLineNumber() + " col: "
283
                                        + parser.getColumnNumber() + ")", e);
284
                }
285

    
286
                return value;
287
        }
288
        private ObjectReference getValueReference() throws XmlPullParserException,
289
                        IOException, PersistenceException {
290
                parser.nextTag();
291
                parser.require(XmlPullParser.START_TAG, "", REFERENCE_TAG);
292
                String idstr = parser.getAttributeValue("", REFERENCE_ID_ATTR);
293
                if (idstr == null) {
294
                        throw new PersistenceRuntimeException("missing object reference "
295
                                        + REFERENCE_ID_ATTR + " attribute (row:"
296
                                        + parser.getLineNumber() + " col: "
297
                                        + parser.getColumnNumber() + ")");
298

    
299
                }
300
                Integer id;
301
                try{
302
                        id = new Integer(idstr);
303
                } catch (NumberFormatException e) {
304
                        throw new PersistenceRuntimeException("invalid object reference "
305
                                        + STATE_ID_ATTR + " attribute (row:"
306
                                        + parser.getLineNumber() + " col: "
307
                                        + parser.getColumnNumber() + ")", e);
308

    
309
                }
310
                parser.nextTag();
311
                parser.require(XmlPullParser.END_TAG, "", REFERENCE_TAG);
312
                parser.nextTag();
313
                return manager.createrObjectReference(id);
314

    
315
        }
316

    
317
        private List getValueList() throws XmlPullParserException, IOException,
318
                        PersistenceException {
319
                parser.nextTag();
320
                List list = new ArrayList();
321
                String type;
322
                while (parser.getEventType() == XmlPullParser.START_TAG
323
                                && LISTITEM_TAG.equals(parser.getName())) {
324

    
325
                        type = parser.getAttributeValue("", VALUE_TYPE_ATTR);
326
                        if (type == null) {
327
                                throw new PersistenceRuntimeException("missing list item "
328
                                                + VALUE_TYPE_ATTR + " attribute (row:"
329
                                                + parser.getLineNumber() + " col: "
330
                                                + parser.getColumnNumber() + ")");
331

    
332
                        }
333

    
334
                        list.add(getValue(type));
335

    
336

    
337
                        parser.require(XmlPullParser.END_TAG, "", LISTITEM_TAG);
338
                        parser.nextTag();
339
                }
340
                return manager.createList(list, context);
341
        }
342

    
343
        private Set getValueSet() throws XmlPullParserException, IOException,
344
                        PersistenceException {
345
                parser.nextTag();
346
                Set set = new HashSet();
347
                String type;
348
                while (parser.getEventType() == XmlPullParser.START_TAG
349
                                && SETITEM_TAG.equals(parser.getName())) {
350

    
351
                        type = parser.getAttributeValue("", VALUE_TYPE_ATTR);
352
                        if (type == null) {
353
                                throw new PersistenceRuntimeException("missing set item "
354
                                                + VALUE_TYPE_ATTR + " attribute (row:"
355
                                                + parser.getLineNumber() + " col: "
356
                                                + parser.getColumnNumber() + ")");
357

    
358
                        }
359

    
360
                        set.add(getValue(type));
361

    
362
                        parser.require(XmlPullParser.END_TAG, "", SETITEM_TAG);
363
                        parser.nextTag();
364
                }
365
                return manager.createSet(set, context);
366

    
367
        }
368

    
369
        private void checkDocumentEnd() throws XmlPullParserException {
370
                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
371
                        throw new PersistenceRuntimeException("Unspected end of document");
372
                }
373

    
374
        }
375

    
376

    
377
        private Map getValueMap() throws XmlPullParserException, IOException,
378
                        PersistenceException {
379
                parser.nextTag();
380
                Map map = new HashMap();
381
                String keyType, valueType;
382
                Object key, value;
383
                while (parser.getEventType() == XmlPullParser.START_TAG
384
                                && MAPITEM_TAG.equals(parser.getName())) {
385

    
386
                        parser.nextTag();
387
                        parser.require(XmlPullParser.START_TAG, "", MAPKEY_TAG);
388
                        keyType = parser.getAttributeValue("", VALUE_TYPE_ATTR);
389
                        if (keyType == null) {
390
                                throw new PersistenceRuntimeException("missing key map item "
391
                                                + VALUE_TYPE_ATTR + " attribute (row:"
392
                                                + parser.getLineNumber() + " col: "
393
                                                + parser.getColumnNumber() + ")");
394

    
395
                        }
396
                        key = getValue(keyType);
397

    
398
                        parser.require(XmlPullParser.END_TAG, "", MAPKEY_TAG);
399
                        parser.nextTag();
400
                        parser.require(XmlPullParser.START_TAG, "", MAPVALUE_TAG);
401

    
402
                        valueType = parser.getAttributeValue("", VALUE_TYPE_ATTR);
403
                        if (valueType == null) {
404
                                throw new PersistenceRuntimeException("missing value map item "
405
                                                + VALUE_TYPE_ATTR + " attribute (row:"
406
                                                + parser.getLineNumber() + " col: "
407
                                                + parser.getColumnNumber() + ")");
408

    
409
                        }
410

    
411
                        value = getValue(valueType);
412

    
413
                        parser.require(XmlPullParser.END_TAG, "", MAPVALUE_TAG);
414
                        parser.nextTag();
415

    
416
                        map.put(key, value);
417

    
418
                        parser.require(XmlPullParser.END_TAG, "", MAPITEM_TAG);
419
                        parser.nextTag();
420
                }
421
                return manager.createMap(map, context);
422
        }
423
}