Revision 29658

View differences:

branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSProtocolHandler.java
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.StringTokenizer;
15
import java.util.TreeMap;
16

  
17
import org.gvsig.remoteclient.exceptions.ServerErrorException;
18
import org.gvsig.remoteclient.exceptions.WMSException;
19
import org.gvsig.remoteclient.ogc.OGCProtocolHandler;
20
import org.gvsig.remoteclient.ogc.OGCServiceInformation;
21
import org.gvsig.remoteclient.utils.CapabilitiesTags;
22
import org.gvsig.remoteclient.utils.ExceptionTags;
23
import org.gvsig.remoteclient.utils.Utilities;
24
import org.gvsig.remoteclient.wms.request.WMSGetFeatureInfoRequest;
25
import org.gvsig.remoteclient.wms.request.WMSGetLegendGraphicRequest;
26
import org.gvsig.remoteclient.wms.request.WMSGetMapRequest;
27
import org.kxml2.io.KXmlParser;
28
import org.xmlpull.v1.XmlPullParserException;
29

  
30
/**
31
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.
32
 * </p>
33
 *
34
 */
35
public abstract class WMSProtocolHandler extends OGCProtocolHandler{
36
	/**
37
	 * Encoding used to parse different xml documents.
38
	 */
39
	protected String encoding = "UTF-8";
40
    /**
41
     * WMS metadata
42
     */
43
    protected WMSServiceInformation serviceInfo;
44
    public TreeMap layers;
45
    public WMSLayer rootLayer;
46

  
47
    /**
48
     * returns the alfanumeric information of the layers at the specified point.
49
     * the diference between the other getfeatureInfo method is that this will
50
     * be implemented by each specific version because the XML from the server will be
51
     * parsed and presented by a well known structure.
52
     */
53

  
54
    public String getName() {
55
    	return name;
56
    }
57

  
58
    /*
59
     * (non-Javadoc)
60
     * @see org.gvsig.remoteClient.ogc.OGCProtocolHandler#getServiceInformation()
61
     */
62
    public OGCServiceInformation getServiceInformation() {
63
        return serviceInfo;
64
    }
65

  
66
    /**
67
	 * <p>Builds a GetCapabilities request that is sent to the WMS
68
	 * the response will be parse to extract the data needed by the
69
	 * WMS client</p>
70
	 * @param override, if true the previous downloaded data will be overridden
71
	 */
72
    public void getCapabilities(WMSStatus status, boolean override, ICancellable cancel)
73
    {
74
    	URL request = null;
75
		try
76
		{
77
			request = new URL(buildCapabilitiesRequest(status));
78
		}
79
		catch(Exception e)
80
		{
81
			e.printStackTrace();
82
		}
83
		try
84
		{
85
			if (override)
86
				Utilities.removeURL(request);
87
			File f = Utilities.downloadFile(request,"wms_capabilities.xml", cancel);
88
			if (f == null)
89
				return;
90
			clear();
91
			parseCapabilities(f);
92
	    } catch(Exception e)
93
		{
94
			//TODO
95
			e.printStackTrace();
96
		}
97
    }
98

  
99
    private void clear() {
100
		layers.clear();
101
		serviceInfo.clear();
102
	}
103

  
104
	/**
105
     * <p>It will send a GetFeatureInfo request to the WMS
106
     * Parsing the response and redirecting the info to the WMS client</p>
107
     * TODO: return a stored file instead a String.
108
     */
109
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount, ICancellable cancel)
110
    {
111
    	StringBuffer output = new StringBuffer();
112
    	String outputFormat = new String();
113
    	String ServiceException = "ServiceExceptionReport";
114
    	StringBuffer sb = new StringBuffer();
115
    	sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
116
		try
117
		{
118
			WMSGetFeatureInfoRequest request = createGetFeatureInfoRequest(status, x, y);
119
			URL url = request.getURL();
120
	    	outputFormat = url.openConnection().getContentType();
121
	    	File f = request.sendRequest();
122
			if (f == null){
123
				return "";
124
			}
125

  
126
			FileReader fReader = new FileReader(f);
127
			char[] buffer = new char[1024*256];
128
			for (int i = fReader.read(buffer); i>0; i = fReader.read(buffer))
129
		    {
130
		    	String str = new String(buffer,0,i);
131
		    	output.append(str);
132
		    }
133
		    if ( (outputFormat == null) || (outputFormat.indexOf("xml") != -1)
134
		    		||output.toString().toLowerCase().startsWith("<?xml")
135
		    		||(outputFormat.indexOf("gml") != -1))
136
		    {
137
		    	int tag;
138
		    	KXmlParser kxmlParser = null;
139
		    	kxmlParser = new KXmlParser();
140
		    	//kxmlParser.setInput(new StringReader(output.toString()));
141
		    	kxmlParser.setInput(new FileReader(f));
142

  
143
		    	tag = kxmlParser.nextTag();
144
		    	if (kxmlParser.getName().compareTo(ServiceException)==0)
145
				{
146
		    		sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
147
		    		return sb.toString();
148
				}
149
				else if (kxmlParser.getName().compareToIgnoreCase("ERROR")==0)
150
				{
151
					return output.toString();
152
				}
153
				else
154
				{
155
					return output.toString();
156
				}
157
	    	}
158
	    	else
159
	    	{  		
160
	    		//Para que funcione con el GetFeatureInfo Viewer generico hay que devolver:
161
	    		 return output.toString();
162
	    	}
163
		}
164
    	catch(XmlPullParserException parserEx)
165
    	{
166
    		if (output.toString().toLowerCase().indexOf("xml") != -1)
167
    		{
168
    			return output.toString().trim();
169
    		}
170
    		else
171
    		{
172
    	   		sb.append("<INFO>").append("Info format not supported").append("</INFO>");
173
        		return sb.toString();
174
    		}
175
    	}
176
    	catch(Exception e)
177
    	{
178
    		e.printStackTrace();
179
    		sb.append("<INFO>").append("Info format not supported").append("</INFO>");
180
    		return sb.toString();
181

  
182
    	}
183
    }
184
    /**
185
     * <p>Builds a GetMap request that is sent to the WMS
186
     * the response (image) will be redirect to the
187
     * WMS client</p>
188
     */
189
    public byte[] _getMap(WMSStatus status) throws ServerErrorException, WMSException
190
    {
191
    	try
192
		{
193
			//TODO:
194
			//pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
195
			WMSGetMapRequest request = createGetMapRequest(status);
196
			URL url = request.getURL();
197
			
198
			URLConnection conn = url.openConnection();
199
			System.out.println(request.toString());
200
            String type = conn.getContentType();
201

  
202

  
203
	    	byte[] imageBytes = null;
204
	    	byte[] buffer = new byte[1024*256];
205
            InputStream is = conn.getInputStream();
206
	    	int readed = 0;
207

  
208
	    	for (int i = is.read(buffer); i>0; i = is.read(buffer)){
209
                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
210
	    		byte[] buffered = new byte[readed+i];
211
	    		for (int j = 0; j < buffered.length; j++) {
212
	    			if (j<readed){
213
                        // puts the previously downloaded bytes into the image buffer
214
	    				buffered[j] = imageBytes[j];
215
	    			}
216
	    			else {
217
                        // appends the recently downloaded bytes to the image buffer.
218
	    				buffered[j] = buffer[j-readed];
219
	    			}
220
				}
221
	    		imageBytes = (byte[]) buffered.clone();
222
	    		readed += i;
223
	    	}
224

  
225
	    	if ((type !=null && !type.subSequence(0,5).equals("image"))
226
	    		||(Utilities.isTextData(imageBytes)))
227
	    	{
228
               	WMSException wmsEx = null;
229

  
230
            	String exceptionMessage = parseException(imageBytes);
231
                if (exceptionMessage==null)
232
                {
233
                 	String error = new String(imageBytes);
234
                	int pos = error.indexOf("<?xml");
235
                	if (pos!= -1)
236
                	{
237
                		String xml = error.substring(pos,error.length());
238
                		exceptionMessage = parseException(xml.getBytes());
239
                        if (exceptionMessage == null)
240
                        	exceptionMessage = new String(imageBytes);
241
                	}
242
                }
243
             	wmsEx = new WMSException(exceptionMessage);
244
            	wmsEx.setWMSMessage(new String(imageBytes));
245
                throw wmsEx;
246
            }
247
			return imageBytes;
248
		}
249
		catch(IOException e)
250
		{
251
			e.printStackTrace();
252
            throw new ServerErrorException();
253
		}
254
    }
255

  
256
    public File getLegendGraphic(WMSStatus status, String layerName, ICancellable cancel) throws ServerErrorException, WMSException
257
    {
258
    	try
259
		{
260
			WMSGetLegendGraphicRequest request = createGetLegendGraphicRequest(status, layerName);
261
			File f = request.sendRequest();
262
	    	if (f== null)
263
	    		return null;
264
            if (Utilities.isTextFile(f)) {
265
	    		FileInputStream fis = new FileInputStream(f);
266
	    		FileChannel fc = fis.getChannel();
267
	    		byte[] data = new byte[(int)fc.size()];
268
	    		ByteBuffer bb = ByteBuffer.wrap(data);
269
	    		fc.read(bb);
270

  
271
	    		WMSException wmsEx = null;
272

  
273
            	String exceptionMessage = parseException(data);
274
                if (exceptionMessage==null)
275
                {
276
                 	String error = new String(data);
277
                	int pos = error.indexOf("<?xml");
278
                	if (pos!= -1)
279
                	{
280
                		String xml = error.substring(pos,error.length());
281
                		exceptionMessage = parseException(xml.getBytes());
282
                	}
283
                    if (exceptionMessage == null)
284
                    	exceptionMessage = new String(data);
285

  
286
                }
287
             	wmsEx = new WMSException(exceptionMessage);
288
            	wmsEx.setWMSMessage(new String(data));
289
            	Utilities.removeURL(request);
290
                throw wmsEx;
291
            }
292
			return f;
293
		}
294
		catch(IOException e)
295
		{
296
			e.printStackTrace();
297
            throw new ServerErrorException();
298
		}
299
    }
300

  
301
    public File getMap(WMSStatus status, ICancellable cancel) throws ServerErrorException, WMSException
302
    {
303
    	try
304
		{
305
			WMSGetMapRequest request = createGetMapRequest(status);
306
			File f = request.sendRequest();
307
			
308
			if (f== null)
309
	    		return null;
310
            if (Utilities.isTextFile(f)) {
311
	    		FileInputStream fis = new FileInputStream(f);
312
	    		FileChannel fc = fis.getChannel();
313
	    		byte[] data = new byte[(int)fc.size()];   // fc.size returns the size of the file which backs the channel
314
	    		ByteBuffer bb = ByteBuffer.wrap(data);
315
	    		fc.read(bb);
316

  
317
	    		WMSException wmsEx = null;
318

  
319
            	String exceptionMessage = parseException(data);
320
                if (exceptionMessage==null)
321
                {
322
                 	String error = new String(data);
323
                	int pos = error.indexOf("<?xml");
324
                	if (pos!= -1)
325
                	{
326
                		String xml = error.substring(pos,error.length());
327
                		exceptionMessage = parseException(xml.getBytes());
328
//                        if (exceptionMessage == null)
329
//                        	exceptionMessage = new String(data);
330
                	}
331
                    if (exceptionMessage == null)
332
                    	exceptionMessage = new String(data);
333

  
334
                }
335
             	wmsEx = new WMSException(exceptionMessage);
336
            	wmsEx.setWMSMessage(new String(data));
337

  
338
            	// Since it is an error file, It must be deleted from the cache
339
            	Utilities.removeURL(request);
340
                throw wmsEx;
341
            }
342
			return f;
343
		}
344
		catch(IOException e)
345
		{
346
			e.printStackTrace();
347
            throw new ServerErrorException();
348
		}
349
    }
350

  
351

  
352
    /* (non-Javadoc)
353
     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#parseException(byte[])
354
     */
355
    protected String parseException(byte[] data) {
356
        ArrayList errors = new ArrayList();
357
        KXmlParser kxmlParser = new KXmlParser();
358
        try
359
        {
360
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);
361
            kxmlParser.nextTag();
362
            int tag;
363
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
364
            {
365
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);
366
                tag = kxmlParser.nextTag();
367
                 while(tag != KXmlParser.END_DOCUMENT)
368
                 {
369
                     switch(tag)
370
                     {
371
                        case KXmlParser.START_TAG:
372
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
373
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
374
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
375
                                String errorMessage = kxmlParser.nextText();
376
                                errors.add(errorCode+errorMessage);
377
                            }
378
                            break;
379
                        case KXmlParser.END_TAG:
380
                            break;
381

  
382
                     }
383
                     tag = kxmlParser.nextTag();
384
                 }
385
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
386
            }
387
        }
388
        catch(XmlPullParserException parser_ex){
389
            parser_ex.printStackTrace();
390
        }
391
        catch (IOException ioe) {
392
            ioe.printStackTrace();
393
        }
394
        String message = errors.size()>0? "" : null;
395
        for (int i = 0; i < errors.size(); i++) {
396
            message += (String) errors.get(i)+"\n";
397
        }
398
        return message;
399
    }
400
    /**
401
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
402
     * without a VERSION, to get the highest version than a WMS supports.
403
     */
404
    public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version)
405
    {
406
		int index = _host.indexOf('?');
407
		
408
		if (index > -1) {
409
			String host = _host.substring(0, index + 1);
410
			String query = _host.substring(index + 1, _host.length());
411
			
412
			StringTokenizer tokens = new StringTokenizer(query, "&");
413
			String newQuery = "", token;
414

  
415
			// If there is a field or a value with spaces, (and then it's on different tokens) -> unify them
416
			while (tokens.hasMoreTokens()) {
417
				token = tokens.nextToken().trim();
418

  
419
				if (token.toUpperCase().compareTo("REQUEST=GETCAPABILITIES") == 0)
420
					continue;
421

  
422
				if (token.toUpperCase().compareTo("SERVICE=WMS") == 0)
423
					continue;
424

  
425
				if ((_version != null) && (_version.length() > 0)) {
426
    				if (token.toUpperCase().compareTo("VERSION=" + _version) == 0)
427
    					continue;
428
				}
429

  
430
				if (token.toUpperCase().compareTo("EXCEPTIONS=XML") == 0)
431
					continue;
432

  
433
				newQuery += token + "&";
434
			}
435

  
436
        	_host = host + newQuery;
437
		}
438
		else {
439
			_host += "?";
440
		}
441

  
442
    	if ((_version != null) && (_version.compareTo("") != 0))
443
    		_host += "REQUEST=GetCapabilities&SERVICE=WMS&VERSION=" + _version + "&EXCEPTIONS=XML";
444
    	else
445
    		_host += "REQUEST=GetCapabilities&SERVICE=WMS&EXCEPTIONS=XML";
446

  
447
    	return _host;
448
    }
449

  
450
    /**
451
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
452
     * @param WMSStatus
453
     */
454
    private String buildCapabilitiesRequest(WMSStatus status)
455
    {
456
		StringBuffer req = new StringBuffer();
457
		String symbol = null;
458

  
459
		String onlineResource;
460
		if (status == null || status.getOnlineResource() == null)
461
			onlineResource = getHost();
462
		else
463
			onlineResource = status.getOnlineResource();
464
		symbol = getSymbol(onlineResource);
465

  
466
		req.append(onlineResource).append(symbol).append("REQUEST=GetCapabilities&SERVICE=WMS&");
467
		req.append("VERSION=").append(getVersion()).append("&EXCEPTIONS=XML");
468
		return req.toString();
469
    }  
470
   
471
     public void close() {
472
        // your code here
473
    } 
474
     
475
     /**
476
 	 * @param status
477
 	 * The WMS status
478
 	 * @param protocolHandler
479
 	 * The handler to parse the requests
480
 	 * @return an object to send the GetMap requests
481
 	 */
482
 	protected abstract WMSGetMapRequest createGetMapRequest(WMSStatus status);
483
 	
484
 	protected abstract WMSGetFeatureInfoRequest createGetFeatureInfoRequest(WMSStatus status, int x, int y);
485
 	
486
 	protected abstract WMSGetLegendGraphicRequest createGetLegendGraphicRequest(WMSStatus status, String layerName);
487

  
488
 	
489
 	/**
490
     * <p>Parses the Request tag </p>
491
     */ 
492
    protected void parseRequestTag(KXmlParser parser) throws IOException, XmlPullParserException
493
    {	
494
    	int currentTag;
495
    	boolean end = false;
496
    	
497
    	parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.REQUEST);
498
    	currentTag = parser.next();
499
    	
500
    	while (!end) 
501
    	{
502
			 switch(currentTag)
503
			 {
504
				case KXmlParser.START_TAG:
505
					if (parser.getName().compareTo(CapabilitiesTags.GETCAPABILITIES)==0)
506
					{
507
						parserDcpType(parser, CapabilitiesTags.GETCAPABILITIES);
508
					}	
509
					else if (parser.getName().compareTo(CapabilitiesTags.GETMAP)==0)
510
					{	
511
						parseGetMapTag(parser);						
512
					}
513
					else if (parser.getName().compareTo(CapabilitiesTags.GETFEATUREINFO)==0)
514
					{
515
						parseGetFeatureInfoTag(parser);
516
					}		
517
					else if (parser.getName().compareTo(CapabilitiesTags.DESCRIBELAYER)==0)
518
					{
519
						parserDcpType(parser, CapabilitiesTags.DESCRIBELAYER);
520
					}	
521
					else if (parser.getName().compareTo(CapabilitiesTags.GETLEGENDGRAPHIC)==0)
522
					{
523
						parseGetLegendGraphicTag(parser);
524
					}					
525
					break;
526
				case KXmlParser.END_TAG:
527
					if (parser.getName().compareTo(CapabilitiesTags.REQUEST) == 0)
528
						end = true;
529
					break;
530
				case KXmlParser.TEXT:					
531
				break;
532
			 }
533
			 if(!end)
534
				 currentTag = parser.next();
535
    	}
536
    	// TODO: does not get such a tag when arrives here!!!!!!
537
    	//parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.REQUEST);    	
538
    }   
539
 	 /**
540
     * <p>Parses the GetMap tag </p>
541
     */ 
542
    protected void parseGetMapTag(KXmlParser parser) throws IOException, XmlPullParserException
543
    {	
544
    	int currentTag;
545
    	boolean end = false;
546
    	
547
    	parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETMAP);
548
    	currentTag = parser.next();
549
    	
550
    	while (!end) 
551
    	{
552
			 switch(currentTag)
553
			 {
554
				case KXmlParser.START_TAG:
555
					if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
556
					{
557
						serviceInfo.formats.add(parser.nextText());
558
					}	
559
					else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
560
					{		
561
						parserDcpType(parser, CapabilitiesTags.GETMAP);						
562
					}			
563
					break;
564
				case KXmlParser.END_TAG:
565
					if (parser.getName().compareTo(CapabilitiesTags.GETMAP) == 0)
566
						end = true;
567
					break;
568
				case KXmlParser.TEXT:					
569
				break;
570
			 }
571
			 if(!end)
572
				 currentTag = parser.next();
573
    	}	
574
    }    
575
    
576
    /**
577
     * <p>Parses the GetFeatureInfo tag </p>
578
     */ 
579
    protected void parseGetFeatureInfoTag(KXmlParser parser) throws IOException, XmlPullParserException
580
    {	
581
    	int currentTag;
582
    	boolean end = false;
583
    	
584
    	parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETFEATUREINFO);
585
    	currentTag = parser.next();
586
    	
587
    	while (!end) 
588
    	{
589
			 switch(currentTag)
590
			 {
591
				case KXmlParser.START_TAG:
592
					if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
593
					{
594
						//TODO:
595
						// add the supported formats by the GetFeatureInfo request
596
						//serviceInfo.formats.add(parser.nextText());
597
					}	
598
					else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
599
					{			
600
						parserDcpType(parser, CapabilitiesTags.GETFEATUREINFO);		
601
					}			
602
					break;
603
				case KXmlParser.END_TAG:
604
					if (parser.getName().compareTo(CapabilitiesTags.GETFEATUREINFO) == 0)
605
						end = true;
606
					break;
607
				case KXmlParser.TEXT:					
608
				break;
609
			 }
610
			 if(!end)
611
				 currentTag = parser.next();
612
    	}	
613
    }     
614
 
615
    /**
616
     * <p>Parses the GetLegendGraphic tag </p>
617
     */ 
618
    protected void parseGetLegendGraphicTag(KXmlParser parser) throws IOException, XmlPullParserException
619
    {	
620
    	int currentTag;
621
    	boolean end = false;
622
    	
623
    	parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETLEGENDGRAPHIC);
624
    	currentTag = parser.next();
625
    	
626
    	while (!end) 
627
    	{
628
			 switch(currentTag)
629
			 {
630
				case KXmlParser.START_TAG:
631
					if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
632
					{
633
						//TODO:
634
						// add the supported formats by the GetLegendGraphic request
635
						//serviceInfo.formats.add(parser.nextText());
636
					}	
637
					else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
638
					{			
639
						parserDcpType(parser, CapabilitiesTags.GETLEGENDGRAPHIC);		
640
					}			
641
					break;
642
				case KXmlParser.END_TAG:
643
					if (parser.getName().compareTo(CapabilitiesTags.GETLEGENDGRAPHIC) == 0)
644
						end = true;
645
					break;
646
				case KXmlParser.TEXT:					
647
				break;
648
			 }
649
			 if(!end)
650
				 currentTag = parser.next();
651
    	}	
652
    }
653
 }
0 654

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSOperation.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

  
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 Iver T.I.  {{Task}}
26
 */
27

  
28
package org.gvsig.remoteclient.wms;
29

  
30
import java.util.Hashtable;
31

  
32
import org.gvsig.remoteclient.ogc.OGCClientOperation;
33
import org.gvsig.remoteclient.utils.CapabilitiesTags;
34

  
35
/**
36
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
37
 */
38
public class WMSOperation extends OGCClientOperation{ 
39
	protected static Hashtable operations = new Hashtable();
40

  
41
	static{
42
		operations.put(CapabilitiesTags.GETCAPABILITIES, new WMSOperation(CapabilitiesTags.GETCAPABILITIES));
43
		operations.put(CapabilitiesTags.GETFEATUREINFO, new WMSOperation(CapabilitiesTags.GETFEATUREINFO));
44
		operations.put(CapabilitiesTags.GETLEGENDGRAPHIC, new WMSOperation(CapabilitiesTags.GETLEGENDGRAPHIC));
45
		operations.put(CapabilitiesTags.GETMAP, new WMSOperation(CapabilitiesTags.GETMAP));
46
		operations.put(CapabilitiesTags.DESCRIBELAYER, new WMSOperation(CapabilitiesTags.DESCRIBELAYER));
47
	}
48
	
49
	public WMSOperation(String operationName) {
50
		super(operationName);		
51
	}
52

  
53
	public WMSOperation(String operationName, String onlineResource) {
54
		super(operationName, onlineResource);		
55
	}
56
	
57
	/*
58
	 * (non-Javadoc)
59
	 * @see org.gvsig.remoteClient.OGCClientOperation#getOperations()
60
	 */
61
	public Hashtable getOperations() {
62
		return operations;
63
	}
64
}
65

  
0 66

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSStyle.java
1

  
2
package org.gvsig.remoteclient.wms;
3

  
4
import java.io.IOException;
5

  
6
import org.gvsig.remoteclient.utils.CapabilitiesTags;
7
import org.kxml2.io.KXmlParser;
8
import org.xmlpull.v1.XmlPullParserException;
9

  
10
/**
11
 * <p>Defines a OGC style. Theme that describes the appeareance of certain layer.</p>
12
 *
13
 */
14
public abstract class WMSStyle {
15

  
16
	//style name, defined in the WMS capabilities
17
	private String name;
18
	//style title, defined in the WMS capabilities
19
	private String title;
20
	// style abstract, defined in the WMS capabilities
21
    private String styleAbstract;
22

  
23
    private org.gvsig.remoteclient.wms.WMSStyle.LegendURL legendURL;
24

  
25
    /**
26
     * <p>Parses the STYLE tag in the WMS capabilities, filling the WMSStyle object
27
     * loading the data in memory to be easily accesed</p>
28
     *
29
     */
30
    public abstract void parse(KXmlParser parser) throws IOException, XmlPullParserException;
31

  
32
    /**
33
     * Parses the legendURL tag.
34
     * @param parser
35
     * @throws IOException
36
     * @throws XmlPullParserException
37
     */
38
    protected void parseLegendURL(KXmlParser parser) throws IOException, XmlPullParserException
39
    {
40
    	int currentTag;
41
    	boolean end = false;
42

  
43
    	parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.LEGENDURL);
44

  
45
    	String value = new String();
46
    	legendURL = new LegendURL();
47

  
48
    	//First of all set whether the layer is Queryable reading the attribute.
49
    	value = parser.getAttributeValue("", CapabilitiesTags.WIDTH);
50
    	if (value != null)
51
    	{
52
    		legendURL.width = Integer.parseInt( value );
53
    	}
54
    	value = parser.getAttributeValue("", CapabilitiesTags.HEIGHT);
55
    	if (value != null)
56
    	{
57
    		legendURL.height = Integer.parseInt( value );
58
    	}
59
    	currentTag = parser.nextTag();
60

  
61
    	while (!end)
62
    	{
63
    		switch(currentTag)
64
    		{
65
    		case KXmlParser.START_TAG:
66
    			if (parser.getName().compareTo(CapabilitiesTags.FORMAT)==0)
67
    			{
68
    				legendURL.format = parser.nextText();
69
    			}
70
    			else if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
71
    			{
72
    				value = parser.getAttributeValue("", CapabilitiesTags.XLINK_TYPE);
73
    				if (value != null)
74
    					legendURL.onlineResource_type = value;
75
    				value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
76
    				if (value != null)
77
    					legendURL.onlineResource_href = value;
78
    			}
79
    			break;
80
    		case KXmlParser.END_TAG:
81
    			if (parser.getName().compareTo(CapabilitiesTags.LEGENDURL) == 0)
82
    				end = true;
83
    			break;
84
    		case KXmlParser.TEXT:
85
    			break;
86
    		}
87
    		if (!end)
88
    		{
89
    			currentTag = parser.next();
90
    		}
91
    	}
92
    	parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.LEGENDURL);
93
    }
94

  
95
    /**
96
     * gets the LegendURL OnlineResource type
97
     */
98
    public String getLegendURLOnlineResourceType()
99
    {
100
    	if (legendURL != null)
101
    	{
102
    		return legendURL.onlineResource_type;
103
    	}
104
    	else
105
    	{
106
    		return null;
107
    	}
108
    }
109

  
110
    /**
111
     * gets the LegendURL OnlineResource href
112
     */
113
    public String getLegendURLOnlineResourceHRef()
114
    {
115
    	if (legendURL != null)
116
    	{
117
    		return legendURL.onlineResource_href;
118
    	}
119
    	else
120
    	{
121
    		return null;
122
    	}
123
    }
124
    public String getLegendURLFormat()
125
    {
126
    	if (legendURL != null)
127
    	{
128
    		return legendURL.format;
129
    	}
130
    	else
131
    	{
132
    		return null;
133
    	}
134
    }
135
    public int getLegendURLWidth()
136
    {
137
    	if (legendURL != null)
138
    	{
139
    		return legendURL.width;
140
    	}
141
    	return 0;
142
    }
143
    public int getLegendURLHeight()
144
    {
145
    	if (legendURL != null)
146
    	{
147
    		return legendURL.height;
148
    	}
149
    	return 0;
150
    }
151

  
152
    /**
153
     * sets LegendURL
154
     */
155
    protected void setLegendURL(LegendURL legendURL)
156
    {
157
    	this.legendURL = legendURL;
158
    }
159

  
160
    /**
161
     * <p>gets the style name</p>
162
     *
163
     * @return style name
164
     */
165
    public String getName() {
166
    	return name;
167
    }
168

  
169
    /**
170
     * <p>sets the style name.</p>
171
     *
172
     * @param _name
173
     */
174
    public void setName(String _name) {
175
    	name = _name;
176
    }
177

  
178
    /**
179
     * <p>gets the style title</p>
180
     *
181
     *
182
     * @return style title
183
     */
184
    public String getTitle() {
185
    	return title;
186
    }
187

  
188
    /**
189
     * <p>Sets style title</p>
190
     *
191
     *
192
     * @param _title
193
     */
194
    public void setTitle(String _title) {
195
    	title = _title.trim();
196
    }
197

  
198
    /**
199
     * <p>gets style abstract</p>
200
     *
201
     *
202
     * @return style abstract
203
     */
204
    public String getAbstract() {
205
    	return styleAbstract;
206
    }
207

  
208
    /**
209
     * <p>sets style abstract</p>
210
     *
211
     *
212
     * @param _abstract, style abstract
213
     */
214
    public void setAbstract(String _abstract) {
215
    	styleAbstract = _abstract;
216
    }
217

  
218
    /**
219
     * <p>Inner class describing the Legend URL defined for styles in the OGC specifications in WMS</p>
220
     *
221
     */
222
    protected class LegendURL
223
    {
224
    	public LegendURL()
225
    	{
226
    		width = 0;
227
    		height= 0;
228
    		format = new String();
229
    		onlineResource_type = new String();
230
    		onlineResource_href = new String();
231
    	}
232

  
233
    	public int width;
234
    	public int height;
235
    	public String format;
236
    	public String onlineResource_type;
237
    	public String onlineResource_href;
238
    }
239
}
0 240

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSServiceInformation.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 Iver T.I.  {{Task}}
26
*/
27
 
28
package org.gvsig.remoteclient.wms;
29

  
30
import java.util.Vector;
31

  
32
import org.gvsig.remoteclient.ogc.OGCClientOperation;
33
import org.gvsig.remoteclient.ogc.OGCServiceInformation;
34
import org.gvsig.remoteclient.utils.CapabilitiesTags;
35

  
36
/**
37
 * Class that represents the description of the WMS metadata.
38
 * The first part of the capabilities will return the service information
39
 * from the WMS, this class will hold this information.
40
 * 
41
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
42
 */
43
public class WMSServiceInformation extends OGCServiceInformation{
44
	/*public String map_online_resource = null;
45
    public String feature_online_resource = null;*/
46
    public String version;
47
    public String name;
48
    public String scope;
49
    public String title;
50
    public String abstr;
51
    public String keywords;
52
    public String fees;
53
    public String operationsInfo;
54
    public String personname;
55
    public String organization;
56
    public String function;
57
    public String addresstype;
58
    public String address;
59
    public String place;
60
    public String province;
61
    public String postcode;
62
    public String country;
63
    public String phone;
64
    public String fax;
65
    public String email;
66
    public Vector formats;
67

  
68
    public WMSServiceInformation()
69
    {
70
        version = new String();
71
        name = new String();
72
        scope = new String();
73
        title = new String();
74
        abstr = new String();
75
        keywords = new String();
76
        fees = new String();
77
        operationsInfo = new String();
78
        personname = new String();
79
        organization = new String();
80
        function = new String();
81
        addresstype = new String();
82
        address = new String();
83
        place = new String();
84
        province = new String();
85
        postcode = new String();
86
        country = new String();
87
        phone = new String();
88
        fax = new String();
89
        email = new String();
90
        formats = new Vector();       
91
    }
92
    
93
    public boolean isQueryable()
94
    {
95
    	if (getOnlineResource(CapabilitiesTags.GETFEATUREINFO) != null)    	
96
    		return true;
97
    	else
98
    		return false;
99
    }
100
    
101
    public boolean hasLegendGraphic()
102
    {
103
    	if (getOnlineResource(CapabilitiesTags.GETLEGENDGRAPHIC) != null) 
104
    		return true;
105
    	else
106
    		return false;
107
    }
108
    
109
    public void clear() {
110
    	version = new String();
111
        name = new String();
112
        scope = new String();
113
        title = new String();
114
        abstr = new String();
115
        keywords = new String();
116
        fees = new String();
117
        operationsInfo = new String();
118
        personname = new String();
119
        organization = new String();
120
        function = new String();
121
        addresstype = new String();
122
        address = new String();
123
        place = new String();
124
        province = new String();
125
        postcode = new String();
126
        country = new String();
127
        phone = new String();
128
        fax = new String();
129
        email = new String();
130
        formats = new Vector();        
131
    }      
132
    
133
	/* (non-Javadoc)
134
	 * @see org.gvsig.remoteClient.ogc.OGCServiceInformation#createOperation(java.lang.String)
135
	 */	
136
	public OGCClientOperation createOperation(String name) {
137
		return new WMSOperation(name); 
138
	}
139

  
140
	/* (non-Javadoc)
141
	 * @see org.gvsig.remoteClient.ogc.OGCServiceInformation#createOperation(java.lang.String, java.lang.String)
142
	 */	
143
	public OGCClientOperation createOperation(String name, String onlineResource) {
144
		return new WMSOperation(name, onlineResource);
145
	}	
146

  
147
 }
148

  
0 149

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/ICancellable.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

  
42
/* CVS MESSAGES:
43
 *
44
 * $Id$
45
 * $Log$
46
 * Revision 1.1  2006-05-24 16:37:34  jaume
47
 * *** empty log message ***
48
 *
49
 *
50
 */
51
package org.gvsig.remoteclient.wms;
52

  
53
/**
54
 * <p>When a task is accessing to remote data, takes an indeterminate time, and occasionally gets locked. That's
55
 * the reason a task should support to be cancelable.</p>
56
 * <p><code>ICancellable</code> interface is designed for getting information about the cancellation of a
57
 * task of downloading remote information.</p>
58
 */
59
public interface ICancellable {
60
	/**
61
	 * <p>Returns <code>true</code> if a download or a group of downloads tasks has been canceled.</p>
62
	 * 
63
	 * @return <code>true</code> if a download or a group of downloads tasks has been canceled, otherwise <code>false</code>
64
	 */
65
	public boolean isCanceled();
66
	
67
	/**
68
	 * <p>Used to cancel only a group of downloads tasks with the same identifier.</p>
69
	 * 
70
	 * @return the identifier
71
	 */
72
	public Object getID();
73
}
0 74

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSExtent.java
1
package org.gvsig.remoteclient.wms;
2

  
3
import java.io.IOException;
4

  
5
import org.gvsig.remoteclient.utils.CapabilitiesTags;
6
import org.kxml2.io.KXmlParser;
7
import org.xmlpull.v1.XmlPullParserException;
8

  
9
public class WMSExtent {
10
	    
11
    private String name; 
12
    /**
13
     * Indicates that the server will round off inexact dimension values
14
     * to the nearest valid value, or (if it is null or zero) it will not.
15
     */
16
    private String nearestValue; 
17
    /**
18
     * Indicates that temporal data are normally kept current and that the
19
     * request parameter TIME <b>may</b> include the keyword 'current' 
20
     * instead of an ending value. 
21
     */
22
    private String current;
23
    
24
    /**
25
     * cotains the expression for this dimension's extent.
26
     */
27
    private String extentExpression;
28
    private String extDefaultValue;
29

  
30
    public String getName() {        
31
        return name;
32
    } 
33
    
34
    /**
35
     * Tells that the temporal data are normally kept current and that
36
     * the request parameter TIME may include the keyword 'current'
37
     * instead of an ending value.
38
     *
39
     * @return <b>true</b> if the server does keep the data, <b>false</b> else.
40
     */
41
    public boolean allowsCurrentTime() {
42
        return (current!=null && !current.equals("0"));
43
    }
44
    
45
    /**
46
     * Gets the value that would be used along this dimension if a Web
47
     * request omits a value for the dimension.
48
     * 
49
     * @return Returns the defaultValue.
50
     */
51
    public String getDefaultValue() {
52
        return extDefaultValue;
53
    }
54
    
55
    /**
56
     * Returns the extent expression as it was written in the Capabilities 
57
     * document.
58
     * @return String
59
     */
60
    public String getExtentExpression() {
61
        return extentExpression;
62
    }
63
       
64

  
65
    /**
66
     * @return Returns the nearestValues.
67
     */
68
    public boolean allowsNearestValue() {
69
        return (nearestValue!=null && !nearestValue.equals("0"));
70
    }	 
71

  
72
	   /**
73
	 * Parses the EXTENT tag in the WMS capabilities, filling the Extend fills of the
74
	 * WMSDimension object and loading the data into memory to be easily accesed.
75
	 */
76
	public void parse(KXmlParser parser) throws IOException, XmlPullParserException{
77
	    parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.EXTENT);
78
	    name			 = parser.getAttributeValue("", CapabilitiesTags.DIMENSION_NAME);
79
	    extDefaultValue  = parser.getAttributeValue("", CapabilitiesTags.DEFAULT);
80
	    nearestValue    = parser.getAttributeValue("", CapabilitiesTags.EXTENT_NEAREST_VALUE);
81
	    current          = parser.getAttributeValue("", CapabilitiesTags.EXTENT_CURRENT);
82
	    extentExpression = parser.nextText();
83
	}	
84
}
0 85

  
branches/v2_0_0_prep/libraries/libRemoteServices/src/org/gvsig/remoteclient/wms/WMSLayer.java
1
package org.gvsig.remoteclient.wms;
2

  
3
import java.io.IOException;
4
import java.util.ArrayList;
5
import java.util.Hashtable;
6
import java.util.TreeMap;
7
import java.util.Vector;
8

  
9
import org.gvsig.remoteclient.utils.BoundaryBox;
10
import org.gvsig.remoteclient.utils.CapabilitiesTags;
11
import org.kxml2.io.KXmlParser;
12
import org.xmlpull.v1.XmlPullParserException;
13

  
14
/**
15
 * <p>Abstract class that defines an WMSLayer.</p>
16
 *
17
 */
18
public abstract class WMSLayer implements org.gvsig.remoteclient.ILayer {
19

  
20
    protected ArrayList children;
21
    protected WMSLayer parent;
22

  
23
    /**
24
     * <p>Layer Abstract field in the capabilities document </p>
25
     */
26
    private String layerAbstract;
27

  
28
    /**
29
     * <p>Themes provided by the WMS for the layer</p>
30
     */
31
    public ArrayList styles = new ArrayList();
32

  
33
    /**
34
     * <p>Layer name</p>
35
     */
36
    private String name;
37

  
38
    /**
39
     * <p>Layer title</p>
40
     */
41
    private String title;
42

  
43
    private ArrayList keywordList = new ArrayList();
44
    /**
45
     * <p>Layer srs.</p>
46
     */
47
    protected Vector srs = new Vector();
48

  
49
    /**
50
     * <p>extents for each srs the layer can be reproyected to</p>
51
     */
52
    private Hashtable bBoxes  = new Hashtable();
53

  
54
    /**
55
     * <p>extents that defines the bbox for the LatLon projection
56
     * It can be included in the bBoxes vector as well, because it is the most used, we keep it separeted too, according
57
     *  with the OGC WMSCapabilities specifications...
58
     */
59
    private org.gvsig.remoteclient.utils.BoundaryBox latLonBbox;
60

  
61
    /**
62
     * <p>min scale for the layer to be visible</p>
63
     */
64
    private double scaleMin;
65

  
66
    /**
67
     * <p>max scale for the layer to be visible</p>
68
     */
69
    private double scaleMax;
70

  
71
    /**
72
     * <p>Dimensions defined for the layer in the capabilities doc</p>
73
     */
74
    protected java.util.ArrayList dimensions = new ArrayList();
75

  
76
    /**
77
     * Tells if this layer accepts getFeatureInfo requests.
78
     */
79
    private boolean queryable = false;
80

  
81
    /**
82
     * Tells if this layer is opaque.
83
     */
84
    private boolean opaque = false;
85
    /**
86
     * when set to true, noSubsets indicates that the server is not able to make a map
87
     * of a geographic area other than the layer's bounding box.
88
     */
89
    private boolean m_noSubSets = false;
90

  
91
    /**
92
     * when present and non-zero fixedWidth and fixedHeight indicate that the server is not
93
     * able to produce a map of the layer at a width and height different from the fixed sizes indicated.
94
     */
95
    private int fixedWidth = 0;
96
    private int fixedHeight = 0;
97

  
98
    /**
99
     * Tells if this layer can be served with transparency.
100
     */
101
    private boolean transparency;
102

  
103
    /**
104
     * <p>Parses the LAYER tag in the WMS capabilities, filling the WMSLayer object
105
     * loading the data in memory to be easily accesed</p>
106
     *
107
     */
108
    public abstract void parse(KXmlParser parser, TreeMap layerTreeMap)
109
    throws IOException, XmlPullParserException;
110

  
111
    //public abstract ArrayList getAllDimensions();
112

  
113
    /**
114
     * add a new keyword to the keywordList.
115
     * @param key
116
     */
117
    protected void addkeyword(String key)
118
    {
119
    	keywordList.add(key);
120
    }
121
    public ArrayList getKeywords()
122
    {
123
    	return keywordList;
124
    }
125
    /**
126
     * <p>Adds a style to the styles vector</p>
127
     * @param _style
128
     */
129
    public void addStyle(org.gvsig.remoteclient.wms.WMSStyle _style) {
130
        styles.add( _style );    }
131

  
132
   /**
133
     * <p>Gets the style vector</p>
134
     * @return
135
     */
136
    public ArrayList getStyles() {
137
    	ArrayList list = new ArrayList();
138
    	if (styles != null)
139
    		list.addAll(styles);
140
    	if (this.getParent()!= null)
141
    	{
142
    		//return getAllStyles(this);
143
    		if(this.getParent().getStyles() != null)
144
    			list.addAll(this.getParent().getStyles());
145
    	}
146
        return list;
147
    }
148

  
149
    public ArrayList getAllStyles(WMSLayer layer)
150
    {
151
    	if (layer.getParent()!= null)
152
    	{
153
    		ArrayList list = getAllStyles(layer.getParent());
154
    		for(int i = 0; i < this.styles.size(); i++)
155
    		{
156
    			list.add(styles.get(i));
157
    		}
158
    		return list;
159
    	}
160
    	else
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff