Statistics
| Revision:

svn-gvsig-desktop / branches / v02_desarrollo / libraries / sld / temp / org.gvsig.sldsupport.lib.impl / src / main / java / org / gvsig / sldsupport / impl / sld / handler / Handler.java @ 40827

History | View | Annotate | Download (10.9 KB)

1
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib��ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.sldsupport.impl.sld.handler;
42

    
43

    
44
import java.io.File;
45
import java.io.FileOutputStream;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.OutputStream;
49
import java.io.OutputStreamWriter;
50
import java.util.ArrayList;
51
import java.util.HashMap;
52
import java.util.List;
53
import java.util.Map;
54

    
55
import org.gvsig.sldsupport.exception.InvalidSLDObjectException;
56
import org.gvsig.sldsupport.exception.SLDException;
57
import org.gvsig.sldsupport.exception.SLDReadException;
58
import org.gvsig.sldsupport.exception.UnsupportedSLDObjectException;
59
import org.gvsig.sldsupport.exception.UnsupportedSLDVersionException;
60
import org.gvsig.sldsupport.impl.parser.ExtendedKXmlParser;
61
import org.gvsig.sldsupport.impl.sld.parsing.FeatureStyleElement;
62
import org.gvsig.sldsupport.impl.sld.parsing.NamedLayerElement;
63
import org.gvsig.sldsupport.impl.sld.parsing.UserLayerElement;
64
import org.gvsig.sldsupport.impl.sld.parsing.symbol.SymbolElement;
65
import org.gvsig.sldsupport.impl.util.SLDUtils;
66
import org.gvsig.sldsupport.impl.util.XmlBuilder;
67
import org.gvsig.sldsupport.sld.SLDObject;
68
import org.gvsig.sldsupport.sld.SLDRoot;
69
import org.gvsig.sldsupport.sld.SLDTags;
70
import org.gvsig.sldsupport.sld.layer.SLDLayer;
71
import org.gvsig.sldsupport.sld.layer.SLDNamedLayer;
72
import org.gvsig.sldsupport.sld.layer.SLDUserLayer;
73
import org.gvsig.sldsupport.sld.style.SLDFeatureStyle;
74
import org.gvsig.sldsupport.sld.symbol.SLDSymbol;
75
import org.kxml2.io.KXmlParser;
76
import org.xmlpull.v1.XmlPullParser;
77
import org.xmlpull.v1.XmlPullParserException;
78

    
79

    
80
public class Handler {
81

    
82
        private static List<String> versions = new ArrayList<String>();
83
        
84
        static {
85
                versions.add("1.0.0");
86
                versions.add("1.1.0");
87
        }
88
        
89
        public Handler() {
90
                
91
        }
92

    
93
        public static SLDObject parse(InputStream inStream, String encoding, String version)
94
                        throws XmlPullParserException, IOException, SLDException {
95
                
96
                int tag;
97
                XmlPullParser parser = new ExtendedKXmlParser();
98
                parser.setInput(inStream, encoding);
99

    
100
                tag = parser.getEventType();
101
                if (tag == XmlPullParser.START_DOCUMENT) {
102
                        parser.nextTag();
103
                        parser.require(KXmlParser.START_TAG, null, SLDTags.SLD_ROOT);
104
                        // Now we are in root
105
                } else {
106
                        if (tag != XmlPullParser.START_TAG) {
107
                                throw new IOException(
108
                                                "Misplaced input stream (it's not before opening tag)");
109
                        }
110
                }
111
                
112
                String name = parser.getName();
113
                String v = null;
114
                
115
                if (name.compareToIgnoreCase(SLDTags.SLD_ROOT) == 0) {
116
                        v = parser.getAttributeValue(null, SLDTags.VERSION_ATTR);
117
                        if (v == null) {
118
                                throw new SLDReadException(
119
                                                "Version attribute is missing in " + SLDTags.SLD_ROOT);
120
                        }
121
                        
122
                        SLDRoot root = parseRoot(parser, v);
123
                        tag = parser.getEventType();
124
                        // Must be end-document
125
                        if (tag != KXmlParser.END_DOCUMENT) {
126
                                throw new SLDReadException(
127
                                                "Expected end of document after closing '"
128
                                                + SLDTags.SLD_ROOT + "' tag");
129
                        }
130
                        return root;
131
                        
132
                } else {
133
                        if (name.compareToIgnoreCase(SLDTags.FEATURESTYLE) == 0
134
                                        || name.compareToIgnoreCase(SLDTags.FEATURETYPESTYLE) == 0) {
135
                                /*
136
                                 * This line is out of the SLD standard
137
                                 */
138
                                v = parser.getAttributeValue(null, SLDTags.VERSION_ATTR);
139
                                return parseFeatureStyle(parser, v);
140
                        } else {
141
                                if (name.compareToIgnoreCase(SLDTags.LINESYMBOLIZER) == 0
142
                                                || name.compareToIgnoreCase(SLDTags.POLYGONSYMBOLIZER) == 0
143
                                                || name.compareToIgnoreCase(SLDTags.POINTSYMBOLIZER) == 0
144
                                                || name.compareToIgnoreCase(SLDTags.TEXTSYMBOLIZER) == 0
145
                                                || name.compareToIgnoreCase(SLDTags.RASTERSYMBOLIZER) == 0) {
146
                                        
147
                                        /*
148
                                         * This line is out of the SLD standard
149
                                         */
150
                                        v = parser.getAttributeValue(null, SLDTags.VERSION_ATTR);
151
                                        return parseSymbol(parser, v);
152
                                }
153
                        }
154
                }
155
                throw new SLDReadException(
156
                                "Misplaced input stream. Bad opening tag: " + name);
157
        }
158

    
159
        private static SLDSymbol parseSymbol(XmlPullParser parser, String version)
160
                        throws XmlPullParserException, IOException, SLDReadException {
161
                
162
                return SymbolElement.parse(parser, version);
163
        }
164
        
165
        private static SLDLayer parseLayer(XmlPullParser parser, String version)
166
                        throws XmlPullParserException, IOException, SLDReadException {
167

    
168
                String name = parser.getName();
169
                SLDLayer resp = null;
170
                
171
                if (SLDUtils.isStr(name, SLDTags.NAMEDLAYER)) {
172
                        resp = NamedLayerElement.parse(parser, version);
173
                } else {
174
                        if (SLDUtils.isStr(name, SLDTags.USERDEFINEDLAYER)) {
175
                                resp = UserLayerElement.parse(parser, version);
176
                        } else {
177
                                throw new SLDReadException(
178
                                                "Expected layer, found: '" + name + "' tag");                        
179
                                
180
                        }
181
                }
182
                return resp;        
183
                
184
        }
185
        
186
        private static SLDFeatureStyle parseFeatureStyle(
187
                        XmlPullParser parser, String version)
188
                        throws XmlPullParserException, IOException, SLDReadException {
189

    
190
                String name = parser.getName();
191
                SLDFeatureStyle resp = null;
192
                
193
                if (SLDUtils.isStr(name, SLDTags.FEATURESTYLE) ||
194
                                SLDUtils.isStr(name, SLDTags.FEATURETYPESTYLE)) {
195
                        resp = FeatureStyleElement.parse(parser, version);
196
                } else {
197
                        throw new SLDReadException(
198
                                        "Expected layer, found: '" + name + "' tag");                        
199
                }
200
                return resp;        
201
                
202
        }
203

    
204
        private static SLDRoot parseRoot(XmlPullParser parser, String version)
205
                        throws XmlPullParserException, IOException, SLDReadException {
206
                
207
                parser.require(KXmlParser.START_TAG, null, SLDTags.SLD_ROOT);
208
                int tag = parser.nextTag();
209
                String name = parser.getName();
210
                SLDLayer layer_item = null;
211
                SLDRoot resp = new SLDRoot(version);
212
                
213
                while (tag == KXmlParser.START_TAG  && 
214
                                (SLDUtils.isStr(name, SLDTags.USERDEFINEDLAYER) ||
215
                                SLDUtils.isStr(name, SLDTags.NAMEDLAYER))) {
216
                        layer_item = parseLayer(parser, version);
217
                        resp.getLayers().add(layer_item);
218
                        // =============
219
                        name = parser.getName();
220
                        tag = parser.getEventType();
221
                }
222
                parser.require(KXmlParser.END_TAG, null, SLDTags.SLD_ROOT);
223
                parser.next(); // goes to end of doc
224
                return resp;
225
        }        
226
        
227
        // ============   WRITING   =================
228
        
229
        public static void writeToFile(SLDObject obj, File outf)
230
        throws InvalidSLDObjectException, UnsupportedSLDVersionException,
231
        UnsupportedSLDObjectException, IOException {
232
                
233
                if (obj == null) {
234
                        throw new InvalidSLDObjectException("SLDObject", "Null");
235
                }
236
                
237
                if (! (obj instanceof SLDRoot
238
                                || obj instanceof SLDFeatureStyle
239
                                || obj instanceof SLDSymbol)) {
240
                        
241
                        throw new InvalidSLDObjectException("Unexpected class.",
242
                                        obj.getClass().getName());
243
                }
244

    
245
                if (outf == null || !outf.canWrite()) {
246
                        new IOException("Null or read-only file: "
247
                                        + (outf == null ? "Null" : outf.getAbsolutePath()));
248
                }
249
                
250
                if (obj.getVersion() == null || !versions.contains(obj.getVersion())) {
251
                        throw new UnsupportedSLDVersionException(obj.getVersion());
252
                }
253
                // ok
254
                outf.delete();
255
                outf.createNewFile();
256
                FileOutputStream outs = new FileOutputStream(outf);
257
                
258
                XmlBuilder xmlb = getXML(obj);
259

    
260
                OutputStreamWriter writer = new OutputStreamWriter(outs, SLDUtils.DEFAULT_ENCODING);
261
                writer.write(xmlb.getXML());
262
                writer.close();
263
                outs.close();
264
        }
265
        
266

    
267
        public static XmlBuilder getXML(SLDObject obj)
268
                        throws InvalidSLDObjectException, UnsupportedSLDObjectException {
269
                
270
                if (! (obj instanceof SLDRoot
271
                                || obj instanceof SLDFeatureStyle
272
                                || obj instanceof SLDSymbol)) {
273
                        
274
                        throw new InvalidSLDObjectException("Unexpected entity.",
275
                                        obj.getClass().getName());
276
                }
277
                
278
                Map<String, String> attributes = new HashMap<String, String>();
279
                
280
                attributes.put("xsi:schemaLocation","http://www.opengis.net/sld StyledLayerDescriptor.xsd");
281
                attributes.put("xmlns","http://www.opengis.net/sld");
282
                attributes.put("xmlns:ogc","http://www.opengis.net/ogc");
283
                attributes.put("xmlns:xlink","http://www.w3.org/1999/xlink");
284
                attributes.put("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
285
                attributes.put(SLDTags.VERSION_ATTR, obj.getVersion());
286
                /*
287
                 * Atts will be written in the opentag of the first entity
288
                 */
289

    
290
                XmlBuilder xmlBuilder = new XmlBuilder();
291
                xmlBuilder.setEncoding(SLDUtils.DEFAULT_ENCODING);
292
                xmlBuilder.writeHeader();
293
                
294
                // ==========================================
295
                if (obj instanceof SLDRoot) {
296
                        appendRoot((SLDRoot) obj, xmlBuilder, attributes);
297
                } else {
298
                        if (obj instanceof SLDFeatureStyle) {
299
                                /*
300
                                 * Doing this is not SLD standard-conformal
301
                                 */
302
                                FeatureStyleElement.append((SLDFeatureStyle) obj, xmlBuilder, attributes); 
303
                        } else {
304
                                if (obj instanceof SLDSymbol) {
305
                                        /*
306
                                         * Doing this is not SLD standard-conformal
307
                                         */
308
                                        SymbolElement.append((SLDSymbol) obj,  xmlBuilder, attributes);
309
                                }
310
                        }
311
                }
312
                // ==========================================
313
                return xmlBuilder;
314
        }
315
        
316

    
317
        private static void appendRoot(
318
                        SLDRoot root,
319
                        XmlBuilder xb,
320
                        Map<String, String> atts) throws
321
                        InvalidSLDObjectException, UnsupportedSLDObjectException {
322
                
323
                xb.openTag(SLDTags.SLD_ROOT, atts);
324
                
325
                List<SLDLayer> list = root.getLayers();
326
                if (list == null || list.size() == 0) {
327
                        throw new InvalidSLDObjectException(
328
                                        SLDTags.SLD_ROOT, "No layers");
329
                } else {
330
                        for (int i=0; i<list.size(); i++) {
331
                                if (list.get(i) instanceof SLDUserLayer) {
332
                                        // Do not pass attributes 8already written)
333
                                        UserLayerElement.append((SLDUserLayer) list.get(i), xb, root.getVersion());
334
                                } else {
335
                                        if (list.get(i) instanceof SLDNamedLayer) {
336
                                                // Do not pass attributes 8already written)
337
                                                NamedLayerElement.append((SLDNamedLayer) list.get(i), xb, root.getVersion());
338
                                        } else {
339
                                                throw new UnsupportedSLDObjectException(
340
                                                                (list.get(i) == null ? "Null" :
341
                                                                        list.get(i).getClass().getName()),
342
                                                                        "Unknwon layer type");
343
                                        }
344
                                }
345
                        }
346
                }
347
                
348
                xb.closeTag();
349
        }
350
        
351
}