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 @ 3325

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
                                        bbox.setXmin(bbox.getYmin());
106
                                        bbox.setYmin(bbox.getXmin());
107
                                        bbox.setXmax(bbox.getYmax());
108
                                        bbox.setYmax(bbox.getXmax());
109
                                }
110
                        }
111
                }
112
                ArrayList children = layer.getChildren();
113
                if (children!=null) {
114
                        for (int i=0; i<children.size(); i++) {
115
                                WMSLayer child = (WMSLayer) children.get(i);
116
                                processLayer(child);
117
                        }
118
                }
119
        }
120
        
121
    public boolean parseCapabilities(File f)
122
    {   
123
            rootLayer = null;
124
            
125
            int tag;
126
              EncodingXMLParser kxmlParser = null;
127
            kxmlParser = new EncodingXMLParser();
128
            try
129
            {
130
                       kxmlParser.setInput(f);
131
                        kxmlParser.nextTag();
132
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
133
                    {                    
134
                            kxmlParser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITIES_ROOT1_3_0);                            
135
                            tag = kxmlParser.nextTag();
136
                                 while(tag != KXmlParser.END_DOCUMENT)
137
                                 {
138
                     switch(tag)
139
                                         {                       
140
                                                case KXmlParser.START_TAG:
141
                                                        if (kxmlParser.getName().compareTo(CapabilitiesTags.SERVICE )==0)
142
                                                        {
143
                                                                parseServiceTag(kxmlParser);
144
                                                        }        
145
                                                        else if (kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITY)==0)
146
                                                        {
147
                                                                parseCapabilityTag(kxmlParser);
148
                                                        }
149
                                                        break;
150
                                                case KXmlParser.END_TAG:                                                        
151
                                                        break;
152
                                                case KXmlParser.TEXT:
153
                                                        //System.out.println("[TEXT]["+kxmlParser.getText()+"]");                                                        
154
                                                break;
155
                                         }
156
                                     tag = kxmlParser.next();
157
                             }//while !END_DOCUMENT
158
                    }
159
            }
160
            catch(XmlPullParserException parser_ex){                    
161
                logger.warn("Error parsing capabilites.",parser_ex);
162
                    return false;
163
            }
164
                   catch (IOException ioe) {                        
165
                        logger.warn("Error parsing capabilites.",ioe);
166
                           return false;
167
                 } finally {
168
            return true;
169
        }
170
                   // In the parsing process the layer has been filled                  
171
    } 
172
    
173
    /**
174
     * <p>Parses the Service Information </p>
175
     */    
176
    private void parseServiceTag(KXmlParser parser) throws IOException, XmlPullParserException 
177
    {
178
            int currentTag;
179
            boolean end = false;
180
            
181
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.SERVICE);
182
            currentTag = parser.next();
183
            
184
            while (!end) 
185
            {
186
                         switch(currentTag)
187
                         {
188
                                case KXmlParser.START_TAG:
189
                                        if (parser.getName().compareTo(CapabilitiesTags.NAME)==0)
190
                                        {
191
                                                serviceInfo.name = parser.nextText(); 
192
                                        }        
193
                                        else if (parser.getName().compareTo(CapabilitiesTags.TITLE)==0)
194
                                        {
195
                                                serviceInfo.title = parser.nextText(); 
196
                                        }
197
                                        else if (parser.getName().compareTo(CapabilitiesTags.ABSTRACT)==0)
198
                                        {
199
                                                serviceInfo.abstr = parser.nextText(); 
200
                                        }
201
                                        else if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
202
                                        {
203
                                            String value = new String();
204
                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
205
                                        if (value != null){
206
                                                serviceInfo.online_resource = value;
207
                                        }
208
                                        }                                        
209
                                        else if ((parser.getName().compareTo(CapabilitiesTags.KEYWORDLIST)==0) ||
210
                                                        (parser.getName().compareTo(CapabilitiesTags.CONTACTINFORMATION)==0))
211
                                        {
212
                                                parser.skipSubTree();
213
                                        }                                        
214
                                        break;
215
                                case KXmlParser.END_TAG:
216
                                        if (parser.getName().compareTo(CapabilitiesTags.SERVICE) == 0)
217
                                                end = true;
218
                                        break;
219
                                case KXmlParser.TEXT:                                        
220
                                break;
221
                         }
222
             if (!end)
223
                 currentTag = parser.next();
224
            }
225
            parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.SERVICE);
226
    }
227
    
228
    /**
229
     * <p>Parses the Capability Tag </p>
230
     */    
231
    private void parseCapabilityTag(KXmlParser parser) throws IOException, XmlPullParserException
232
    {         
233
            int currentTag;
234
            boolean end = false;
235
            
236
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITY);
237
            currentTag = parser.next();
238
            
239
            while (!end) 
240
            {
241
                         switch(currentTag)
242
                         {
243
                                case KXmlParser.START_TAG:
244
                                        if (parser.getName().compareTo(CapabilitiesTags.REQUEST)==0)
245
                                        {
246
                                                parseRequestTag(parser); 
247
                                        }        
248
                                        else if (parser.getName().compareTo(CapabilitiesTags.EXCEPTION)==0)
249
                                        {
250
                                                //TODO:
251
                                                //Add to serviceInformation the supported exception formats.
252
                                        }
253
                                        else if (parser.getName().compareTo(CapabilitiesTags.LAYER)==0)
254
                                        {
255
                                                WMSLayer1_3_0 lyr = new WMSLayer1_3_0();
256
                        if (rootLayer == null)
257
                            rootLayer = lyr;
258
                        else {
259
                            // Handles when there is no general root layer, will use
260
                            // a fake non-queryable one.
261
                            if (!rootLayer.equals(getFakeRootLayer())){
262
                                WMSLayer1_3_0 aux = (WMSLayer1_3_0) rootLayer;
263
                                rootLayer  = getFakeRootLayer();
264
                                rootLayer.getChildren().add(aux);
265
                            }
266
                            rootLayer.getChildren().add(lyr);
267
                        }
268
                                                lyr.parse(parser, layers);
269
                                                
270
                        if (lyr.getName()!=null)
271
                                                    layers.put(lyr.getName(), lyr);                                                                                         
272
                                        }
273
                                        else if ((parser.getName().compareTo(CapabilitiesTags.VENDORSPECIFICCAPABILITIES)==0) ||
274
                                                        (parser.getName().compareTo(CapabilitiesTags.USERDEFINEDSYMBOLIZATION )==0))                            
275
                                        {
276
                                                parser.skipSubTree();
277
                                        }                                        
278
                                        break;
279
                                case KXmlParser.END_TAG:
280
                                        if (parser.getName().compareTo(CapabilitiesTags.CAPABILITY) == 0)
281
                                                end = true;
282
                                        break;
283
                                case KXmlParser.TEXT:                                        
284
                                break;
285
                         }
286
                         if (!end)
287
                                 currentTag = parser.next();
288
            }
289
            //parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.CAPABILITY);            
290
    }  
291
    
292
    private WMSLayer1_3_0 getFakeRootLayer(){
293
        if (fakeRootLayer == null){
294
            fakeRootLayer = new WMSLayer1_3_0();
295
            fakeRootLayer.setTitle(serviceInfo.title);
296
            fakeRootLayer.setQueryable(false);
297
            fakeRootLayer.setName(null);
298
        }
299
        return fakeRootLayer;
300
    }
301
    /* (non-Javadoc)
302
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
303
     */
304
    protected String parseException(byte[] data) {
305
        ArrayList errors = new ArrayList();
306
        KXmlParser kxmlParser = new KXmlParser();
307
        try
308
        {
309
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);        
310
            kxmlParser.nextTag();
311
            int tag;
312
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
313
            { 
314
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);             
315
                tag = kxmlParser.nextTag();
316
                 while(tag != KXmlParser.END_DOCUMENT)
317
                 {
318
                     switch(tag)
319
                     {
320
                        case KXmlParser.START_TAG:
321
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
322
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
323
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
324
                                String errorMessage = kxmlParser.nextText();
325
                                errors.add(errorCode+errorMessage);
326
                            }
327
                            break;
328
                        case KXmlParser.END_TAG:                            
329
                            break;
330
                        
331
                     }
332
                     tag = kxmlParser.nextTag();
333
                 }
334
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
335
            }
336
        }
337
        catch(XmlPullParserException parser_ex){
338
            logger.warn("",parser_ex);
339
        }
340
        catch (IOException ioe) {           
341
            logger.warn("",ioe);        
342
        }
343
        String message = errors.size()>0? "" : null;
344
        for (int i = 0; i < errors.size(); i++) {
345
            message += (String) errors.get(i)+"\n";
346
        }
347
        return message;
348
    }   
349
    
350
    /*
351
     * (non-Javadoc)
352
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#createGetFeatureInfoRequest(org.gvsig.remoteClient.wms.WMSStatus, int, int)
353
     */
354
        protected WMSGetFeatureInfoRequest createGetFeatureInfoRequest(
355
                        WMSStatus status, int x, int y) {
356
                return new WMSGetFeatureInfoRequest1_1_3(status, this, x, y);
357
        }
358

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

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

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