Revision 11381 trunk/libraries/libRemoteServices/src/org/gvsig/remoteClient/wms/WMSProtocolHandler.java

View differences:

WMSProtocolHandler.java
26 26
/**
27 27
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.
28 28
 * </p>
29
 * 
29
 *
30 30
 */
31 31
public abstract class WMSProtocolHandler {
32 32
	/**
......
48 48
    /**
49 49
     * port number of the comunication channel of the WMS to connect
50 50
     */
51
    protected String port;    
51
    protected String port;
52 52
    /**
53 53
     * WMS metadata
54 54
     */
......
56 56
    public TreeMap layers;
57 57
    public WMSLayer rootLayer;
58 58
//    public Vector srs;
59
    
59

  
60 60
    /**
61
     * parses the data retrieved by the WMS in XML format. 
61
     * parses the data retrieved by the WMS in XML format.
62 62
     * It will be mostly the WMS Capabilities, but the implementation
63 63
     * will be placed in the handler implementing certain version of the protocol.
64
     * 
64
     *
65 65
     */
66 66
    public abstract void parse(File f) ;
67
    
67

  
68 68
    /**
69 69
     * returns the alfanumeric information of the layers at the specified point.
70 70
     * the diference between the other getfeatureInfo method is that this will
71 71
     * be implemented by each specific version because the XML from the server will be
72 72
     * parsed and presented by a well known structure.
73
     */    
73
     */
74 74

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

  
79
    public String getVersion() {        
79
    public String getVersion() {
80 80
    	return version;
81
    }    
82
    
83
    public ServiceInformation getServiceInformation() {        
81
    }
82

  
83
    public ServiceInformation getServiceInformation() {
84 84
        return serviceInfo;
85
    }  
85
    }
86 86
    public String getHost ()
87 87
    {
88 88
    	return host;
......
99 99
    {
100 100
    	port = _port;
101 101
    }
102
    
103 102

  
103

  
104 104
    /**
105 105
	 * <p>Builds a GetCapabilities request that is sent to the WMS
106 106
	 * the response will be parse to extract the data needed by the
......
108 108
	 * @param override, if true the previous downloaded data will be overridden
109 109
	 */
110 110
    public void getCapabilities(WMSStatus status, boolean override, ICancellable cancel)
111
    {		
111
    {
112 112
    	URL request = null;
113 113
		try
114 114
		{
......
120 120
		}
121 121
		try
122 122
		{
123
			if (override) 
123
			if (override)
124 124
				Utilities.removeURL(request);
125 125
			File f = Utilities.downloadFile(request,"wms_capabilities.xml", cancel);
126 126
			if (f == null)
......
146 146
     */
147 147
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount, ICancellable cancel)
148 148
    {
149
		
149

  
150 150
    	URL request = null;
151 151
    	StringBuffer output = new StringBuffer();
152 152
    	String outputFormat = new String();
153
    	String ServiceException = "ServiceExceptionReport";    	    	
153
    	String ServiceException = "ServiceExceptionReport";
154 154
    	StringBuffer sb = new StringBuffer();
155 155
    	sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
156 156
		try
......
160 160
	    	File f = Utilities.downloadFile(request,"wms_feature_info.xml", cancel);
161 161
			if (f == null)
162 162
				return "";
163
			
164
//	    	byte[] buffer = new byte[1024*256];	    	
165
//	    	DataInputStream is = new DataInputStream();	    	
163

  
164
//	    	byte[] buffer = new byte[1024*256];
165
//	    	DataInputStream is = new DataInputStream();
166 166
//	    	outputFormat = request.openConnection().getContentType();
167 167
//	    	for (int i = f.read(buffer); i>0; i = is.read(buffer))
168 168
//	    	{
169 169
//	    		String str = new String(buffer,0,i);
170
//	    		output.append(str);	    	
170
//	    		output.append(str);
171 171
//	    	}
172
//	    		    
172
//
173 173
//	    	is.close();
174 174
			FileReader fReader = new FileReader(f);
175 175
			char[] buffer = new char[1024*256];
176 176
			for (int i = fReader.read(buffer); i>0; i = fReader.read(buffer))
177 177
		    {
178 178
		    	String str = new String(buffer,0,i);
179
		    	output.append(str);	    	
179
		    	output.append(str);
180 180
		    }
181 181
		    if ( (outputFormat == null) || (outputFormat.indexOf("xml") != -1)
182 182
		    		||output.toString().toLowerCase().startsWith("<?xml")
......
184 184
		    {
185 185
		    	int tag;
186 186
		    	KXmlParser kxmlParser = null;
187
		    	kxmlParser = new KXmlParser();	    
188
		    	//kxmlParser.setInput(new StringReader(output.toString()));		    	
187
		    	kxmlParser = new KXmlParser();
188
		    	//kxmlParser.setInput(new StringReader(output.toString()));
189 189
		    	kxmlParser.setInput(new FileReader(f));
190
		    	
191
		    	tag = kxmlParser.nextTag();   	
190

  
191
		    	tag = kxmlParser.nextTag();
192 192
		    	if (kxmlParser.getName().compareTo(ServiceException)==0)
193 193
				{
194 194
		    		sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
195
		    		return sb.toString();									
195
		    		return sb.toString();
196 196
				}
197 197
				else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
198 198
				{
199 199
					return output.toString();
200 200
				}
201
				else		
201
				else
202 202
				{
203
					return output.toString();		
203
					return output.toString();
204 204
				}
205
					    		
205

  
206 206
// 				 while(tag != KXmlParser.END_DOCUMENT)
207 207
//				 {
208 208
//					 switch(tag)
209 209
//					 {
210
//						case KXmlParser.START_TAG:		
210
//						case KXmlParser.START_TAG:
211 211
//							if (kxmlParser.getName().compareTo(ServiceException)==0)
212 212
//							{
213 213
//					    		sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
214
//					    		return sb.toString();									
214
//					    		return sb.toString();
215 215
//							}
216 216
//							else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
217 217
//								return output.toString();
218
//							else								
219
//								sb.append("<" + kxmlParser.getName() + ">\n");							
218
//							else
219
//								sb.append("<" + kxmlParser.getName() + ">\n");
220 220
//							break;
221
//						case KXmlParser.END_TAG:	
221
//						case KXmlParser.END_TAG:
222 222
//							sb.append("</" + kxmlParser.getName() + ">\n");
223 223
//							break;
224 224
//						case KXmlParser.TEXT:
225
//							sb.append(kxmlParser.getText());						
225
//							sb.append(kxmlParser.getText());
226 226
//						break;
227 227
//					 }
228 228
//    				 tag = kxmlParser.next();
229
//    			 }		    		
229
//    			 }
230 230
	    		//return sb.toString();
231 231
	    	}
232 232
	    	else
......
261 261
     * <p>Builds a GetMap request that is sent to the WMS
262 262
     * the response (image) will be redirect to the
263 263
     * WMS client</p>
264
     */   
264
     */
265 265
    public byte[] _getMap(WMSStatus status) throws ServerErrorException, WMSException
266
    {        
266
    {
267 267
    	URL request = null;
268 268
		try
269 269
		{
......
273 273
			URLConnection conn = request.openConnection();
274 274
			System.out.println(request.toString());
275 275
            String type = conn.getContentType();
276
            
277
                        	
276

  
277

  
278 278
	    	byte[] imageBytes = null;
279 279
	    	byte[] buffer = new byte[1024*256];
280 280
            InputStream is = conn.getInputStream();
281 281
	    	int readed = 0;
282
	    	
282

  
283 283
	    	for (int i = is.read(buffer); i>0; i = is.read(buffer)){
284 284
                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
285 285
	    		byte[] buffered = new byte[readed+i];
......
294 294
	    			}
295 295
				}
296 296
	    		imageBytes = (byte[]) buffered.clone();
297
	    		readed += i;	    		
297
	    		readed += i;
298 298
	    	}
299
	    	
300
	    	if ((type !=null && !type.subSequence(0,5).equals("image")) 
299

  
300
	    	if ((type !=null && !type.subSequence(0,5).equals("image"))
301 301
	    		||(Utilities.isTextData(imageBytes)))
302
	    	{	    		
302
	    	{
303 303
               	WMSException wmsEx = null;
304
               	
304

  
305 305
            	String exceptionMessage = parseException(imageBytes);
306 306
                if (exceptionMessage==null)
307 307
                {
......
319 319
            	wmsEx.setWMSMessage(new String(imageBytes));
320 320
                throw wmsEx;
321 321
            }
322
			return imageBytes;	    	
322
			return imageBytes;
323 323
		}
324 324
		catch(IOException e)
325 325
		{
326 326
			e.printStackTrace();
327 327
            throw new ServerErrorException();
328 328
		}
329
    } 
330
    
329
    }
330

  
331 331
    public File getLegendGraphic(WMSStatus status, String layerName, ICancellable cancel) throws ServerErrorException, WMSException
332 332
    {
333 333
    	URL request = null;
334 334
		try
335 335
		{
336
			request = new URL(buildGetLegendGraphicRequest(status, layerName));     
336
			request = new URL(buildGetLegendGraphicRequest(status, layerName));
337 337
			System.out.println(request);
338
            File f = Utilities.downloadFile(request, "wmsGetLegendGraphic", cancel);            		    	
338
            File f = Utilities.downloadFile(request, "wmsGetLegendGraphic", cancel);
339 339
	    	if (f== null)
340 340
	    		return null;
341 341
            if (Utilities.isTextFile(f)) {
......
344 344
	    		byte[] data = new byte[(int)fc.size()];
345 345
	    		ByteBuffer bb = ByteBuffer.wrap(data);
346 346
	    		fc.read(bb);
347
	    			    		
347

  
348 348
	    		WMSException wmsEx = null;
349
               	
349

  
350 350
            	String exceptionMessage = parseException(data);
351 351
                if (exceptionMessage==null)
352 352
                {
......
356 356
                	{
357 357
                		String xml = error.substring(pos,error.length());
358 358
                		exceptionMessage = parseException(xml.getBytes());
359
                	}               
359
                	}
360 360
                    if (exceptionMessage == null)
361 361
                    	exceptionMessage = new String(data);
362
                	
362

  
363 363
                }
364 364
             	wmsEx = new WMSException(exceptionMessage);
365 365
            	wmsEx.setWMSMessage(new String(data));
366 366
            	Utilities.removeURL(request);
367 367
                throw wmsEx;
368 368
            }
369
			return f;	    	
369
			return f;
370 370
		}
371 371
		catch(IOException e)
372 372
		{
373 373
			e.printStackTrace();
374 374
            throw new ServerErrorException();
375 375
		}
376
    } 
377
    
376
    }
377

  
378 378
    public File getMap(WMSStatus status, ICancellable cancel) throws ServerErrorException, WMSException
379
    {        
379
    {
380 380
    	URL request = null;
381 381
		try
382 382
		{
383 383
			//TODO:
384 384
			//pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
385 385
			request = new URL(buildMapRequest(status));
386
            
387
            File f = Utilities.downloadFile(request, "wmsGetMap", cancel);            		    	
386

  
387
            File f = Utilities.downloadFile(request, "wmsGetMap", cancel);
388 388
	    	if (f== null)
389 389
	    		return null;
390 390
            if (Utilities.isTextFile(f)) {
......
393 393
	    		byte[] data = new byte[(int)fc.size()];   // fc.size returns the size of the file which backs the channel
394 394
	    		ByteBuffer bb = ByteBuffer.wrap(data);
395 395
	    		fc.read(bb);
396
	    			    		
396

  
397 397
	    		WMSException wmsEx = null;
398
               	
398

  
399 399
            	String exceptionMessage = parseException(data);
400 400
                if (exceptionMessage==null)
401 401
                {
......
407 407
                		exceptionMessage = parseException(xml.getBytes());
408 408
//                        if (exceptionMessage == null)
409 409
//                        	exceptionMessage = new String(data);
410
                	}               
410
                	}
411 411
                    if (exceptionMessage == null)
412 412
                    	exceptionMessage = new String(data);
413
                	
413

  
414 414
                }
415 415
             	wmsEx = new WMSException(exceptionMessage);
416 416
            	wmsEx.setWMSMessage(new String(data));
417
            	
417

  
418 418
            	// Since it is an error file, It must be deleted from the cache
419 419
            	Utilities.removeURL(request);
420 420
                throw wmsEx;
421 421
            }
422
			return f;	    	
422
			return f;
423 423
		}
424 424
		catch(IOException e)
425 425
		{
426 426
			e.printStackTrace();
427 427
            throw new ServerErrorException();
428 428
		}
429
    } 
430
    
431
    
429
    }
430

  
431

  
432 432
    /* (non-Javadoc)
433 433
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
434 434
     */
......
437 437
        KXmlParser kxmlParser = new KXmlParser();
438 438
        try
439 439
        {
440
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);        
440
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);
441 441
            kxmlParser.nextTag();
442 442
            int tag;
443
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
444
            { 
445
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);             
443
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
444
            {
445
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);
446 446
                tag = kxmlParser.nextTag();
447 447
                 while(tag != KXmlParser.END_DOCUMENT)
448 448
                 {
......
456 456
                                errors.add(errorCode+errorMessage);
457 457
                            }
458 458
                            break;
459
                        case KXmlParser.END_TAG:                            
459
                        case KXmlParser.END_TAG:
460 460
                            break;
461
                        
461

  
462 462
                     }
463 463
                     tag = kxmlParser.nextTag();
464 464
                 }
465 465
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
466 466
            }
467 467
        }
468
        catch(XmlPullParserException parser_ex){ 
468
        catch(XmlPullParserException parser_ex){
469 469
            parser_ex.printStackTrace();
470 470
        }
471
        catch (IOException ioe) {           
472
            ioe.printStackTrace();            
471
        catch (IOException ioe) {
472
            ioe.printStackTrace();
473 473
        }
474 474
        String message = errors.size()>0? "" : null;
475 475
        for (int i = 0; i < errors.size(); i++) {
......
483 483
     */
484 484
    public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version)
485 485
    {
486
		String req = new String();		
486
		String req = new String();
487 487
        String symbol = getSymbol(_host);
488
        req = req + _host + symbol + "REQUEST=GetCapabilities&SERVICE=WMS&";		
488
        req = req + _host + symbol + "SERVICE=WMS&REQUEST=GetCapabilities";
489 489
        if((_version != null) && (_version.length()>0 ))
490 490
        {
491 491
        	req += ("&VERSION=" + _version);
492 492
        }
493 493
		req += ("&EXCEPTIONS=XML");
494
		return req;   	
494
		return req;
495 495
    }
496
    
496

  
497 497
    /**
498 498
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
499 499
     * @param WMSStatus
......
502 502
    {
503 503
		StringBuffer req = new StringBuffer();
504 504
		String symbol = null;
505
		
505

  
506 506
		String onlineResource;
507 507
		if (status == null || status.getOnlineResource() == null)
508 508
			onlineResource = getHost();
509
		else 
509
		else
510 510
			onlineResource = status.getOnlineResource();
511 511
		symbol = getSymbol(onlineResource);
512
		
512

  
513 513
		req.append(onlineResource).append(symbol).append("REQUEST=GetCapabilities&SERVICE=WMS&");
514 514
		req.append("VERSION=").append(getVersion()).append("&EXCEPTIONS=XML");
515 515
		return req.toString();
516 516
    }
517
    
517

  
518 518
    /**
519 519
     * Builds the GetFeatureInfoRequest according to the OGC WMS Specifications
520 520
     */
......
527 527
		String onlineResource;
528 528
		if (status.getOnlineResource() == null)
529 529
			onlineResource = getHost();
530
		else 
530
		else
531 531
			onlineResource = status.getOnlineResource();
532 532
		symbol = getSymbol(onlineResource);
533
        
533

  
534 534
		req.append(onlineResource).append(symbol).append("REQUEST=GetFeatureInfo&SERVICE=WMS&");
535
		req.append("QUERY_LAYERS=").append(Utilities.Vector2CS(status.getLayerNames())); 
535
		req.append("QUERY_LAYERS=").append(Utilities.Vector2CS(status.getLayerNames()));
536 536
		req.append("&VERSION=").append(getVersion()).append("&INFO_FORMAT=application/vnd.ogc.gml&");
537 537
		req.append(getPartialQuery(status)).append("&x="+x + "&y="+y);
538 538
		//this parameter sets the max number of features per layer to be returned.
......
544 544
            req.append("&EXCEPTIONS=XML");
545 545
        }
546 546
		return req.toString().replaceAll(" ", "%20");
547
    }    
547
    }
548 548

  
549 549
    /**
550 550
     * Builds the GetMapRequest according to the OGC WMS Specifications
551 551
     */
552 552
    private String buildGetLegendGraphicRequest(WMSStatus status, String layerName)
553
    { 
553
    {
554 554
    	//TODO: pass by parameter the legend output format?
555 555
		StringBuffer req = new StringBuffer();
556 556
		String symbol = null;
557 557
		String onlineResource = null;
558
		
558

  
559 559
		if (status.getOnlineResource() == null)
560 560
			onlineResource = getHost();
561
		else 
561
		else
562 562
			onlineResource = status.getOnlineResource();
563 563
		symbol = getSymbol(onlineResource);
564
        
564

  
565 565
		req.append(onlineResource + symbol + "REQUEST=GetLegendGraphic&SERVICE=WMS&VERSION=").append(getVersion());
566 566
        req.append("&LAYER=" + layerName).append("&TRANSPARENT=TRUE").append("&FORMAT=image/png");
567 567
		return req.toString().replaceAll(" ", "%20");
......
571 571
     * Builds the GetMapRequest according to the OGC WMS Specifications
572 572
     */
573 573
    private String buildMapRequest(WMSStatus status)
574
    { 
574
    {
575 575
		StringBuffer req = new StringBuffer();
576 576
		String symbol = null;
577 577
		String onlineResource = null;
578
		
578

  
579 579
		if (status.getOnlineResource() == null)
580 580
			onlineResource = getHost();
581
		else 
581
		else
582 582
			onlineResource = status.getOnlineResource();
583 583
		symbol = getSymbol(onlineResource);
584
        
584

  
585 585
		req.append(onlineResource + symbol + "REQUEST=GetMap&SERVICE=WMS&VERSION=").append(getVersion()).append("&");
586 586
		req.append(getPartialQuery(status));
587 587
//        if (status.getExceptionFormat() != null) {
......
591 591
//        }
592 592
		return req.toString().replaceAll(" ", "%20");
593 593
    }
594
    
594

  
595 595
    /**
596 596
     * Just for not repeat code. Gets the correct separator according to the server URL
597 597
     * @param h
......
599 599
     */
600 600
    protected static String getSymbol(String h) {
601 601
        String symbol;
602
        if (h.indexOf("?")==-1) 
602
        if (h.indexOf("?")==-1)
603 603
            symbol = "?";
604 604
        else if (h.indexOf("?")!=h.length()-1)
605 605
            symbol = "&";
......
613 613
     * @return String request
614 614
     */
615 615
    public String getPartialQuery(WMSStatus status)
616
    {    	
616
    {
617 617
        StringBuffer req = new StringBuffer();
618 618
        req.append("LAYERS=" + Utilities.Vector2CS(status.getLayerNames()))
619 619
           .append("&SRS=" + status.getSrs())
......
627 627
           .append("&STYLES=");
628 628
        Vector v = status.getStyles();
629 629
        if (v!=null && v.size()>0)
630
        	req.append(Utilities.Vector2CS(v)); 
630
        	req.append(Utilities.Vector2CS(v));
631 631
        v = status.getDimensions();
632 632
        if (v!=null && v.size()>0)
633 633
            req.append("&" + Utilities.Vector2URLParamString(v));
......
637 637
        return req.toString();
638 638
    }
639 639

  
640
    
641
    
642
    public void close() {        
640

  
641

  
642
    public void close() {
643 643
        // your code here
644
    } 
645
    
644
    }
645

  
646 646
    /**
647 647
     * Inner class that represents the description of the WMS metadata.
648 648
     * The first part of the capabilities will return the service information
649
     * from the WMS, this class will hold this information. 
650
     * 
649
     * from the WMS, this class will hold this information.
650
     *
651 651
     */
652 652
    public class ServiceInformation {
653 653

  
......
676 676
        public String email;
677 677
        public Vector formats;
678 678
        public HashMap operations; // operations that WMS supports
679
        
679

  
680 680
        public ServiceInformation()
681
        {  	
681
        {
682 682
            version = new String();
683 683
            name = new String();
684 684
            scope = new String();
......
699 699
            phone = new String();
700 700
            fax = new String();
701 701
            email = new String();
702
            formats = new Vector();       	
703
            operations = new HashMap();            
702
            formats = new Vector();
703
            operations = new HashMap();
704 704
        }
705 705
        public boolean isQueryable()
706 706
        {
......
715 715
        		return true;
716 716
        	else
717 717
        		return false;
718
        }        
718
        }
719 719
        public void clear() {
720 720
        	version = new String();
721 721
            name = new String();
......
737 737
            phone = new String();
738 738
            fax = new String();
739 739
            email = new String();
740
            formats = new Vector();       	
741
            operations = new HashMap();            
740
            formats = new Vector();
741
            operations = new HashMap();
742 742
        }
743
     }   
743
     }
744 744
 }

Also available in: Unified diff