root / branches / Mobile_Compatible_Hito_1 / libFMap / src / es / prodevelop / gvsig / mobile / fmap / driver / raster / wms / WMSProtocolHandler.java @ 21606
History | View | Annotate | Download (24 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2006 Prodevelop 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 |
* http://www.gvsig.gva.es
|
30 |
*
|
31 |
* or
|
32 |
*
|
33 |
* Prodevelop Integraci?n de Tecnolog?as SL
|
34 |
* Conde Salvatierra de ?lava , 34-10
|
35 |
* 46004 Valencia
|
36 |
* Spain
|
37 |
*
|
38 |
* +34 963 510 612
|
39 |
* +34 963 510 968
|
40 |
* gis@prodevelop.es
|
41 |
* http://www.prodevelop.es
|
42 |
*
|
43 |
* or
|
44 |
*
|
45 |
* Instituto de Rob?tica
|
46 |
* Apartado de correos 2085
|
47 |
* 46071 Valencia
|
48 |
* (Spain)
|
49 |
*
|
50 |
* +34 963 543 577
|
51 |
* jjordan@robotica.uv.es
|
52 |
* http://robotica.uv.es
|
53 |
*
|
54 |
*/
|
55 |
|
56 |
package es.prodevelop.gvsig.mobile.fmap.driver.raster.wms; |
57 |
|
58 |
import java.awt.geom.Rectangle2D; |
59 |
import java.io.ByteArrayInputStream; |
60 |
import java.io.File; |
61 |
import java.io.FileInputStream; |
62 |
import java.io.FileReader; |
63 |
import java.io.IOException; |
64 |
import java.io.StringReader; |
65 |
import java.net.URL; |
66 |
import java.util.ArrayList; |
67 |
|
68 |
import org.apache.log4j.Logger; |
69 |
import org.kxml2.io.KXmlParser; |
70 |
import org.xmlpull.v1.XmlPullParserException; |
71 |
|
72 |
import es.prodevelop.gvsig.mobile.fmap.util.download.DownloadTask; |
73 |
import es.prodevelop.gvsig.mobile.fmap.util.download.Downloader; |
74 |
import es.prodevelop.gvsig.mobile.fmap.util.string.StringUtilities; |
75 |
|
76 |
/**
|
77 |
*
|
78 |
* This is the class that interacts with the WMS drivers. Sends requests
|
79 |
* (capabilities, images, etc) and
|
80 |
* starts the parsing process. It also instantiates the root of the layer descriptions
|
81 |
* tree, and provides a getter used by the WMS dialog to show the results.
|
82 |
*
|
83 |
* @see es.prodevelop.gvsig.mobile.fmap.driver.raster.wms.WmsRasterDriver
|
84 |
* @see es.prodevelop.gvsig.mobile.fmap.driver.raster.wms.WMSLayerDescription
|
85 |
*
|
86 |
* @author iver
|
87 |
* @author jldominguez
|
88 |
*
|
89 |
*/
|
90 |
public class WMSProtocolHandler { |
91 |
|
92 |
private static Logger logger = Logger.getLogger(WMSProtocolHandler.class); |
93 |
|
94 |
public static final String DEFAULT_WMS_VERSION = "1.1.1"; |
95 |
private String encoding = "UTF-8"; |
96 |
private String host; |
97 |
// private String port;
|
98 |
private String version = ""; |
99 |
private String symbol = ""; |
100 |
|
101 |
public WMSLayerDescription root;
|
102 |
private boolean infoable = false; |
103 |
private ArrayList formats = new ArrayList(); |
104 |
private ArrayList infoFormats = new ArrayList(); |
105 |
|
106 |
/**
|
107 |
* @return the root of the layer descriptions tree
|
108 |
*/
|
109 |
public WMSLayerDescription getRoot() {
|
110 |
return root;
|
111 |
} |
112 |
|
113 |
/**
|
114 |
* Removes all the objects owned by this object. This is used when the WMS dialog closes,
|
115 |
* in order to prevent memory leaks.
|
116 |
*
|
117 |
*/
|
118 |
public void delete() { |
119 |
|
120 |
if (root != null) root.delete(); |
121 |
formats.clear(); |
122 |
formats = null;
|
123 |
infoFormats.clear(); |
124 |
infoFormats = null;
|
125 |
} |
126 |
|
127 |
/**
|
128 |
* Sets the WMS protocol version (1.1.1, etc)
|
129 |
*
|
130 |
* @param v the WMS protocol version
|
131 |
*/
|
132 |
public void setVersion(String v) { |
133 |
version = v; |
134 |
} |
135 |
|
136 |
/**
|
137 |
* Sets the path separator symbol to use with the current WMS server
|
138 |
* @param s the path separator symbol to use with the current WMS server
|
139 |
*/
|
140 |
public void setSymbol(String s) { |
141 |
symbol = s; |
142 |
} |
143 |
|
144 |
/**
|
145 |
*
|
146 |
* @return the WMS protocol version (1.1.1, etc)
|
147 |
*/
|
148 |
public String getVersion() { |
149 |
return version;
|
150 |
} |
151 |
|
152 |
/**
|
153 |
*
|
154 |
* @return the path separator symbol to use with the current WMS server
|
155 |
*/
|
156 |
public String getSymbol() { |
157 |
return symbol;
|
158 |
} |
159 |
|
160 |
|
161 |
/**
|
162 |
*
|
163 |
* @return an array with the image formats supoprted by the current WMS server
|
164 |
*/
|
165 |
public ArrayList getFormats() { |
166 |
return formats;
|
167 |
} |
168 |
|
169 |
/**
|
170 |
*
|
171 |
* @return an array with the image formats supported by the current WMS server
|
172 |
*/
|
173 |
public ArrayList getInfoFormats() { |
174 |
return infoFormats;
|
175 |
} |
176 |
|
177 |
/**
|
178 |
*
|
179 |
* @return whether the layer described by this object is declared as infoable by
|
180 |
* the server in the getcapabilities response
|
181 |
*/
|
182 |
public boolean isInfoable() { |
183 |
return infoable;
|
184 |
} |
185 |
|
186 |
|
187 |
/**
|
188 |
*
|
189 |
* @return the host url
|
190 |
*/
|
191 |
public String getHost() { |
192 |
return host;
|
193 |
} |
194 |
|
195 |
/**
|
196 |
* Sets the host url
|
197 |
* @param _host the new host url
|
198 |
*/
|
199 |
public void setHost(String _host) { |
200 |
host = _host; |
201 |
} |
202 |
|
203 |
/**
|
204 |
* This method starts the get capabilities request process and parses the result.
|
205 |
*
|
206 |
* @param version the WMS protocol version to be used
|
207 |
* @param sym the path separator symbol to be used when building requests
|
208 |
* @return whether the get capabilities request was completed successfully
|
209 |
*/
|
210 |
public boolean getCapabilities(String version, String sym) { |
211 |
|
212 |
URL request = null; |
213 |
try {
|
214 |
request = new URL(buildCapabilitiesRequest(host, version, sym)); |
215 |
} catch (Exception e) { |
216 |
logger.error("Bad capabilities request URL: " + e.getMessage());
|
217 |
} |
218 |
|
219 |
try {
|
220 |
// File f = Downloader.get(request, "cap");
|
221 |
|
222 |
File f = (File) Downloader.downloadObjectCancel(request, "cap", |
223 |
DownloadTask.FILE, "wms", null, true); |
224 |
|
225 |
if (f == null) { |
226 |
logger.error("capabilities file is null");
|
227 |
return false; |
228 |
} |
229 |
clear(); |
230 |
parse(f); |
231 |
} catch (Exception e) { |
232 |
logger.error("While downloading/parsing WMS capabilities file: "
|
233 |
+ e.getMessage()); |
234 |
return false; |
235 |
} |
236 |
|
237 |
// in case root has no SRS:
|
238 |
avoidEmptySRSInRoot(); |
239 |
|
240 |
return true; |
241 |
} |
242 |
|
243 |
private void avoidEmptySRSInRoot() { |
244 |
|
245 |
if (root == null) |
246 |
return;
|
247 |
if (root.getAvailableSRS().length > 0) |
248 |
return;
|
249 |
|
250 |
logger |
251 |
.debug("Root layer has no SRS array. Those of its first-level children will be added...");
|
252 |
|
253 |
int cnt = root.getChildrenCount();
|
254 |
for (int i = (cnt - 1); i >= 0; i--) { |
255 |
WMSLayerDescription desc = root.getChild(i); |
256 |
String[] ava_srs = desc.getAvailableSRS(); |
257 |
for (int j = 0; j < ava_srs.length; j++) { |
258 |
String item_srs = ava_srs[j];
|
259 |
Rectangle2D ext = desc.getExtentForSRS(item_srs);
|
260 |
root.increaseExtentForSRS(item_srs, ext); |
261 |
} |
262 |
} |
263 |
} |
264 |
|
265 |
private String buildCapabilitiesRequest(String h, String v, String sym) { |
266 |
return h + sym + "REQUEST=GetCapabilities&SERVICE=WMS&VERSION=" + v |
267 |
+ "&EXCEPTIONS=XML";
|
268 |
} |
269 |
|
270 |
private void clear() { |
271 |
infoable = false;
|
272 |
root = new WMSLayerDescription(0, null); |
273 |
formats.clear(); |
274 |
infoFormats.clear(); |
275 |
} |
276 |
|
277 |
protected String parseException(byte[] data) { |
278 |
ArrayList errors = new ArrayList(); |
279 |
KXmlParser kxmlParser = new KXmlParser();
|
280 |
try {
|
281 |
kxmlParser.setInput(new ByteArrayInputStream(data), encoding); |
282 |
kxmlParser.nextTag(); |
283 |
int tag;
|
284 |
if (kxmlParser.getEventType() != KXmlParser.END_DOCUMENT) {
|
285 |
kxmlParser.require(KXmlParser.START_TAG, null,
|
286 |
EXCEPTION_TAGS_EXCEPTION_ROOT); |
287 |
tag = kxmlParser.nextTag(); |
288 |
while (tag != KXmlParser.END_DOCUMENT) {
|
289 |
switch (tag) {
|
290 |
case KXmlParser.START_TAG:
|
291 |
if (kxmlParser.getName().compareTo(
|
292 |
EXCEPTION_TAGS_SERVICE_EXCEPTION) == 0) {
|
293 |
String errorCode = kxmlParser.getAttributeValue("", |
294 |
EXCEPTION_TAGS_CODE); |
295 |
errorCode = (errorCode != null) ? "[" + errorCode |
296 |
+ "] " : ""; |
297 |
String errorMessage = kxmlParser.nextText();
|
298 |
errors.add(errorCode + errorMessage); |
299 |
} |
300 |
break;
|
301 |
case KXmlParser.END_TAG:
|
302 |
break;
|
303 |
|
304 |
} |
305 |
tag = kxmlParser.nextTag(); |
306 |
} |
307 |
//kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
|
308 |
} |
309 |
} catch (XmlPullParserException parser_ex) {
|
310 |
parser_ex.printStackTrace(); |
311 |
} catch (IOException ioe) { |
312 |
ioe.printStackTrace(); |
313 |
} |
314 |
String message = errors.size() > 0 ? "" : null; |
315 |
for (int i = 0; i < errors.size(); i++) { |
316 |
message += (String) errors.get(i) + "\n"; |
317 |
} |
318 |
return message;
|
319 |
} |
320 |
|
321 |
/**
|
322 |
* Closes the protocol handler. Currently empty.
|
323 |
*
|
324 |
*/
|
325 |
public void close() { |
326 |
// your code here
|
327 |
} |
328 |
|
329 |
/**
|
330 |
* Tag used when parsing WMS responses
|
331 |
*/
|
332 |
public final static String EXCEPTION_TAGS_EXCEPTION_ROOT = "ServiceExceptionReport"; |
333 |
/**
|
334 |
* Tag used when parsing WMS responses
|
335 |
*/
|
336 |
public final static String EXCEPTION_TAGS_SERVICE_EXCEPTION = "ServiceException"; |
337 |
/**
|
338 |
* Tag used when parsing WMS responses
|
339 |
*/
|
340 |
public final static String EXCEPTION_TAGS_CODE = "code"; |
341 |
|
342 |
/**
|
343 |
* Main parse method.
|
344 |
*
|
345 |
* @param f file to be parsed
|
346 |
*/
|
347 |
private void parse(File f) { |
348 |
|
349 |
FileReader reader = null; |
350 |
try {
|
351 |
reader = new FileReader(f); |
352 |
|
353 |
// FileInputStream fis = new FileInputStream(f);
|
354 |
// InputStreamReader reader = new InputStreamReader(fis,"ISO-8859-1");
|
355 |
// BufferedReader br = new BufferedReader(reader);
|
356 |
|
357 |
char[] buffer = new char[100]; |
358 |
reader.read(buffer); |
359 |
StringBuffer strBuff = new StringBuffer(); |
360 |
strBuff.append(buffer); |
361 |
String auxStr = strBuff.toString().toLowerCase();
|
362 |
int a = auxStr.toLowerCase().indexOf("<?xml"); |
363 |
if (a != -1) |
364 |
auxStr = auxStr.substring(a, auxStr.length()); |
365 |
|
366 |
StringBuffer st = new StringBuffer(auxStr); |
367 |
String searchText = "encoding=\""; |
368 |
int index = st.indexOf(searchText);
|
369 |
|
370 |
if (index > -1) { |
371 |
st.delete(0, index + searchText.length());
|
372 |
encoding = st.substring(0, st.indexOf("\"")); |
373 |
} |
374 |
|
375 |
reader.close(); |
376 |
|
377 |
} catch (Exception ex) { |
378 |
logger.error("In main parse method: " + ex.getMessage());
|
379 |
} |
380 |
|
381 |
int tag;
|
382 |
KXmlParser kxmlParser = null;
|
383 |
kxmlParser = new KXmlParser();
|
384 |
try {
|
385 |
// reader = new FileReader(f);
|
386 |
// // FileInputStream fis = new FileInputStream(f);
|
387 |
// // InputStreamReader reader = new InputStreamReader(fis,"ISO-8859-1");
|
388 |
// // BufferedReader br = new BufferedReader(reader);
|
389 |
// // patch for ArcIMS + WMS connector > 9.0 bug
|
390 |
//
|
391 |
// char[] buffer = new char[(int) f.length()];
|
392 |
//
|
393 |
// logger.debug("PHONEME - buffer.len = " + buffer.length);
|
394 |
//
|
395 |
// reader.read(buffer);
|
396 |
//
|
397 |
// StringBuffer strBuff = new StringBuffer();
|
398 |
// strBuff.append(buffer);
|
399 |
// String auxStr = strBuff.toString();
|
400 |
//
|
401 |
// logger.debug("PHONEME - auxStr = " + auxStr);
|
402 |
// // String string = new String(buffer);
|
403 |
//
|
404 |
// int a = auxStr.toLowerCase().indexOf("<?xml");
|
405 |
//
|
406 |
// logger.debug("PHONEME - a = " + a);
|
407 |
//
|
408 |
// if (a != -1) {
|
409 |
// auxStr = auxStr.substring(a, auxStr.length());
|
410 |
// logger.debug("PHONEME - auxStr = " + auxStr);
|
411 |
// kxmlParser.setInput(new StringReader(auxStr));
|
412 |
// } else
|
413 |
// // end patch
|
414 |
// kxmlParser.setInput(new FileInputStream(f), encoding);
|
415 |
|
416 |
|
417 |
FileInputStream fir = new FileInputStream(f); |
418 |
kxmlParser.setInput(fir, encoding); |
419 |
|
420 |
|
421 |
logger.debug("PHONEME - kxmlParser.nextTag();");
|
422 |
|
423 |
kxmlParser.nextTag(); |
424 |
if (kxmlParser.getEventType() != KXmlParser.END_DOCUMENT) {
|
425 |
kxmlParser.require(KXmlParser.START_TAG, null,
|
426 |
CapabilitiesTags.CAPABILITIES_ROOT1_1_1); |
427 |
tag = kxmlParser.nextTag(); |
428 |
while (tag != KXmlParser.END_DOCUMENT) {
|
429 |
switch (tag) {
|
430 |
|
431 |
case KXmlParser.START_TAG:
|
432 |
if (kxmlParser.getName().compareTo(
|
433 |
CapabilitiesTags.SERVICE) == 0) {
|
434 |
// parseServiceTag(kxmlParser);
|
435 |
} else if (kxmlParser.getName().compareTo( |
436 |
CapabilitiesTags.CAPABILITY) == 0) {
|
437 |
parseCapabilityTag(kxmlParser); |
438 |
} |
439 |
break;
|
440 |
case KXmlParser.END_TAG:
|
441 |
break;
|
442 |
case KXmlParser.TEXT:
|
443 |
break;
|
444 |
} |
445 |
tag = kxmlParser.next(); |
446 |
} |
447 |
kxmlParser.require(KXmlParser.END_DOCUMENT, null, null); |
448 |
fir.close(); |
449 |
} |
450 |
} catch (XmlPullParserException parser_ex) {
|
451 |
logger.error("Parser exception: " + parser_ex.getMessage());
|
452 |
} catch (IOException ioe) { |
453 |
logger.error("IO exception: " + ioe.getMessage());
|
454 |
} finally {
|
455 |
|
456 |
} |
457 |
// In the parsing process the layer has been filled
|
458 |
} |
459 |
|
460 |
/**
|
461 |
* <p>Parses the Service Information </p>
|
462 |
*/
|
463 |
|
464 |
/*
|
465 |
private void parseServiceTag(KXmlParser parser) throws IOException, XmlPullParserException
|
466 |
{
|
467 |
int currentTag;
|
468 |
boolean end = false;
|
469 |
|
470 |
parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.SERVICE);
|
471 |
currentTag = parser.next();
|
472 |
|
473 |
while (!end)
|
474 |
{
|
475 |
switch(currentTag)
|
476 |
{
|
477 |
case KXmlParser.START_TAG:
|
478 |
if (parser.getName().compareTo(CapabilitiesTags.NAME)==0)
|
479 |
{
|
480 |
serviceInfo.name = parser.nextText();
|
481 |
}
|
482 |
else if (parser.getName().compareTo(CapabilitiesTags.TITLE)==0)
|
483 |
{
|
484 |
serviceInfo.title = parser.nextText();
|
485 |
}
|
486 |
else if (parser.getName().compareTo(CapabilitiesTags.ABSTRACT)==0)
|
487 |
{
|
488 |
serviceInfo.abstr = parser.nextText();
|
489 |
}
|
490 |
else if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
|
491 |
{
|
492 |
String value = new String();
|
493 |
value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
|
494 |
if (value != null){
|
495 |
serviceInfo.online_resource = value;
|
496 |
}
|
497 |
}
|
498 |
else if ((parser.getName().compareTo(CapabilitiesTags.KEYWORDLIST)==0) ||
|
499 |
(parser.getName().compareTo(CapabilitiesTags.CONTACTINFORMATION)==0))
|
500 |
{
|
501 |
parser.skipSubTree();
|
502 |
}
|
503 |
break;
|
504 |
case KXmlParser.END_TAG:
|
505 |
if (parser.getName().compareTo(CapabilitiesTags.SERVICE) == 0)
|
506 |
end = true;
|
507 |
break;
|
508 |
case KXmlParser.TEXT:
|
509 |
break;
|
510 |
}
|
511 |
if (!end)
|
512 |
currentTag = parser.next();
|
513 |
}
|
514 |
parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.SERVICE);
|
515 |
}
|
516 |
*/
|
517 |
|
518 |
/**
|
519 |
* <p>Parses the Capability Tag </p>
|
520 |
*/
|
521 |
private void parseCapabilityTag(KXmlParser parser) throws IOException, |
522 |
XmlPullParserException { |
523 |
int currentTag;
|
524 |
boolean end = false; |
525 |
|
526 |
parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.CAPABILITY);
|
527 |
currentTag = parser.next(); |
528 |
|
529 |
while (!end) {
|
530 |
switch (currentTag) {
|
531 |
case KXmlParser.START_TAG:
|
532 |
if (parser.getName().compareTo(CapabilitiesTags.REQUEST) == 0) { |
533 |
parseRequestTag(parser); |
534 |
} else if (parser.getName().compareTo( |
535 |
CapabilitiesTags.EXCEPTION) == 0) {
|
536 |
//TODO:
|
537 |
//Add to serviceInfo the supported formats for the exceptions????
|
538 |
} else if (parser.getName().compareTo(CapabilitiesTags.LAYER) == 0) { |
539 |
int curr_tag = root.parseAsRoot(parser);
|
540 |
end = ((parser.getName().compareTo( |
541 |
CapabilitiesTags.CAPABILITY) == 0) && (curr_tag == KXmlParser.END_TAG));
|
542 |
} else if ((parser.getName().compareTo( |
543 |
CapabilitiesTags.VENDORSPECIFICCAPABILITIES) == 0)
|
544 |
|| (parser.getName().compareTo( |
545 |
CapabilitiesTags.USERDEFINEDSYMBOLIZATION) == 0)
|
546 |
|| (parser.getName().compareTo(CapabilitiesTags.STYLE) == 0))
|
547 |
|
548 |
{ |
549 |
parser.skipSubTree(); |
550 |
} |
551 |
break;
|
552 |
case KXmlParser.END_TAG:
|
553 |
if (parser.getName().compareTo(CapabilitiesTags.CAPABILITY) == 0) |
554 |
end = true;
|
555 |
break;
|
556 |
case KXmlParser.TEXT:
|
557 |
break;
|
558 |
} |
559 |
if (!end)
|
560 |
currentTag = parser.next(); |
561 |
} |
562 |
//parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.CAPABILITY);
|
563 |
} |
564 |
|
565 |
/**
|
566 |
* <p>Parses the Request tag </p>
|
567 |
*/
|
568 |
private void parseRequestTag(KXmlParser parser) throws IOException, |
569 |
XmlPullParserException { |
570 |
int currentTag;
|
571 |
boolean end = false; |
572 |
|
573 |
parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.REQUEST);
|
574 |
currentTag = parser.next(); |
575 |
|
576 |
while (!end) {
|
577 |
switch (currentTag) {
|
578 |
case KXmlParser.START_TAG:
|
579 |
if (parser.getName().compareTo(CapabilitiesTags.GETMAP) == 0) { |
580 |
parseGetMapTag(parser); |
581 |
} else if (parser.getName().compareTo( |
582 |
CapabilitiesTags.GETFEATUREINFO) == 0) {
|
583 |
infoable = true;
|
584 |
parseGetFeatureInfoTag(parser); |
585 |
} |
586 |
break;
|
587 |
case KXmlParser.END_TAG:
|
588 |
if (parser.getName().compareTo(CapabilitiesTags.REQUEST) == 0) |
589 |
end = true;
|
590 |
break;
|
591 |
case KXmlParser.TEXT:
|
592 |
break;
|
593 |
} |
594 |
if (!end)
|
595 |
currentTag = parser.next(); |
596 |
} |
597 |
// TODO: does not get such a tag when arrives here!!!!!!
|
598 |
//parser.require(KXmlParser.END_TAG, null, CapabilitiesTags.REQUEST);
|
599 |
} |
600 |
|
601 |
/**
|
602 |
* <p>Parses the GetMap tag </p>
|
603 |
*/
|
604 |
private void parseGetMapTag(KXmlParser parser) throws IOException, |
605 |
XmlPullParserException { |
606 |
int currentTag;
|
607 |
boolean end = false; |
608 |
|
609 |
parser.require(KXmlParser.START_TAG, null, CapabilitiesTags.GETMAP);
|
610 |
currentTag = parser.next(); |
611 |
|
612 |
while (!end) {
|
613 |
switch (currentTag) {
|
614 |
case KXmlParser.START_TAG:
|
615 |
if (parser.getName().compareTo(CapabilitiesTags.FORMAT) == 0) { |
616 |
String f = parser.nextText();
|
617 |
if (validFormat(f)) {
|
618 |
formats.add(f); |
619 |
} |
620 |
|
621 |
} |
622 |
/*
|
623 |
else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
|
624 |
{
|
625 |
currentTag = parser.nextTag();
|
626 |
if(parser.getName().compareTo(CapabilitiesTags.HTTP)==0)
|
627 |
{
|
628 |
currentTag = parser.nextTag();
|
629 |
if(parser.getName().compareTo(CapabilitiesTags.GET)==0)
|
630 |
{
|
631 |
currentTag = parser.nextTag();
|
632 |
if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
|
633 |
{
|
634 |
String value = new String();
|
635 |
value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
|
636 |
if (value != null){
|
637 |
serviceInfo.operations.put(CapabilitiesTags.GETMAP, value);
|
638 |
}
|
639 |
}
|
640 |
}
|
641 |
}
|
642 |
}
|
643 |
*/
|
644 |
break;
|
645 |
case KXmlParser.END_TAG:
|
646 |
if (parser.getName().compareTo(CapabilitiesTags.GETMAP) == 0) |
647 |
end = true;
|
648 |
break;
|
649 |
case KXmlParser.TEXT:
|
650 |
break;
|
651 |
} |
652 |
if (!end)
|
653 |
currentTag = parser.next(); |
654 |
} |
655 |
} |
656 |
|
657 |
private boolean validFormat(String f) { |
658 |
|
659 |
String format = f.toLowerCase();
|
660 |
if (format.indexOf("jpg") != -1) |
661 |
return true; |
662 |
if (format.indexOf("jpeg") != -1) |
663 |
return true; |
664 |
if (format.indexOf("gif") != -1) |
665 |
return true; |
666 |
if (format.indexOf("png") != -1) |
667 |
return true; |
668 |
return false; |
669 |
} |
670 |
|
671 |
/**
|
672 |
* <p>Parses the GetFeatureInfoTag tag </p>
|
673 |
*/
|
674 |
|
675 |
private void parseGetFeatureInfoTag(KXmlParser parser) throws IOException, |
676 |
XmlPullParserException { |
677 |
int currentTag;
|
678 |
boolean end = false; |
679 |
|
680 |
parser.require(KXmlParser.START_TAG, null,
|
681 |
CapabilitiesTags.GETFEATUREINFO); |
682 |
currentTag = parser.next(); |
683 |
|
684 |
while (!end) {
|
685 |
switch (currentTag) {
|
686 |
case KXmlParser.START_TAG:
|
687 |
if (parser.getName().compareTo(CapabilitiesTags.FORMAT) == 0) { |
688 |
//TODO:
|
689 |
// add the supported formats by the GetFeatureInfo request
|
690 |
infoFormats.add(parser.nextText()); |
691 |
//serviceInfo.formats.add(parser.nextText());
|
692 |
} |
693 |
/*
|
694 |
else if (parser.getName().compareTo(CapabilitiesTags.DCPTYPE)==0)
|
695 |
{
|
696 |
currentTag = parser.nextTag();
|
697 |
if(parser.getName().compareTo(CapabilitiesTags.HTTP)==0)
|
698 |
{
|
699 |
currentTag = parser.nextTag();
|
700 |
if(parser.getName().compareTo(CapabilitiesTags.GET)==0)
|
701 |
{
|
702 |
currentTag = parser.nextTag();
|
703 |
if (parser.getName().compareTo(CapabilitiesTags.ONLINERESOURCE)==0)
|
704 |
{
|
705 |
String value = new String();
|
706 |
value = parser.getAttributeValue("", CapabilitiesTags.XLINK_HREF);
|
707 |
if (value != null){
|
708 |
serviceInfo.operations.put(CapabilitiesTags.GETFEATUREINFO, value);
|
709 |
}
|
710 |
}
|
711 |
}
|
712 |
}
|
713 |
}
|
714 |
*/
|
715 |
break;
|
716 |
case KXmlParser.END_TAG:
|
717 |
if (parser.getName().compareTo(CapabilitiesTags.GETFEATUREINFO) == 0) |
718 |
end = true;
|
719 |
break;
|
720 |
case KXmlParser.TEXT:
|
721 |
break;
|
722 |
} |
723 |
if (!end)
|
724 |
currentTag = parser.next(); |
725 |
} |
726 |
} |
727 |
|
728 |
/**
|
729 |
* Utility method to find out the convenient path separator symbol for a given url string.
|
730 |
* @param url the URL of interest
|
731 |
* @return the convenient path separator symbol
|
732 |
*/
|
733 |
public static String getSymbol(String url) { |
734 |
|
735 |
String symbol;
|
736 |
|
737 |
if (url.indexOf("?") == -1) |
738 |
symbol = "?";
|
739 |
else if (url.indexOf("?") != url.length() - 1) |
740 |
symbol = "&";
|
741 |
else
|
742 |
symbol = "";
|
743 |
|
744 |
return symbol;
|
745 |
} |
746 |
|
747 |
private static String getVersionQueryRequest(String _host) { |
748 |
|
749 |
String req = ""; |
750 |
String symbol = getSymbol(_host);
|
751 |
req = req + _host + symbol + "REQUEST=GetCapabilities&SERVICE=WMS&";
|
752 |
req += ("&EXCEPTIONS=XML");
|
753 |
return req;
|
754 |
} |
755 |
|
756 |
/**
|
757 |
* Sends a GetCapabilities to the WMS server to get the version
|
758 |
* if the version parameter is null, the WMS will return the highest version supported
|
759 |
* if not it will return the lower highest version than the one requested.
|
760 |
* @param host host URL
|
761 |
* @return suitable version supported by the server
|
762 |
*/
|
763 |
public static String getSuitableWMSVersion(URL host) |
764 |
throws BadWMSResponseException {
|
765 |
|
766 |
String request = getVersionQueryRequest(host.toString());
|
767 |
String version = ""; |
768 |
|
769 |
byte[] version_bytes = null; |
770 |
|
771 |
try {
|
772 |
|
773 |
URL req_url = new URL(request); |
774 |
|
775 |
version_bytes = (byte[]) Downloader.downloadObjectCancel(req_url, |
776 |
"", DownloadTask.BYTE_ARRAY, "", "", false); |
777 |
|
778 |
} catch (Exception ex) { |
779 |
|
780 |
logger.error("While getting version request response: "
|
781 |
+ ex.getMessage()); |
782 |
throw new BadWMSResponseException(ex.getMessage()); |
783 |
} |
784 |
|
785 |
String response = new String(version_bytes); |
786 |
|
787 |
int a = response.toLowerCase().indexOf("<?xml"); |
788 |
if (a != -1) { |
789 |
response = response.substring(a, response.length()); |
790 |
} |
791 |
|
792 |
StringReader reader = new StringReader(response); |
793 |
KXmlParser kxmlParser = null;
|
794 |
kxmlParser = new KXmlParser();
|
795 |
|
796 |
try {
|
797 |
kxmlParser.setInput(reader); |
798 |
kxmlParser.nextTag(); |
799 |
|
800 |
if (kxmlParser.getEventType() != KXmlParser.END_DOCUMENT) {
|
801 |
if ((kxmlParser.getName().compareTo(
|
802 |
CapabilitiesTags.CAPABILITIES_ROOT1_1_0) == 0)
|
803 |
|| (kxmlParser.getName().compareTo( |
804 |
CapabilitiesTags.CAPABILITIES_ROOT1_1_1) == 0)
|
805 |
|| (kxmlParser.getName().compareTo( |
806 |
CapabilitiesTags.CAPABILITIES_ROOT1_3_0) == 0)) {
|
807 |
version = kxmlParser.getAttributeValue("",
|
808 |
CapabilitiesTags.VERSION); |
809 |
} |
810 |
} |
811 |
// do not forget to close the Stream.
|
812 |
reader.close(); |
813 |
|
814 |
if (version.length() == 0) { |
815 |
throw new BadWMSResponseException("No WMS version found."); |
816 |
} |
817 |
|
818 |
return version;
|
819 |
|
820 |
} catch (Exception ex) { |
821 |
logger.error("While parsing version request response: "
|
822 |
+ ex.getMessage()); |
823 |
throw new BadWMSResponseException(ex.getMessage()); |
824 |
} finally {
|
825 |
if (reader != null) { |
826 |
reader.close(); |
827 |
} |
828 |
} |
829 |
} |
830 |
|
831 |
/**
|
832 |
* This method excludes from a comma separated string of IDs, the ones that are not infoable.
|
833 |
* It is used for querying only on queriable layers, and prevents empty responses on some
|
834 |
* WMS servers.
|
835 |
*
|
836 |
* @param all_csv comma separated string of all layers requested by the user
|
837 |
* @param root the layer description object of the root layer
|
838 |
* @param getname whether we wanrt to get the names or the IDs of the layers
|
839 |
* @return a comma separated string with the IDs or names of the queryable layers
|
840 |
*/
|
841 |
public static String leaveInfoable(String all_csv, |
842 |
WMSLayerDescription root, boolean getname) {
|
843 |
|
844 |
String[] all_array = StringUtilities.split(all_csv, ","); |
845 |
ArrayList resp = new ArrayList(); |
846 |
addRecursiveYourselfIfPresent(root, all_array, resp, getname); |
847 |
|
848 |
String _resp = null; |
849 |
int sz = resp.size();
|
850 |
if (sz > 0) { |
851 |
_resp = "";
|
852 |
for (int i = 0; i < sz; i++) |
853 |
_resp = _resp + "," + ((String) resp.get(i)); |
854 |
_resp = _resp.substring(1);
|
855 |
} |
856 |
return _resp;
|
857 |
|
858 |
} |
859 |
|
860 |
private static void addRecursiveYourselfIfPresent(WMSLayerDescription desc, |
861 |
String[] sel, ArrayList resp, boolean getname) { |
862 |
|
863 |
if (desc.isInfoable() && isOneOf(desc.getLayerId(), sel)) {
|
864 |
if (getname) {
|
865 |
// name
|
866 |
resp.add(desc.getLayerName()); |
867 |
} else {
|
868 |
// id
|
869 |
resp.add(desc.getLayerId()); |
870 |
} |
871 |
|
872 |
} |
873 |
|
874 |
for (int i = 0; i < desc.getChildrenCount(); i++) { |
875 |
addRecursiveYourselfIfPresent(desc.getChild(i), sel, resp, getname); |
876 |
} |
877 |
} |
878 |
|
879 |
|
880 |
|
881 |
private static void addRecursiveYourselfIfPresentNew(WMSLayerDescription desc, |
882 |
String[] sel, ArrayList resp, boolean getname) { |
883 |
|
884 |
if (isOneOf(desc.getLayerId(), sel)) {
|
885 |
|
886 |
if (desc.isInfoable()) {
|
887 |
if (getname) {
|
888 |
resp.add(desc.getLayerName()); // name
|
889 |
} else {
|
890 |
resp.add(desc.getLayerId()); // id
|
891 |
} |
892 |
} |
893 |
addAllInfoableChildren(desc, resp, getname); |
894 |
|
895 |
} else {
|
896 |
|
897 |
// ---------- search children
|
898 |
for (int i = 0; i < desc.getChildrenCount(); i++) { |
899 |
addRecursiveYourselfIfPresentNew(desc.getChild(i), sel, resp, getname); |
900 |
} |
901 |
|
902 |
} |
903 |
|
904 |
} |
905 |
|
906 |
private static void addAllInfoableChildren( |
907 |
WMSLayerDescription desc, |
908 |
ArrayList resp,
|
909 |
boolean getname) {
|
910 |
|
911 |
for (int i = 0; i < desc.getChildrenCount(); i++) { |
912 |
|
913 |
WMSLayerDescription ch = desc.getChild(i); |
914 |
if (ch.isInfoable()) {
|
915 |
if (getname) {
|
916 |
resp.add(ch.getLayerName()); |
917 |
} else {
|
918 |
resp.add(ch.getLayerId()); |
919 |
} |
920 |
} |
921 |
addAllInfoableChildren(ch, resp, getname); |
922 |
} |
923 |
} |
924 |
|
925 |
private static boolean isOneOf(String str, String[] arr) { |
926 |
|
927 |
for (int i = 0; i < arr.length; i++) { |
928 |
if (str.compareTo(arr[i]) == 0) |
929 |
return true; |
930 |
} |
931 |
return false; |
932 |
|
933 |
} |
934 |
|
935 |
} |
936 |
|