Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / wms_1_3_0 / WMSProtocolHandler1_3_0.java @ 14705

History | View | Annotate | Download (16.2 KB)

1

    
2
package org.gvsig.remoteClient.wms.wms_1_3_0;
3

    
4
import java.io.ByteArrayInputStream;
5
import java.io.File;
6
import java.io.IOException;
7
import java.util.ArrayList;
8
import java.util.TreeMap;
9

    
10
import org.gvsig.remoteClient.utils.CapabilitiesTags;
11
import org.gvsig.remoteClient.utils.EncodingXMLParser;
12
import org.gvsig.remoteClient.utils.ExceptionTags;
13
import org.gvsig.remoteClient.utils.Utilities;
14
import org.gvsig.remoteClient.wms.WMSStatus;
15
import org.kxml2.io.KXmlParser;
16
import org.xmlpull.v1.XmlPullParserException;
17

    
18
/**
19
 * <p>
20
 * Describes the handler to comunicate to a WMS 1.3.0
21
 * </p>
22
 */
23
public class WMSProtocolHandler1_3_0 extends org.gvsig.remoteClient.wms.WMSProtocolHandler {
24
        private WMSLayer1_3_0 fakeRootLayer;
25
    
26
        public WMSProtocolHandler1_3_0()
27
        {
28
                this.version = "1.3.0";
29
                this.name = "WMS1.3.0";
30
                this.serviceInfo = new ServiceInformation(); 
31
                this.layers = new TreeMap();                   
32
        }
33
    
34
//------------------------------------------------------------------------------
35
// Parsing methods....    
36
//------------------------------------------------------------------------------    
37
/**
38
 * <p>Parse the xml data retrieved from the WMS, it will parse the WMS Capabilities</p>
39
 * 
40
 */
41
    public void parse(File f)
42
    {   
43
            rootLayer = null;
44
            
45
            int tag;
46
              EncodingXMLParser kxmlParser = null;
47
            kxmlParser = new EncodingXMLParser();
48
            try
49
            {
50
                       kxmlParser.setInput(f);
51
                        kxmlParser.nextTag();
52
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
53
                    {                    
54
                            kxmlParser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITIES_ROOT1_3_0);                            
55
                            tag = kxmlParser.nextTag();
56
                                 while(tag != KXmlParser.END_DOCUMENT)
57
                                 {
58
                     switch(tag)
59
                                         {                       
60
                                                case KXmlParser.START_TAG:
61
                                                        if (kxmlParser.getName().compareTo(CapabilitiesTags.SERVICE )==0)
62
                                                        {
63
                                                                parseServiceTag(kxmlParser);
64
                                                        }        
65
                                                        else if (kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITY)==0)
66
                                                        {
67
                                                                parseCapabilityTag(kxmlParser);
68
                                                        }
69
                                                        break;
70
                                                case KXmlParser.END_TAG:                                                        
71
                                                        break;
72
                                                case KXmlParser.TEXT:
73
                                                        //System.out.println("[TEXT]["+kxmlParser.getText()+"]");                                                        
74
                                                break;
75
                                         }
76
                                     tag = kxmlParser.next();
77
                             }//while !END_DOCUMENT
78
                    }
79
            }
80
            catch(XmlPullParserException parser_ex){                    
81
                    parser_ex.printStackTrace();
82
            }
83
                   catch (IOException ioe) {                        
84
                           ioe.printStackTrace();
85
                 } finally {
86
            
87
        }
88
                   // In the parsing process the layer has been filled                  
89
    } 
90
    
91
    /**
92
     * <p>Parses the Service Information </p>
93
     */    
94
    private void parseServiceTag(KXmlParser parser) throws IOException, XmlPullParserException 
95
    {
96
            int currentTag;
97
            boolean end = false;
98
            
99
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.SERVICE);
100
            currentTag = parser.next();
101
            
102
            while (!end) 
103
            {
104
                         switch(currentTag)
105
                         {
106
                                case KXmlParser.START_TAG:
107
                                        if (parser.getName().compareTo(CapabilitiesTags.NAME)==0)
108
                                        {
109
                                                serviceInfo.name = parser.nextText(); 
110
                                        }        
111
                                        else if (parser.getName().compareTo(CapabilitiesTags.TITLE)==0)
112
                                        {
113
                                                serviceInfo.title = parser.nextText(); 
114
                                        }
115
                                        else if (parser.getName().compareTo(CapabilitiesTags.ABSTRACT)==0)
116
                                        {
117
                                                serviceInfo.abstr = parser.nextText(); 
118
                                        }
119
                                        else if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
120
                                        {
121
                                            String value = new String();
122
                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
123
                                        if (value != null){
124
                                                serviceInfo.online_resource = value;
125
                                        }
126
                                        }                                        
127
                                        else if ((parser.getName().compareTo(CapabilitiesTags.KEYWORDLIST)==0) ||
128
                                                        (parser.getName().compareTo(CapabilitiesTags.CONTACTINFORMATION)==0))
129
                                        {
130
                                                parser.skipSubTree();
131
                                        }                                        
132
                                        break;
133
                                case KXmlParser.END_TAG:
134
                                        if (parser.getName().compareTo(CapabilitiesTags.SERVICE) == 0)
135
                                                end = true;
136
                                        break;
137
                                case KXmlParser.TEXT:                                        
138
                                break;
139
                         }
140
             if (!end)
141
                 currentTag = parser.next();
142
            }
143
            parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.SERVICE);
144
    }
145
    
146
    /**
147
     * <p>Parses the Capability Tag </p>
148
     */    
149
    private void parseCapabilityTag(KXmlParser parser) throws IOException, XmlPullParserException
150
    {         
151
            int currentTag;
152
            boolean end = false;
153
            
154
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITY);
155
            currentTag = parser.next();
156
            
157
            while (!end) 
158
            {
159
                         switch(currentTag)
160
                         {
161
                                case KXmlParser.START_TAG:
162
                                        if (parser.getName().compareTo(CapabilitiesTags.REQUEST)==0)
163
                                        {
164
                                                parseRequestTag(parser); 
165
                                        }        
166
                                        else if (parser.getName().compareTo(CapabilitiesTags.EXCEPTION)==0)
167
                                        {
168
                                                //TODO:
169
                                                //Add to serviceInformation the supported exception formats.
170
                                        }
171
                                        else if (parser.getName().compareTo(CapabilitiesTags.LAYER)==0)
172
                                        {
173
                                                WMSLayer1_3_0 lyr = new WMSLayer1_3_0();
174
                        if (rootLayer == null)
175
                            rootLayer = lyr;
176
                        else {
177
                            // Handles when there is no general root layer, will use
178
                            // a fake non-queryable one.
179
                            if (!rootLayer.equals(getFakeRootLayer())){
180
                                WMSLayer1_3_0 aux = (WMSLayer1_3_0) rootLayer;
181
                                rootLayer  = getFakeRootLayer();
182
                                rootLayer.getChildren().add(aux);
183
                            }
184
                            rootLayer.getChildren().add(lyr);
185
                        }
186
                                                lyr.parse(parser, layers);
187
                                                
188
                        if (lyr.getName()!=null)
189
                                                    layers.put(lyr.getName(), lyr);                                                                                         
190
                                        }
191
                                        else if ((parser.getName().compareTo(CapabilitiesTags.VENDORSPECIFICCAPABILITIES)==0) ||
192
                                                        (parser.getName().compareTo(CapabilitiesTags.USERDEFINEDSYMBOLIZATION )==0))                            
193
                                        {
194
                                                parser.skipSubTree();
195
                                        }                                        
196
                                        break;
197
                                case KXmlParser.END_TAG:
198
                                        if (parser.getName().compareTo(CapabilitiesTags.CAPABILITY) == 0)
199
                                                end = true;
200
                                        break;
201
                                case KXmlParser.TEXT:                                        
202
                                break;
203
                         }
204
                         if (!end)
205
                                 currentTag = parser.next();
206
            }
207
            //parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.CAPABILITY);            
208
    }
209
    
210
    /**
211
     * <p>Parses the Request tag </p>
212
     */ 
213
    private void parseRequestTag(KXmlParser parser) throws IOException, XmlPullParserException
214
    {        
215
            int currentTag;
216
            boolean end = false;
217
            
218
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.REQUEST);
219
            currentTag = parser.next();
220
            
221
            while (!end) 
222
            {
223
                         switch(currentTag)
224
                         {
225
                                case KXmlParser.START_TAG:
226
                                        if (parser.getName().compareTo(CapabilitiesTags.GETCAPABILITIES)==0)
227
                                        {
228
                                                //we could parse here the info of Capabilities request, but we actually never use it.
229
                                        }        
230
                                        else if (parser.getName().compareTo(CapabilitiesTags.GETMAP)==0)
231
                                        {        
232
                                                serviceInfo.operations.put(CapabilitiesTags.GETMAP, null);
233
                                                parseGetMapTag(parser);                
234
                                        }
235
                                        else if (parser.getName().compareTo(CapabilitiesTags.GETFEATUREINFO)==0)
236
                                        {
237
                                                serviceInfo.operations.put(CapabilitiesTags.GETFEATUREINFO, null);
238
                                                parseGetFeatureInfoTag(parser);                
239
                                        }        
240
                                        else if (parser.getName().compareTo(CapabilitiesTags.DESCRIBELAYER)==0)
241
                                        {
242
                                                serviceInfo.operations.put(CapabilitiesTags.DESCRIBELAYER, null); 
243
                                        }        
244
                                        else if (parser.getName().compareTo(CapabilitiesTags.GETLEGENDGRAPHIC)==0)
245
                                        {
246
                                                serviceInfo.operations.put(CapabilitiesTags.GETLEGENDGRAPHIC, null);
247
                                                parseGetLegendGraphicTag(parser);
248
                                        }
249
                                        break;
250
                                case KXmlParser.END_TAG:
251
                                        if (parser.getName().compareTo(CapabilitiesTags.REQUEST) == 0)
252
                                                end = true;
253
                                        break;
254
                                case KXmlParser.TEXT:                                        
255
                                break;
256
                         }
257
                         if (!end)
258
                                 currentTag = parser.next();
259
            }
260
            // TODO: does not get such a tag when arrives here!!!!!!
261
            //parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.REQUEST);            
262
    }
263
    
264
    /**
265
     * <p>Parses the GetMap tag </p>
266
     */ 
267
    private void parseGetMapTag(KXmlParser parser) throws IOException, XmlPullParserException
268
    {        
269
            int currentTag;
270
            boolean end = false;
271
            
272
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETMAP);
273
            currentTag = parser.next();
274
            
275
            while (!end) 
276
            {
277
                         switch(currentTag)
278
                         {
279
                                case KXmlParser.START_TAG:
280
                                        if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
281
                                        {
282
                                                serviceInfo.formats.add(parser.nextText());
283
                                        }        
284
                                        else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
285
                                        {                        
286
                                                currentTag = parser.nextTag();
287
                                                if(parser.getName().compareTo(CapabilitiesTags.HTTP)==0)
288
                                                {
289
                                                        currentTag = parser.nextTag();
290
                                                        if(parser.getName().compareTo(CapabilitiesTags.GET)==0)
291
                                                        {
292
                                                                currentTag = parser.nextTag();
293
                                                                if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
294
                                                                {
295
                                                                        String value = new String();
296
                                                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
297
                                                                        if (value != null){
298
                                                                                serviceInfo.operations.put(CapabilitiesTags.GETMAP, value);
299
                                                                        }                                                                        
300
                                                                }
301
                                                        }
302
                                                }
303
                                        }                        
304
                                        break;
305
                                case KXmlParser.END_TAG:
306
                                        if (parser.getName().compareTo(CapabilitiesTags.GETMAP) == 0)
307
                                                end = true;
308
                                        break;
309
                                case KXmlParser.TEXT:                                        
310
                                break;
311
                         }
312
                         if(!end)
313
                                 currentTag = parser.next();
314
            }        
315
    }    
316
    
317
    /**
318
     * <p>Parses the GetFeatureInfo tag </p>
319
     */ 
320
    private void parseGetFeatureInfoTag(KXmlParser parser) throws IOException, XmlPullParserException
321
    {        
322
            int currentTag;
323
            boolean end = false;
324
            
325
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETFEATUREINFO);
326
            currentTag = parser.next();
327
            
328
            while (!end) 
329
            {
330
                         switch(currentTag)
331
                         {
332
                                case KXmlParser.START_TAG:
333
                                        if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
334
                                        {
335
                                                //TODO:
336
                                                // add the supported formats by the GetFeatureInfo request
337
                                                //serviceInfo.formats.add(parser.nextText());
338
                                        }        
339
                                        else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
340
                                        {                        
341
                                                currentTag = parser.nextTag();
342
                                                if(parser.getName().compareTo(CapabilitiesTags.HTTP)==0)
343
                                                {
344
                                                        currentTag = parser.nextTag();
345
                                                        if(parser.getName().compareTo(CapabilitiesTags.GET)==0)
346
                                                        {
347
                                                                currentTag = parser.nextTag();
348
                                                                if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
349
                                                                {
350
                                                                        String value = new String();
351
                                                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
352
                                                                        if (value != null){
353
                                                                                //serviceInfo.online_resource = value;
354
                                                                                serviceInfo.operations.put(CapabilitiesTags.GETFEATUREINFO, value);
355
                                                                        }
356
                                                                }
357
                                                        }
358
                                                }
359
                                        }                        
360
                                        break;
361
                                case KXmlParser.END_TAG:
362
                                        if (parser.getName().compareTo(CapabilitiesTags.GETFEATUREINFO) == 0)
363
                                                end = true;
364
                                        break;
365
                                case KXmlParser.TEXT:                                        
366
                                break;
367
                         }
368
                         if(!end)
369
                                 currentTag = parser.next();
370
            }        
371
    }         
372

    
373
    /**
374
     * <p>Parses the GetLegendGraphic tag </p>
375
     */ 
376
    private void parseGetLegendGraphicTag(KXmlParser parser) throws IOException, XmlPullParserException
377
    {        
378
            int currentTag;
379
            boolean end = false;
380
            
381
            parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETLEGENDGRAPHIC);
382
            currentTag = parser.next();
383
            
384
            while (!end) 
385
            {
386
                         switch(currentTag)
387
                         {
388
                                case KXmlParser.START_TAG:
389
                                        if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
390
                                        {
391
                                                //TODO:
392
                                                // add the supported formats by the GetLegendGraphic request
393
                                                //serviceInfo.formats.add(parser.nextText());
394
                                        }        
395
                                        else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
396
                                        {                        
397
                                                currentTag = parser.nextTag();
398
                                                if(parser.getName().compareTo(CapabilitiesTags.HTTP)==0)
399
                                                {
400
                                                        currentTag = parser.nextTag();
401
                                                        if(parser.getName().compareTo(CapabilitiesTags.GET)==0)
402
                                                        {
403
                                                                currentTag = parser.nextTag();
404
                                                                if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
405
                                                                {
406
                                                                        String value = new String();
407
                                                                        value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
408
                                                                        if (value != null){
409
                                                                                serviceInfo.operations.put(CapabilitiesTags.GETLEGENDGRAPHIC, value);
410
                                                                        }
411
                                                                }
412
                                                        }
413
                                                }
414
                                        }                        
415
                                        break;
416
                                case KXmlParser.END_TAG:
417
                                        if (parser.getName().compareTo(CapabilitiesTags.GETLEGENDGRAPHIC) == 0)
418
                                                end = true;
419
                                        break;
420
                                case KXmlParser.TEXT:                                        
421
                                break;
422
                         }
423
                         if(!end)
424
                                 currentTag = parser.next();
425
            }        
426
    } 
427
    
428
    private WMSLayer1_3_0 getFakeRootLayer(){
429
        if (fakeRootLayer == null){
430
            fakeRootLayer = new WMSLayer1_3_0();
431
            fakeRootLayer.setTitle(serviceInfo.title);
432
            fakeRootLayer.setQueryable(false);
433
            fakeRootLayer.setName(null);
434
        }
435
        return fakeRootLayer;
436
    }
437
    /* (non-Javadoc)
438
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
439
     */
440
    protected String parseException(byte[] data) {
441
        ArrayList errors = new ArrayList();
442
        KXmlParser kxmlParser = new KXmlParser();
443
        try
444
        {
445
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);        
446
            kxmlParser.nextTag();
447
            int tag;
448
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
449
            { 
450
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);             
451
                tag = kxmlParser.nextTag();
452
                 while(tag != KXmlParser.END_DOCUMENT)
453
                 {
454
                     switch(tag)
455
                     {
456
                        case KXmlParser.START_TAG:
457
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
458
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
459
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
460
                                String errorMessage = kxmlParser.nextText();
461
                                errors.add(errorCode+errorMessage);
462
                            }
463
                            break;
464
                        case KXmlParser.END_TAG:                            
465
                            break;
466
                        
467
                     }
468
                     tag = kxmlParser.nextTag();
469
                 }
470
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
471
            }
472
        }
473
        catch(XmlPullParserException parser_ex){
474
            System.out.println(parser_ex.getMessage());
475
            parser_ex.printStackTrace();
476
        }
477
        catch (IOException ioe) {           
478
            ioe.printStackTrace();            
479
        }
480
        String message = errors.size()>0? "" : null;
481
        for (int i = 0; i < errors.size(); i++) {
482
            message += (String) errors.get(i)+"\n";
483
        }
484
        return message;
485
    }
486
   
487
    /**
488
     * Builds the GetFeatureInfoRequest according to the 1.3.0 OGC WMS Specifications
489
     */
490
    protected String buildGetFeatureInfoRequest(WMSStatus status, int x, int y)
491
    {
492
//            TODO: pass by parameter the info output format?
493
                StringBuffer req = new StringBuffer();
494
                String symbol = null;
495

    
496
                String onlineResource;
497
                if (status.getOnlineResource() == null)
498
                        onlineResource = getHost();
499
                else 
500
                        onlineResource = status.getOnlineResource();
501
                symbol = getSymbol(onlineResource);
502
        
503
                req.append(onlineResource).append(symbol).append("REQUEST=GetFeatureInfo&SERVICE=WMS&");
504
                req.append("QUERY_LAYERS=").append(Utilities.Vector2CS(status.getLayerNames())); 
505
                req.append("&VERSION=").append(getVersion()).append("&INFO_FORMAT=application/vnd.ogc.gml&");
506
                req.append(getPartialQuery(status)).append("&I="+x + "&J="+y);
507
                req.append("&FEATURE_COUNT=10000");
508
       if (status.getExceptionFormat() != null) {
509
            req.append("&EXCEPTIONS=" + status.getExceptionFormat());
510
        } else {
511
            req.append("&EXCEPTIONS=XML");
512
        }
513
                return req.toString().replaceAll(" ", "%20");
514
    } 
515
  }