Statistics
| Revision:

gvsig-raster / org.gvsig.raster.wms / trunk / org.gvsig.raster.wms / org.gvsig.raster.wms.remoteclient / src / main / java / org / gvsig / remoteclient / wms / wms_1_3_0 / WMSProtocolHandler1_3_0.java @ 7271

History | View | Annotate | Download (13.2 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 3
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

    
25
package org.gvsig.remoteclient.wms.wms_1_3_0;
26

    
27
import java.io.ByteArrayInputStream;
28
import java.io.File;
29
import java.io.IOException;
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.Enumeration;
33
import java.util.TreeMap;
34

    
35
import org.kxml2.io.KXmlParser;
36
import org.xmlpull.v1.XmlPullParserException;
37
import org.gvsig.compat.net.ICancellable;
38
import org.gvsig.remoteclient.epsg.CrsAxisOrder;
39
import org.gvsig.remoteclient.utils.BoundaryBox;
40
import org.gvsig.remoteclient.utils.CapabilitiesTags;
41
import org.gvsig.remoteclient.utils.EncodingXMLParser;
42
import org.gvsig.remoteclient.utils.ExceptionTags;
43
import org.gvsig.remoteclient.wms.WMSLayer;
44
import org.gvsig.remoteclient.wms.WMSServiceInformation;
45
import org.gvsig.remoteclient.wms.WMSStatus;
46
import org.gvsig.remoteclient.wms.request.WMSGetCapabilitiesRequest;
47
import org.gvsig.remoteclient.wms.request.WMSGetFeatureInfoRequest;
48
import org.gvsig.remoteclient.wms.request.WMSGetLegendGraphicRequest;
49
import org.gvsig.remoteclient.wms.request.WMSGetMapRequest;
50
import org.gvsig.remoteclient.wms.wms_1_1_1.WMSProtocolHandler1_1_1;
51
import org.gvsig.remoteclient.wms.wms_1_3_0.request.WMSGetCapabilitiesRequest1_3_0;
52
import org.gvsig.remoteclient.wms.wms_1_3_0.request.WMSGetFeatureInfoRequest1_1_3;
53
import org.gvsig.remoteclient.wms.wms_1_3_0.request.WMSGetLegendGraphicRequest1_1_3;
54
import org.gvsig.remoteclient.wms.wms_1_3_0.request.WMSGetMapRequest1_1_3;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

    
58
/**
59
 * <p>
60
 * Describes the handler to comunicate to a WMS 1.3.0
61
 * </p>
62
 */
63
public class WMSProtocolHandler1_3_0 extends org.gvsig.remoteclient.wms.WMSProtocolHandler {
64

    
65
        private static final Logger logger = LoggerFactory.getLogger(WMSProtocolHandler1_3_0.class);
66
        private WMSLayer1_3_0 fakeRootLayer;
67

    
68
        public WMSProtocolHandler1_3_0()
69
        {
70
                this.version = "1.3.0";
71
                this.name = "WMS1.3.0";
72
                this.serviceInfo = new WMSServiceInformation();
73
                this.layers = new TreeMap();
74
        }
75

    
76
//------------------------------------------------------------------------------
77
// Parsing methods....
78
//------------------------------------------------------------------------------
79

    
80
        @Override
81
        public void getCapabilities(WMSStatus status, boolean override,
82
                        ICancellable cancel) {
83
                super.getCapabilities(status, override, cancel);
84
                if (rootLayer!=null && status!=null && !status.isXyAxisOrder()) {
85
                        /*        WMSLayer parser gets no information about the user preferences regarding
86
                                 axis order, so the bboxes should be post-processed here,
87
                                 where we get the user preference from the WMSStatus
88
                         */
89
                        processLayer(rootLayer);
90
                }
91
        }
92

    
93
        /**
94
         * WMSLayer parser gets no information about the user preferences regarding
95
         * axis order, so the bboxes should be should be post-processed here,
96
         * where we get the information from  at the
97
         * protocol hanlder
98
         * @param layer
99
         */
100
        protected void processLayer(WMSLayer layer) {
101
        if (layer.getBboxes()!=null) {
102
            Collection<BoundaryBox> col = (Collection<BoundaryBox>) layer.getBboxes().values();
103
            for (BoundaryBox bbox: col) {
104
                if (!CrsAxisOrder.isXyAxisOrder(bbox.getSrs())) {
105
                    double auxX = bbox.getXmin();
106
                    double auxY = bbox.getYmin();
107
                    bbox.setXmin(auxY);
108
                    bbox.setYmin(auxX);
109
                    auxX = bbox.getXmax();
110
                    auxY = bbox.getYmax();
111
                    bbox.setXmax(auxY);
112
                    bbox.setYmax(auxX);
113
                }
114
            }
115
        }
116
        ArrayList children = layer.getChildren();
117
        if (children!=null) {
118
            for (int i=0; i<children.size(); i++) {
119
                WMSLayer child = (WMSLayer) children.get(i);
120
                processLayer(child);
121
            }
122
        }
123
    }
124

    
125
    public boolean parseCapabilities(File f)
126
    {
127
            rootLayer = null;
128

    
129
            int tag;
130
              EncodingXMLParser kxmlParser = null;
131
            kxmlParser = new EncodingXMLParser();
132
            try
133
            {
134
                       kxmlParser.setInput(f);
135
                        kxmlParser.nextTag();
136
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
137
                    {
138
                            kxmlParser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITIES_ROOT1_3_0);
139
                            tag = kxmlParser.nextTag();
140
                                 while(tag != KXmlParser.END_DOCUMENT)
141
                                 {
142
                     switch(tag)
143
                                         {
144
                                                case KXmlParser.START_TAG:
145
                                                        if (kxmlParser.getName().compareTo(CapabilitiesTags.SERVICE )==0)
146
                                                        {
147
                                                                parseServiceTag(kxmlParser);
148
                                                        }
149
                                                        else if (kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITY)==0)
150
                                                        {
151
                                                                parseCapabilityTag(kxmlParser);
152
                                                        }
153
                                                        break;
154
                                                case KXmlParser.END_TAG:
155
                                                        break;
156
                                                case KXmlParser.TEXT:
157
                                                        //System.out.println("[TEXT]["+kxmlParser.getText()+"]");
158
                                                break;
159
                                         }
160
                                     tag = kxmlParser.next();
161
                             }//while !END_DOCUMENT
162
                    }
163
            }
164
            catch(XmlPullParserException parser_ex){
165
                logger.warn("Error parsing capabilites.",parser_ex);
166
                    return false;
167
            }
168
                   catch (IOException ioe) {
169
                        logger.warn("Error parsing capabilites.",ioe);
170
                           return false;
171
                 } finally {
172
            return true;
173
        }
174
                   // In the parsing process the layer has been filled
175
    }
176

    
177
    /**
178
     * <p>Parses the Service Information </p>
179
     */
180
    private void parseServiceTag(KXmlParser parser) throws IOException, XmlPullParserException
181
    {
182
            int currentTag;
183
            boolean end = false;
184

    
185
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.SERVICE);
186
            currentTag = parser.next();
187

    
188
            while (!end)
189
            {
190
                         switch(currentTag)
191
                         {
192
                                case KXmlParser.START_TAG:
193
                                        if (parser.getName().compareTo(CapabilitiesTags.NAME)==0)
194
                                        {
195
                                                serviceInfo.name = parser.nextText();
196
                                        }
197
                                        else if (parser.getName().compareTo(CapabilitiesTags.TITLE)==0)
198
                                        {
199
                                                serviceInfo.title = parser.nextText();
200
                                        }
201
                                        else if (parser.getName().compareTo(CapabilitiesTags.ABSTRACT)==0)
202
                                        {
203
                                                serviceInfo.abstr = parser.nextText();
204
                                        }
205
                                        else if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
206
                                        {
207
                                            String value = new String();
208
                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
209
                                        if (value != null){
210
                                                serviceInfo.online_resource = value;
211
                                        }
212
                                        }
213
                                        else if ((parser.getName().compareTo(CapabilitiesTags.KEYWORDLIST)==0) ||
214
                                                        (parser.getName().compareTo(CapabilitiesTags.CONTACTINFORMATION)==0))
215
                                        {
216
                                                parser.skipSubTree();
217
                                        }
218
                                        break;
219
                                case KXmlParser.END_TAG:
220
                                        if (parser.getName().compareTo(CapabilitiesTags.SERVICE) == 0)
221
                                                end = true;
222
                                        break;
223
                                case KXmlParser.TEXT:
224
                                break;
225
                         }
226
             if (!end)
227
                 currentTag = parser.next();
228
            }
229
            parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.SERVICE);
230
    }
231

    
232
    /**
233
     * <p>Parses the Capability Tag </p>
234
     */
235
    private void parseCapabilityTag(KXmlParser parser) throws IOException, XmlPullParserException
236
    {
237
            int currentTag;
238
            boolean end = false;
239

    
240
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITY);
241
            currentTag = parser.next();
242

    
243
            while (!end)
244
            {
245
                         switch(currentTag)
246
                         {
247
                                case KXmlParser.START_TAG:
248
                                        if (parser.getName().compareTo(CapabilitiesTags.REQUEST)==0)
249
                                        {
250
                                                parseRequestTag(parser);
251
                                        }
252
                                        else if (parser.getName().compareTo(CapabilitiesTags.EXCEPTION)==0)
253
                                        {
254
                                                //TODO:
255
                                                //Add to serviceInformation the supported exception formats.
256
                                        }
257
                                        else if (parser.getName().compareTo(CapabilitiesTags.LAYER)==0)
258
                                        {
259
                                                WMSLayer1_3_0 lyr = new WMSLayer1_3_0();
260
                        if (rootLayer == null)
261
                            rootLayer = lyr;
262
                        else {
263
                            // Handles when there is no general root layer, will use
264
                            // a fake non-queryable one.
265
                            if (!rootLayer.equals(getFakeRootLayer())){
266
                                WMSLayer1_3_0 aux = (WMSLayer1_3_0) rootLayer;
267
                                rootLayer  = getFakeRootLayer();
268
                                rootLayer.getChildren().add(aux);
269
                            }
270
                            rootLayer.getChildren().add(lyr);
271
                        }
272
                                                lyr.parse(parser, layers);
273

    
274
                        if (lyr.getName()!=null)
275
                                                    layers.put(lyr.getName(), lyr);
276
                                        }
277
                                        else if ((parser.getName().compareTo(CapabilitiesTags.VENDORSPECIFICCAPABILITIES)==0) ||
278
                                                        (parser.getName().compareTo(CapabilitiesTags.USERDEFINEDSYMBOLIZATION )==0))
279
                                        {
280
                                                parser.skipSubTree();
281
                                        }
282
                                        break;
283
                                case KXmlParser.END_TAG:
284
                                        if (parser.getName().compareTo(CapabilitiesTags.CAPABILITY) == 0)
285
                                                end = true;
286
                                        break;
287
                                case KXmlParser.TEXT:
288
                                break;
289
                         }
290
                         if (!end)
291
                                 currentTag = parser.next();
292
            }
293
            //parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.CAPABILITY);
294
    }
295

    
296
    private WMSLayer1_3_0 getFakeRootLayer(){
297
        if (fakeRootLayer == null){
298
            fakeRootLayer = new WMSLayer1_3_0();
299
            fakeRootLayer.setTitle(serviceInfo.title);
300
            fakeRootLayer.setQueryable(false);
301
            fakeRootLayer.setName(null);
302
        }
303
        return fakeRootLayer;
304
    }
305
    /* (non-Javadoc)
306
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
307
     */
308
    protected String parseException(byte[] data) {
309
        ArrayList errors = new ArrayList();
310
        KXmlParser kxmlParser = new KXmlParser();
311
        try
312
        {
313
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);
314
            kxmlParser.nextTag();
315
            int tag;
316
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
317
            {
318
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);
319
                tag = kxmlParser.nextTag();
320
                 while(tag != KXmlParser.END_DOCUMENT)
321
                 {
322
                     switch(tag)
323
                     {
324
                        case KXmlParser.START_TAG:
325
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
326
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
327
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
328
                                String errorMessage = kxmlParser.nextText();
329
                                errors.add(errorCode+errorMessage);
330
                            }
331
                            break;
332
                        case KXmlParser.END_TAG:
333
                            break;
334

    
335
                     }
336
                     tag = kxmlParser.nextTag();
337
                 }
338
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
339
            }
340
        }
341
        catch(XmlPullParserException parser_ex){
342
            logger.warn("",parser_ex);
343
        }
344
        catch (IOException ioe) {
345
            logger.warn("",ioe);
346
        }
347
        String message = errors.size()>0? "" : null;
348
        for (int i = 0; i < errors.size(); i++) {
349
            message += (String) errors.get(i)+"\n";
350
        }
351
        return message;
352
    }
353

    
354
    /*
355
     * (non-Javadoc)
356
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#createGetFeatureInfoRequest(org.gvsig.remoteClient.wms.WMSStatus, int, int)
357
     */
358
        protected WMSGetFeatureInfoRequest createGetFeatureInfoRequest(
359
                        WMSStatus status, int x, int y) {
360
                return new WMSGetFeatureInfoRequest1_1_3(status, this, x, y);
361
        }
362

    
363
        /*
364
         * (non-Javadoc)
365
         * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#createGetMapRequest(org.gvsig.remoteClient.wms.WMSStatus)
366
         */
367
        protected WMSGetMapRequest createGetMapRequest(WMSStatus status) {
368
                return new WMSGetMapRequest1_1_3(status, this);
369
        }
370

    
371
        /*
372
         * (non-Javadoc)
373
         * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#createGetLegendGraphicRequest(org.gvsig.remoteClient.wms.WMSStatus, java.lang.String)
374
         */
375
        protected WMSGetLegendGraphicRequest createGetLegendGraphicRequest(
376
                        WMSStatus status, String layerName) {
377
                return new WMSGetLegendGraphicRequest1_1_3(status, this, layerName);
378
        }
379

    
380

    
381
        /* (non-Javadoc)
382
         * @see org.gvsig.remoteclient.wms.WMSProtocolHandler#createGetCapabilitiesRequest(org.gvsig.remoteclient.wms.WMSStatus)
383
         */
384
        protected WMSGetCapabilitiesRequest createGetCapabilitiesRequest(
385
                        WMSStatus status) {
386
                return new WMSGetCapabilitiesRequest1_3_0(status, this);
387
        }
388
  }