Statistics
| Revision:

root / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / WMSProtocolHandler.java @ 7835

History | View | Annotate | Download (23.6 KB)

1
package org.gvsig.remoteClient.wms;
2

    
3
import java.io.ByteArrayInputStream;
4
import java.io.DataInputStream;
5
import java.io.File;
6
import java.io.FileInputStream;
7
import java.io.IOException;
8
import java.io.InputStream;
9
import java.io.StringReader;
10
import java.net.URL;
11
import java.net.URLConnection;
12
import java.nio.ByteBuffer;
13
import java.nio.channels.FileChannel;
14
import java.util.ArrayList;
15
import java.util.HashMap;
16
import java.util.TreeMap;
17
import java.util.Vector;
18

    
19
import org.gvsig.remoteClient.exceptions.ServerErrorException;
20
import org.gvsig.remoteClient.exceptions.WMSException;
21
import org.gvsig.remoteClient.utils.CapabilitiesTags;
22
import org.gvsig.remoteClient.utils.ExceptionTags;
23
import org.gvsig.remoteClient.utils.Utilities;
24
import org.kxml2.io.KXmlParser;
25
import org.xmlpull.v1.XmlPullParserException;
26

    
27
/**
28
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.
29
 * </p>
30
 * 
31
 */
32
public abstract class WMSProtocolHandler {
33
        /**
34
         * Encoding used to parse different xml documents.
35
         */
36
        protected String encoding = "UTF-8";
37
        /**
38
         * procotol handler name
39
         */
40
    protected String name;
41
    /**
42
     * protocol handler version
43
     */
44
    protected String version;
45
    /**
46
     * host of the WMS to connect
47
     */
48
    protected String host;
49
    /**
50
     * port number of the comunication channel of the WMS to connect
51
     */
52
    protected String port;    
53
    /**
54
     * WMS metadata
55
     */
56
    protected ServiceInformation serviceInfo;
57
    public TreeMap layers;
58
    public WMSLayer rootLayer;
59
//    public Vector srs;
60
    
61
    /**
62
     * parses the data retrieved by the WMS in XML format. 
63
     * It will be mostly the WMS Capabilities, but the implementation
64
     * will be placed in the handler implementing certain version of the protocol.
65
     * 
66
     */
67
    public abstract void parse(File f) ;
68
    
69
    /**
70
     * returns the alfanumeric information of the layers at the specified point.
71
     * the diference between the other getfeatureInfo method is that this will
72
     * be implemented by each specific version because the XML from the server will be
73
     * parsed and presented by a well known structure.
74
     */    
75

    
76
    public String getName() {        
77
            return name;
78
    } 
79

    
80
    public String getVersion() {        
81
            return version;
82
    }    
83
    
84
    public ServiceInformation getServiceInformation() {        
85
        return serviceInfo;
86
    }  
87
    public String getHost ()
88
    {
89
            return host;
90
    }
91
    public void setHost(String _host)
92
    {
93
            host = _host;
94
    }
95
    public String getPort()
96
    {
97
            return port;
98
    }
99
    public void setPort(String _port)
100
    {
101
            port = _port;
102
    }
103
    
104

    
105
    /**
106
         * <p>Builds a GetCapabilities request that is sent to the WMS
107
         * the response will be parse to extract the data needed by the
108
         * WMS client</p>
109
         * @param override, if true the previous downloaded data will be overridden
110
         */
111
    public void getCapabilities(WMSStatus status, boolean override, ICancellable cancel)
112
    {                
113
            URL request = null;
114
                try
115
                {
116
                        request = new URL(buildCapabilitiesRequest(status));
117
                }
118
                catch(Exception e)
119
                {
120
                        e.printStackTrace();
121
                }
122
                try
123
                {
124
                        if (override) 
125
                                Utilities.removeURL(request);
126
                        File f = Utilities.downloadFile(request,"wms_capabilities.xml", cancel);
127
                        if (f == null)
128
                                return;
129
                        clear();
130
                        parse(f);
131
            } catch(Exception e)
132
                {
133
                        //TODO
134
                        e.printStackTrace();
135
                }
136
    }
137

    
138
    private void clear() {
139
                layers.clear();
140
                serviceInfo.clear();
141
        }
142

    
143
        /**
144
     * <p>It will send a GetFeatureInfo request to the WMS
145
     * Parsing the response and redirecting the info to the WMS client</p>
146
     */
147
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount)
148
    {
149
            URL request = null;
150
            StringBuffer output = new StringBuffer();
151
            String outputFormat = new String();
152
            String ServiceException = "ServiceExceptionReport";                        
153
            StringBuffer sb = new StringBuffer();
154
            sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
155
                try
156
                {
157
                        //TODO:
158
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
159
                        request = new URL(buildGetFeatureInfoRequest(status, x, y));
160
                        
161
                        //TODO:
162
                        //see which output format is being requested.                                         
163
                }
164
                catch(Exception e)
165
                {
166
                        e.printStackTrace();
167
                        return "";
168
                }
169
                
170
            try
171
            {                                
172
                    System.out.println(request.toString());          
173
                    byte[] buffer = new byte[1024*256];                    
174
                    DataInputStream is = new DataInputStream(request.openStream());                    
175
                    outputFormat = request.openConnection().getContentType();
176

    
177
                    for (int i = is.read(buffer); i>0; i = is.read(buffer))
178
                    {
179
                            String str = new String(buffer,0,i);
180
                            output.append(str);                    
181
                    }
182
                                
183
                    is.close();
184
                    if ( (outputFormat == null) || (outputFormat.indexOf("xml") != -1)
185
                                    ||output.toString().toLowerCase().startsWith("<?xml")
186
                                    ||(outputFormat.indexOf("gml") != -1))
187
                    {
188
                            int tag;
189
                            KXmlParser kxmlParser = null;
190
                            kxmlParser = new KXmlParser();            
191
                            kxmlParser.setInput(new StringReader(output.toString()));
192
                            
193
                            tag = kxmlParser.nextTag();           
194
                            if (kxmlParser.getName().compareTo(ServiceException)==0)
195
                                {
196
                                    sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
197
                                    return sb.toString();                                                                        
198
                                }
199
                                else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
200
                                {
201
                                        return output.toString();
202
                                }
203
                                else                
204
                                {
205
                                        return output.toString();                
206
                                }
207
                                                            
208
//                                  while(tag != KXmlParser.END_DOCUMENT)
209
//                                 {
210
//                                         switch(tag)
211
//                                         {
212
//                                                case KXmlParser.START_TAG:                
213
//                                                        if (kxmlParser.getName().compareTo(ServiceException)==0)
214
//                                                        {
215
//                                                            sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
216
//                                                            return sb.toString();                                                                        
217
//                                                        }
218
//                                                        else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
219
//                                                                return output.toString();
220
//                                                        else                                                                
221
//                                                                sb.append("<" + kxmlParser.getName() + ">\n");                                                        
222
//                                                        break;
223
//                                                case KXmlParser.END_TAG:        
224
//                                                        sb.append("</" + kxmlParser.getName() + ">\n");
225
//                                                        break;
226
//                                                case KXmlParser.TEXT:
227
//                                                        sb.append(kxmlParser.getText());                                                
228
//                                                break;
229
//                                         }
230
//                                     tag = kxmlParser.next();
231
//                             }                                    
232
                            //return sb.toString();
233
                    }
234
                    else
235
                    {
236
//                            sb.append("<INFO>").append("Info format not supported").append("</INFO>");
237
//                            return sb.toString();
238
                            //Para que funcione con el GetFeatureInfo Viewer generico hay que devolver:
239
                             return output.toString();
240
                    }
241
                }
242
            catch(XmlPullParserException parserEx)
243
            {
244
                    if (output.toString().toLowerCase().indexOf("xml") != -1)
245
                    {
246
                            return output.toString().trim();
247
                    }
248
                    else
249
                    {
250
                               sb.append("<INFO>").append("Info format not supported").append("</INFO>");
251
                        return sb.toString();
252
                    }
253
            }
254
            catch(Exception e)
255
            {
256
                    e.printStackTrace();
257
                    sb.append("<INFO>").append("Info format not supported").append("</INFO>");
258
                    return sb.toString();
259

    
260
            }
261
    }
262
    /**
263
     * <p>Builds a GetMap request that is sent to the WMS
264
     * the response (image) will be redirect to the
265
     * WMS client</p>
266
     */   
267
    public byte[] _getMap(WMSStatus status) throws ServerErrorException, WMSException
268
    {        
269
            URL request = null;
270
                try
271
                {
272
                        //TODO:
273
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
274
                        request = new URL(buildMapRequest(status));
275
                        URLConnection conn = request.openConnection();
276
                        System.out.println(request.toString());
277
            String type = conn.getContentType();
278
            
279
                                
280
                    byte[] imageBytes = null;
281
                    byte[] buffer = new byte[1024*256];
282
            InputStream is = conn.getInputStream();
283
                    int readed = 0;
284
                    
285
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
286
                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
287
                            byte[] buffered = new byte[readed+i];
288
                            for (int j = 0; j < buffered.length; j++) {
289
                                    if (j<readed){
290
                        // puts the previously downloaded bytes into the image buffer
291
                                            buffered[j] = imageBytes[j];
292
                                    }
293
                                    else {
294
                        // appends the recently downloaded bytes to the image buffer.
295
                                            buffered[j] = buffer[j-readed];
296
                                    }
297
                                }
298
                            imageBytes = (byte[]) buffered.clone();
299
                            readed += i;                            
300
                    }
301
                    
302
                    if ((type !=null && !type.subSequence(0,5).equals("image")) 
303
                            ||(Utilities.isTextData(imageBytes)))
304
                    {                            
305
                       WMSException wmsEx = null;
306
                       
307
                    String exceptionMessage = parseException(imageBytes);
308
                if (exceptionMessage==null)
309
                {
310
                         String error = new String(imageBytes);
311
                        int pos = error.indexOf("<?xml");
312
                        if (pos!= -1)
313
                        {
314
                                String xml = error.substring(pos,error.length());
315
                                exceptionMessage = parseException(xml.getBytes());
316
                        if (exceptionMessage == null)
317
                                exceptionMessage = new String(imageBytes);
318
                        }
319
                }
320
                     wmsEx = new WMSException(exceptionMessage);
321
                    wmsEx.setWMSMessage(new String(imageBytes));
322
                throw wmsEx;
323
            }
324
                        return imageBytes;                    
325
                }
326
                catch(IOException e)
327
                {
328
                        e.printStackTrace();
329
            throw new ServerErrorException();
330
                }
331
    } 
332
    
333
    public File getLegendGraphic(String layerName, ICancellable cancel) throws ServerErrorException, WMSException
334
    {
335
            URL request = null;
336
                try
337
                {
338
                        request = new URL(buildGetLegendGraphicRequest(layerName));     
339
                        System.out.println(request);
340
            File f = Utilities.downloadFile(request, "wmsGetLegendGraphic", cancel);                                        
341
                    if (f== null)
342
                            return null;
343
            if (Utilities.isTextFile(f)) {
344
                            FileInputStream fis = new FileInputStream(f);
345
                            FileChannel fc = fis.getChannel();
346
                            byte[] data = new byte[(int)fc.size()];
347
                            ByteBuffer bb = ByteBuffer.wrap(data);
348
                            fc.read(bb);
349
                                                        
350
                            WMSException wmsEx = null;
351
                       
352
                    String exceptionMessage = parseException(data);
353
                if (exceptionMessage==null)
354
                {
355
                         String error = new String(data);
356
                        int pos = error.indexOf("<?xml");
357
                        if (pos!= -1)
358
                        {
359
                                String xml = error.substring(pos,error.length());
360
                                exceptionMessage = parseException(xml.getBytes());
361
                        }               
362
                    if (exceptionMessage == null)
363
                            exceptionMessage = new String(data);
364
                        
365
                }
366
                     wmsEx = new WMSException(exceptionMessage);
367
                    wmsEx.setWMSMessage(new String(data));
368
                    Utilities.removeURL(request);
369
                throw wmsEx;
370
            }
371
                        return f;                    
372
                }
373
                catch(IOException e)
374
                {
375
                        e.printStackTrace();
376
            throw new ServerErrorException();
377
                }
378
    } 
379
    
380
    public File getMap(WMSStatus status, ICancellable cancel) throws ServerErrorException, WMSException
381
    {        
382
            URL request = null;
383
                try
384
                {
385
                        //TODO:
386
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
387
                        request = new URL(buildMapRequest(status));
388
            
389
            File f = Utilities.downloadFile(request, "wmsGetMap", cancel);                                        
390
                    if (f== null)
391
                            return null;
392
            if (Utilities.isTextFile(f)) {
393
                            FileInputStream fis = new FileInputStream(f);
394
                            FileChannel fc = fis.getChannel();
395
                            byte[] data = new byte[(int)fc.size()];   // fc.size returns the size of the file which backs the channel
396
                            ByteBuffer bb = ByteBuffer.wrap(data);
397
                            fc.read(bb);
398
                                                        
399
                            WMSException wmsEx = null;
400
                       
401
                    String exceptionMessage = parseException(data);
402
                if (exceptionMessage==null)
403
                {
404
                         String error = new String(data);
405
                        int pos = error.indexOf("<?xml");
406
                        if (pos!= -1)
407
                        {
408
                                String xml = error.substring(pos,error.length());
409
                                exceptionMessage = parseException(xml.getBytes());
410
//                        if (exceptionMessage == null)
411
//                                exceptionMessage = new String(data);
412
                        }               
413
                    if (exceptionMessage == null)
414
                            exceptionMessage = new String(data);
415
                        
416
                }
417
                     wmsEx = new WMSException(exceptionMessage);
418
                    wmsEx.setWMSMessage(new String(data));
419
                    
420
                    // Since it is an error file, It must be deleted from the cache
421
                    Utilities.removeURL(request);
422
                throw wmsEx;
423
            }
424
                        return f;                    
425
                }
426
                catch(IOException e)
427
                {
428
                        e.printStackTrace();
429
            throw new ServerErrorException();
430
                }
431
    } 
432
    
433
    
434
    /* (non-Javadoc)
435
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
436
     */
437
    protected String parseException(byte[] data) {
438
        ArrayList errors = new ArrayList();
439
        KXmlParser kxmlParser = new KXmlParser();
440
        try
441
        {
442
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);        
443
            kxmlParser.nextTag();
444
            int tag;
445
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
446
            { 
447
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);             
448
                tag = kxmlParser.nextTag();
449
                 while(tag != KXmlParser.END_DOCUMENT)
450
                 {
451
                     switch(tag)
452
                     {
453
                        case KXmlParser.START_TAG:
454
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
455
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
456
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
457
                                String errorMessage = kxmlParser.nextText();
458
                                errors.add(errorCode+errorMessage);
459
                            }
460
                            break;
461
                        case KXmlParser.END_TAG:                            
462
                            break;
463
                        
464
                     }
465
                     tag = kxmlParser.nextTag();
466
                 }
467
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
468
            }
469
        }
470
        catch(XmlPullParserException parser_ex){ 
471
            parser_ex.printStackTrace();
472
        }
473
        catch (IOException ioe) {           
474
            ioe.printStackTrace();            
475
        }
476
        String message = errors.size()>0? "" : null;
477
        for (int i = 0; i < errors.size(); i++) {
478
            message += (String) errors.get(i)+"\n";
479
        }
480
        return message;
481
    }
482
    /**
483
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
484
     * without a VERSION, to get the highest version than a WMS supports.
485
     */
486
    public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version)
487
    {
488
                String req = new String();                
489
        String symbol = getSymbol(_host);
490
        req = req + _host + symbol + "REQUEST=GetCapabilities&SERVICE=WMS&";                
491
        if((_version != null) && (_version.length()>0 ))
492
        {
493
                req += ("&VERSION=" + _version);
494
        }
495
                req += ("&EXCEPTIONS=XML");
496
                return req;           
497
    }
498
    
499
    /**
500
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
501
     * @param WMSStatus
502
     */
503
    private String buildCapabilitiesRequest(WMSStatus status)
504
    {
505
                StringBuffer req = new StringBuffer();
506
                String symbol = null;
507
                
508
                String onlineResource;
509
                if (status == null || status.getOnlineResource() == null)
510
                        onlineResource = getHost();
511
                else 
512
                        onlineResource = status.getOnlineResource();
513
                symbol = getSymbol(onlineResource);
514
                
515
                req.append(onlineResource).append(symbol).append("REQUEST=GetCapabilities&SERVICE=WMS&");
516
                req.append("VERSION=").append(getVersion()).append("&EXCEPTIONS=XML");
517
                return req.toString();
518
    }
519
    
520
    /**
521
     * Builds the GetFeatureInfoRequest according to the OGC WMS Specifications
522
     */
523
    protected String buildGetFeatureInfoRequest(WMSStatus status, int x, int y)
524
    {
525
                StringBuffer req = new StringBuffer();
526
                String symbol = null;
527

    
528
                String onlineResource;
529
                if (status.getOnlineResource() == null)
530
                        onlineResource = getHost();
531
                else 
532
                        onlineResource = status.getOnlineResource();
533
                symbol = getSymbol(onlineResource);
534
        
535
                req.append(onlineResource).append(symbol).append("REQUEST=GetFeatureInfo&SERVICE=WMS&");
536
                req.append("QUERY_LAYERS=").append(Utilities.Vector2CS(status.getLayerNames())); 
537
                req.append("&VERSION=").append(getVersion()).append("&INFO_FORMAT=application/vnd.ogc.gml&");
538
                req.append(getPartialQuery(status)).append("&x="+x + "&y="+y);
539
                //this parameter sets the max number of features per layer to be returned.
540
                //we set it to avoid the bug in mapserver that takes this number like max number of total features.
541
                req.append("&FEATURE_COUNT=10000");
542
       if (status.getExceptionFormat() != null) {
543
            req.append("&EXCEPTIONS=" + status.getExceptionFormat());
544
        } else {
545
            req.append("&EXCEPTIONS=XML");
546
        }
547
                return req.toString().replaceAll(" ", "%20");
548
    }    
549

    
550
    /**
551
     * Builds the GetMapRequest according to the OGC WMS Specifications
552
     */
553
    private String buildGetLegendGraphicRequest(String layerName)
554
    { 
555
                StringBuffer req = new StringBuffer();
556
                String symbol = null;
557
                String onlineResource = null;
558
                onlineResource = getHost();
559
                symbol = getSymbol(onlineResource);
560
        
561
                req.append(onlineResource + symbol + "REQUEST=GetLegendGraphic&SERVICE=WMS&VERSION=").append(getVersion()).append("&");
562
        req.append("LAYER=" + layerName)
563
        .append("&FORMAT=image/png");
564
                return req.toString().replaceAll(" ", "%20");
565
    }
566

    
567
    /**
568
     * Builds the GetMapRequest according to the OGC WMS Specifications
569
     */
570
    private String buildMapRequest(WMSStatus status)
571
    { 
572
                StringBuffer req = new StringBuffer();
573
                String symbol = null;
574
                String onlineResource = null;
575
                
576
                if (status.getOnlineResource() == null)
577
                        onlineResource = getHost();
578
                else 
579
                        onlineResource = status.getOnlineResource();
580
                symbol = getSymbol(onlineResource);
581
        
582
                req.append(onlineResource + symbol + "REQUEST=GetMap&SERVICE=WMS&VERSION=").append(getVersion()).append("&");
583
                req.append(getPartialQuery(status));
584
//        if (status.getExceptionFormat() != null) {
585
//            req.append("&EXCEPTIONS=" + status.getExceptionFormat());
586
//        } else {
587
//            req.append("&EXCEPTIONS=XML");
588
//        }
589
                return req.toString().replaceAll(" ", "%20");
590
    }
591
    
592
    /**
593
     * Just for not repeat code. Gets the correct separator according to the server URL
594
     * @param h
595
     * @return
596
     */
597
    private static String getSymbol(String h) {
598
        String symbol;
599
        if (h.indexOf("?")==-1) 
600
            symbol = "?";
601
        else if (h.indexOf("?")!=h.length()-1)
602
            symbol = "&";
603
        else
604
            symbol = "";
605
        return symbol;
606
    }
607

    
608
    /**
609
     * Gets the part of the OGC request that share GetMap and GetFeatureInfo
610
     * @return String request
611
     */
612
    public String getPartialQuery(WMSStatus status)
613
    {            
614
        StringBuffer req = new StringBuffer();
615
        req.append("LAYERS=" + Utilities.Vector2CS(status.getLayerNames()))
616
           .append("&SRS=" + status.getSrs())
617
           .append("&BBOX=" + status.getExtent().getMinX()+ "," )
618
           .append(status.getExtent().getMinY()+ ",")
619
           .append(status.getExtent().getMaxX()+ ",")
620
           .append(status.getExtent().getMaxY())
621
           .append("&WIDTH=" + status.getWidth())
622
           .append("&HEIGHT=" + status.getHeight())
623
           .append("&FORMAT=" + status.getFormat())
624
           .append("&STYLES=");
625
        Vector v = status.getStyles();
626
        if (v!=null && v.size()>0)
627
                req.append(Utilities.Vector2CS(v)); 
628
        v = status.getDimensions();
629
        if (v!=null && v.size()>0)
630
            req.append("&" + Utilities.Vector2URLParamString(v));
631
        if (status.getTransparency()) {
632
            req.append("&TRANSPARENT=TRUE");
633
        }
634
        return req.toString();
635
    }
636

    
637
    
638
    
639
    public void close() {        
640
        // your code here
641
    } 
642
    
643
    /**
644
     * Inner class that represents the description of the WMS metadata.
645
     * The first part of the capabilities will return the service information
646
     * from the WMS, this class will hold this information. 
647
     * 
648
     */
649
    public class ServiceInformation {
650

    
651
        public String online_resource = null;
652
        /*public String map_online_resource = null;
653
        public String feature_online_resource = null;*/
654
        public String version;
655
        public String name;
656
        public String scope;
657
        public String title;
658
        public String abstr;
659
        public String keywords;
660
        public String fees;
661
        public String operationsInfo;
662
        public String personname;
663
        public String organization;
664
        public String function;
665
        public String addresstype;
666
        public String address;
667
        public String place;
668
        public String province;
669
        public String postcode;
670
        public String country;
671
        public String phone;
672
        public String fax;
673
        public String email;
674
        public Vector formats;
675
        public HashMap operations; // operations that WMS supports
676
        
677
        public ServiceInformation()
678
        {          
679
            version = new String();
680
            name = new String();
681
            scope = new String();
682
            title = new String();
683
            abstr = new String();
684
            keywords = new String();
685
            fees = new String();
686
            operationsInfo = new String();
687
            personname = new String();
688
            organization = new String();
689
            function = new String();
690
            addresstype = new String();
691
            address = new String();
692
            place = new String();
693
            province = new String();
694
            postcode = new String();
695
            country = new String();
696
            phone = new String();
697
            fax = new String();
698
            email = new String();
699
            formats = new Vector();               
700
            operations = new HashMap();            
701
        }
702
        public boolean isQueryable()
703
        {
704
                if (operations.keySet().contains( CapabilitiesTags.GETFEATUREINFO ))
705
                        return true;
706
                else
707
                        return false;
708
        }
709
        
710
        public void clear() {
711
                version = new String();
712
            name = new String();
713
            scope = new String();
714
            title = new String();
715
            abstr = new String();
716
            keywords = new String();
717
            fees = new String();
718
            operationsInfo = new String();
719
            personname = new String();
720
            organization = new String();
721
            function = new String();
722
            addresstype = new String();
723
            address = new String();
724
            place = new String();
725
            province = new String();
726
            postcode = new String();
727
            country = new String();
728
            phone = new String();
729
            fax = new String();
730
            email = new String();
731
            formats = new Vector();               
732
            operations = new HashMap();            
733
        }
734
     }   
735
 }