Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_909 / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / WMSProtocolHandler.java @ 11150

History | View | Annotate | Download (24.2 KB)

1
package org.gvsig.remoteClient.wms;
2

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

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

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

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

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

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

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

    
142
        /**
143
     * <p>It will send a GetFeatureInfo request to the WMS
144
     * Parsing the response and redirecting the info to the WMS client</p>
145
     * TODO: return a stored file instead a String.
146
     */
147
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount, ICancellable cancel)
148
    {
149
                
150
            URL request = null;
151
            StringBuffer output = new StringBuffer();
152
            String outputFormat = new String();
153
            String ServiceException = "ServiceExceptionReport";                        
154
            StringBuffer sb = new StringBuffer();
155
            sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
156
                try
157
                {
158
                        request = new URL(buildGetFeatureInfoRequest(status, x, y));
159
                    outputFormat = request.openConnection().getContentType();
160
                    File f = Utilities.downloadFile(request,"wms_feature_info.xml", cancel);
161
                        if (f == null)
162
                                return "";
163
                        
164
//                    byte[] buffer = new byte[1024*256];                    
165
//                    DataInputStream is = new DataInputStream();                    
166
//                    outputFormat = request.openConnection().getContentType();
167
//                    for (int i = f.read(buffer); i>0; i = is.read(buffer))
168
//                    {
169
//                            String str = new String(buffer,0,i);
170
//                            output.append(str);                    
171
//                    }
172
//                                
173
//                    is.close();
174
                        FileReader fReader = new FileReader(f);
175
                        char[] buffer = new char[1024*256];
176
                        for (int i = fReader.read(buffer); i>0; i = fReader.read(buffer))
177
                    {
178
                            String str = new String(buffer,0,i);
179
                            output.append(str);                    
180
                    }
181
                    if ( (outputFormat == null) || (outputFormat.indexOf("xml") != -1)
182
                                    ||output.toString().toLowerCase().startsWith("<?xml")
183
                                    ||(outputFormat.indexOf("gml") != -1))
184
                    {
185
                            int tag;
186
                            KXmlParser kxmlParser = null;
187
                            kxmlParser = new KXmlParser();            
188
                            //kxmlParser.setInput(new StringReader(output.toString()));                            
189
                            kxmlParser.setInput(new FileReader(f));
190
                            
191
                            tag = kxmlParser.nextTag();           
192
                            if (kxmlParser.getName().compareTo(ServiceException)==0)
193
                                {
194
                                    sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
195
                                    return sb.toString();                                                                        
196
                                }
197
                                else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
198
                                {
199
                                        return output.toString();
200
                                }
201
                                else                
202
                                {
203
                                        return output.toString();                
204
                                }
205
                                                            
206
//                                  while(tag != KXmlParser.END_DOCUMENT)
207
//                                 {
208
//                                         switch(tag)
209
//                                         {
210
//                                                case KXmlParser.START_TAG:                
211
//                                                        if (kxmlParser.getName().compareTo(ServiceException)==0)
212
//                                                        {
213
//                                                            sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
214
//                                                            return sb.toString();                                                                        
215
//                                                        }
216
//                                                        else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
217
//                                                                return output.toString();
218
//                                                        else                                                                
219
//                                                                sb.append("<" + kxmlParser.getName() + ">\n");                                                        
220
//                                                        break;
221
//                                                case KXmlParser.END_TAG:        
222
//                                                        sb.append("</" + kxmlParser.getName() + ">\n");
223
//                                                        break;
224
//                                                case KXmlParser.TEXT:
225
//                                                        sb.append(kxmlParser.getText());                                                
226
//                                                break;
227
//                                         }
228
//                                     tag = kxmlParser.next();
229
//                             }                                    
230
                            //return sb.toString();
231
                    }
232
                    else
233
                    {
234
//                            sb.append("<INFO>").append("Info format not supported").append("</INFO>");
235
//                            return sb.toString();
236
                            //Para que funcione con el GetFeatureInfo Viewer generico hay que devolver:
237
                             return output.toString();
238
                    }
239
                }
240
            catch(XmlPullParserException parserEx)
241
            {
242
                    if (output.toString().toLowerCase().indexOf("xml") != -1)
243
                    {
244
                            return output.toString().trim();
245
                    }
246
                    else
247
                    {
248
                               sb.append("<INFO>").append("Info format not supported").append("</INFO>");
249
                        return sb.toString();
250
                    }
251
            }
252
            catch(Exception e)
253
            {
254
                    e.printStackTrace();
255
                    sb.append("<INFO>").append("Info format not supported").append("</INFO>");
256
                    return sb.toString();
257

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

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

    
549
    /**
550
     * Builds the GetMapRequest according to the OGC WMS Specifications
551
     */
552
    private String buildGetLegendGraphicRequest(WMSStatus status, String layerName)
553
    { 
554
            //TODO: pass by parameter the legend output format?
555
                StringBuffer req = new StringBuffer();
556
                String symbol = null;
557
                String onlineResource = null;
558
                
559
                if (status.getOnlineResource() == null)
560
                        onlineResource = getHost();
561
                else 
562
                        onlineResource = status.getOnlineResource();
563
                symbol = getSymbol(onlineResource);
564
        
565
                req.append(onlineResource + symbol + "REQUEST=GetLegendGraphic&SERVICE=WMS&VERSION=").append(getVersion()).append("&");
566
        req.append("LAYER=" + layerName)
567
        .append("&FORMAT=image/png");
568
                return req.toString().replaceAll(" ", "%20");
569
    }
570

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

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

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

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