2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
7 package gov
.nasa
.worldwind
.wms
;
9 import gov
.nasa
.worldwind
.util
.Logging
;
12 import javax
.xml
.XMLConstants
;
13 import javax
.xml
.xpath
.*;
15 import java
.util
.logging
.Level
;
19 * @version $Id: Capabilities.java 3601 2007-11-21 03:23:23Z tgaskins $
21 public abstract class Capabilities
23 protected Document doc
;
24 protected Element service
;
25 protected Element capability
;
26 protected XPath xpath
;
28 public static Capabilities
parse(Document doc
)
30 XPathFactory xpFactory
= XPathFactory
.newInstance();
31 XPath xpath
= xpFactory
.newXPath();
33 SimpleNamespaceContext nsc
= new SimpleNamespaceContext();
34 nsc
.addNamespace(XMLConstants
.DEFAULT_NS_PREFIX
, "http://www.opengis.net/wms");
35 xpath
.setNamespaceContext(new SimpleNamespaceContext());
39 String version
= xpath
.evaluate(altPaths("*/@wms:version"), doc
);
40 if (version
== null || version
.length() == 0)
43 if (version
.compareTo("1.3") < 0)
44 return new CapabilitiesV111(doc
, xpath
);
46 return new CapabilitiesV130(doc
, xpath
);
48 catch (XPathExpressionException e
)
50 Logging
.logger().log(Level
.SEVERE
, "WMS.ParsingError", e
);
55 protected Capabilities(Document doc
, XPath xpath
)
62 this.service
= (Element
) this.xpath
.evaluate(altPaths("*/wms:Service"), doc
, XPathConstants
.NODE
);
63 if (this.service
== null)
65 Logging
.logger().severe("WMS.NoServiceElement");
66 throw new IllegalArgumentException(Logging
.getMessage("WMS.NoServiceElement"));
69 this.capability
= (Element
) this.xpath
.evaluate(altPaths("*/wms:Capability"), doc
, XPathConstants
.NODE
);
70 if (this.capability
== null)
72 Logging
.logger().severe("WMS.NoCapabilityElement");
73 throw new IllegalArgumentException(Logging
.getMessage("WMS.NoCapabilityElement"));
76 catch (XPathExpressionException e
)
78 Logging
.logger().log(Level
.SEVERE
, "WMS.ParsingError", e
);
82 private static String
altPaths(String path
)
84 return path
!= null ? path
+ "|" + path
.replaceAll("wms:", "") : null;
87 protected String
getText(String path
)
89 return this.getText(null, path
);
92 protected String
getText(Element context
, String path
)
96 return this.xpath
.evaluate(altPaths(path
), context
!= null ? context
: doc
);
98 catch (XPathExpressionException e
)
104 protected String
[] getTextArray(Element context
, String path
)
108 NodeList nodes
= (NodeList
) this.xpath
.evaluate(altPaths(path
), context
!= null ? context
: doc
,
109 XPathConstants
.NODESET
);
110 if (nodes
== null || nodes
.getLength() == 0)
113 String
[] strings
= new String
[nodes
.getLength()];
114 for (int i
= 0; i
< nodes
.getLength(); i
++)
116 strings
[i
] = nodes
.item(i
).getTextContent();
120 catch (XPathExpressionException e
)
126 protected String
[] getUniqueText(Element context
, String path
)
128 String
[] strings
= this.getTextArray(context
, path
);
132 ArrayList
<String
> sarl
= new ArrayList
<String
>();
133 for (String s
: strings
)
135 if (!sarl
.contains(s
))
139 return sarl
.toArray(new String
[1]);
142 protected Element
getElement(Element context
, String path
)
146 Node node
= (Node
) this.xpath
.evaluate(altPaths(path
), context
!= null ? context
: doc
,
147 XPathConstants
.NODE
);
151 return node
instanceof Element ?
(Element
) node
: null;
153 catch (XPathExpressionException e
)
159 protected Element
[] getElements(Element context
, String path
)
163 NodeList nodes
= (NodeList
) this.xpath
.evaluate(altPaths(path
), context
!= null ? context
: doc
,
164 XPathConstants
.NODESET
);
165 if (nodes
== null || nodes
.getLength() == 0)
168 Element
[] elements
= new Element
[nodes
.getLength()];
169 for (int i
= 0; i
< nodes
.getLength(); i
++)
171 Node node
= nodes
.item(i
);
172 if (node
instanceof Element
)
173 elements
[i
] = (Element
) node
;
177 catch (XPathExpressionException e
)
183 public Element
[] getUniqueElements(Element context
, String path
, String uniqueTag
)
185 Element
[] elements
= this.getElements(context
, path
);
186 if (elements
== null)
189 HashMap
<String
, Element
> styles
= new HashMap
<String
, Element
>();
190 for (Element e
: elements
)
192 String name
= this.getText(e
, uniqueTag
);
197 return styles
.values().toArray(new Element
[1]);
200 private HashMap
<Element
, Layer
> namedLayerElements
= new HashMap
<Element
, Layer
>();
201 private HashMap
<String
, Layer
> namedLayers
= new HashMap
<String
, Layer
>();
203 private void fillLayerList()
205 if (this.namedLayers
.size() == 0)
207 Element
[] nels
= this.getElements(this.capability
, "descendant::wms:Layer[wms:Name]");
208 if (nels
== null || nels
.length
== 0)
211 for (Element le
: nels
)
213 String name
= this.getLayerName(le
);
216 Layer layer
= new Layer(le
);
217 this.namedLayers
.put(name
, layer
);
218 this.namedLayerElements
.put(le
, layer
);
224 public Element
[] getNamedLayers()
226 if (this.namedLayerElements
.size() == 0)
227 this.fillLayerList();
229 return this.namedLayerElements
.keySet().toArray(new Element
[this.namedLayerElements
.size()]);
232 public Element
getLayerByName(String layerName
)
234 if (this.namedLayers
.size() == 0)
235 this.fillLayerList();
237 Layer l
= this.namedLayers
.get(layerName
);
238 return l
!= null ? l
.element
: null;
241 // ********* Document Items ********* //
243 public String
getVersion()
245 return this.getText("*/@wms:version");
248 public String
getUpdateSequence()
250 return this.getText("*/@wms:updateSequence");
253 // ********* Service Items ********* //
255 public String
getAbstract()
257 return this.getText(this.service
, "wms:Abstract");
260 public String
getAccessConstraints()
262 return this.getText(this.service
, "wms:AccessConstraints");
265 public String
getContactOrganization()
268 this.service
, "wms:ContactInformation/wms:ContactPersonPrimary/wms:ContactOrganization");
271 public String
getContactPerson()
274 this.service
, "wms:ContactInformation/wms:ContactPersonPrimary/wms:ContactPerson");
277 public String
getFees()
279 return this.getText(this.service
, "wms:Fees");
282 public String
[] getKeywordList()
284 return this.getTextArray(this.service
, "wms:KeywordList/wms:Keyword");
287 public String
getLayerLimit()
289 return this.getText(this.service
, "wms:LayerLimit");
292 public String
getMaxWidth()
294 return this.getText(this.service
, "wms:MaxWidth");
297 public String
getMaxHeight()
299 return this.getText(this.service
, "wms:MaxHeight");
302 public String
getName()
304 return this.getText(this.service
, "wms:Name");
307 public String
getTitle()
309 return this.getText(this.service
, "wms:Title");
312 // ********* Capability Items ********* //
314 public String
getOnlineResource()
316 return this.getText(this.capability
, "wms:OnlineResource/@xlink:href");
319 public String
[] getGetCapabilitiesFormats()
321 return this.getTextArray(this.capability
,
322 "wms:Request/wms:GetCapabilities/wms:Format");
325 public String
getGetCapabilitiesRequestGetURL()
327 return this.getText(this.capability
,
328 "wms:Request/wms:GetCapabilities/wms:DCPType/wms:HTTP/wms:Get/wms:OnlineResource/@xlink:href");
331 public String
getGetCapabilitiesRequestPostURL()
333 return this.getText(this.capability
,
334 "wms:Request/wms:GetCapabilities/wms:DCPType/wms:HTTP/wms:Post/wms:OnlineResource/@xlink:href");
337 public String
[] getExceptionFormats()
339 return this.getTextArray(this.capability
, "wms:Exception/wms:Format");
342 public String
getFeatureInfoRequestGetURL()
344 return this.getText(this.capability
,
345 "wms:Request/wms:GetFeatureInfo/wms:DCPType/wms:HTTP/wms:Get/wms:OnlineResource/@xlink:href");
348 public String
getFeatureInfoRequestPostURL()
350 return this.getText(this.capability
,
351 "wms:Request/wms:GetFeatureInfo/wms:DCPType/wms:HTTP/wms:Post/wms:OnlineResource/@xlink:href");
354 public String
[] getGetMapFormats()
356 return this.getTextArray(this.capability
,
357 "wms:Request/wms:GetMap/wms:Format");
360 public String
getGetMapRequestGetURL()
362 return this.getText(this.capability
,
363 "wms:Request/wms:GetMap/wms:DCPType/wms:HTTP/wms:Get/wms:OnlineResource/@xlink:href");
366 public String
getGetMapRequestPostURL()
368 return this.getText(this.capability
,
369 "wms:Request/wms:GetMap/wms:DCPType/wms:HTTP/wms:Post/wms:OnlineResource/@xlink:href");
372 public String
getVendorSpecificCapabilities()
374 return this.getText(this.capability
, "wms:VendorSpecificCapabilities");
377 public Element
getLayer()
379 return this.getElement(this.capability
, "wms:Layer");
382 // ********* Layer Items ********* //
384 protected static class Layer
386 protected HashMap
<Element
, Style
> styleElements
= new HashMap
<Element
, Style
>();
387 protected final Element element
;
388 protected Layer layer
;
389 protected String name
;
390 protected String title
;
392 public Layer(Element element
)
394 this.element
= element
;
398 public String
getLayerAbstract(Element layer
)
400 return this.getText(layer
, "wms:Abstract");
403 public String
getLayerAttributionTitle(Element layer
)
405 return this.getText(layer
, "ancestor-or-self::wms:Layer/wms:Attribution/wms:Title");
408 public String
getLayerAttributionURL(Element layer
)
410 return this.getText(layer
, "ancestor-or-self::wms:Layer/wms:Attribution/wms:OnlineResource/@xlink:href");
413 public String
getLayerAttributionLogoFormat(Element layer
)
415 return this.getText(layer
, "ancestor-or-self::wms:Layer/wms:Attribution/wms:LogoURL/wms:Format");
418 public String
getLayerAttributionLogoHeight(Element layer
)
420 return this.getText(layer
, "ancestor-or-self::wms:Layer/wms:Attribution/wms:LogoURL/@wms:height");
423 public String
getLayerAttributionLogoURL(Element layer
)
425 return this.getText(layer
,
426 "ancestor-or-self::wms:Layer/wms:Attribution/wms:LogoURL/wms:OnlineResource/@xlink:href");
429 public String
getLayerAttributionLogoWidth(Element layer
)
431 return this.getText(layer
, "ancestor-or-self::wms:Layer/wms:Attribution/wms:LogoURL/@wms:width");
434 public Element
[] getLayerAuthorityURLs(Element layer
)
436 return this.getUniqueElements(layer
, "ancestor-or-self::wms:Layer/wms:AuthorityURL", "@wms:type");
439 public abstract BoundingBox
[] getLayerBoundingBoxes(Element layer
);
441 public String
getLayerCascaded(Element layer
)
443 return this.getText(layer
, "ancestor-or-self::wms:Layer/@cascaded");
446 public String
[] getLayerCRS(Element layer
)
448 return this.getUniqueText(layer
, "ancestor-or-self::wms:Layer/wms:CRS");
451 public String
getLayerDataURLFormat(Element layer
)
453 return this.getText(layer
, "wms:DataURL/wms:Format");
456 public String
getLayerDataURL(Element layer
)
458 return this.getText(layer
, "wms:DataURL/wms:OnlineResource/@xlink:href");
461 public Element
[] getLayerDimensions(Element layer
)
463 Element
[] dims
= this.getElements(layer
, "ancestor-or-self::wms:Layer/wms:Dimension");
465 if (dims
== null || dims
.length
== 0)
468 ArrayList
<Element
> uniqueDims
= new ArrayList
<Element
>();
469 ArrayList
<String
> dimNames
= new ArrayList
<String
>();
470 for (Element e
: dims
)
472 // Filter out dimensions with same name.
473 // Keep all those with a null name, even though wms says they're invalid. Let the app decide.
474 String name
= this.getDimensionName(e
);
475 if (name
!= null && dimNames
.contains(name
))
482 return uniqueDims
.toArray(new Element
[uniqueDims
.size()]);
485 public Element
[] getLayerExtents(Element layer
)
487 Element
[] extents
= this.getElements(layer
, "ancestor-or-self::wms:Layer/wms:Extent");
489 if (extents
== null || extents
.length
== 0)
492 ArrayList
<Element
> uniqueExtents
= new ArrayList
<Element
>();
493 ArrayList
<String
> extentNames
= new ArrayList
<String
>();
494 for (Element e
: extents
)
496 // Filter out dimensions with same name.
497 // Keep all those with a null name, even though wms says they're invalid. Let the app decide.
498 String name
= this.getDimensionName(e
);
499 if (name
!= null && extentNames
.contains(name
))
502 uniqueExtents
.add(e
);
503 extentNames
.add(name
);
506 return uniqueExtents
.toArray(new Element
[uniqueExtents
.size()]);
509 public abstract BoundingBox
getLayerGeographicBoundingBox(Element layer
);
511 public String
getLayerFeatureListFormat(Element layer
)
513 return this.getText(layer
, "wms:FeatureListURL/wms:Format");
516 public String
getLayerFeatureListURL(Element layer
)
518 return this.getText(layer
, "wms:FeatureListURL/wms:OnlineResource/@xlink:href");
521 public String
getLayerFixedHeight(Element layer
)
523 return this.getText(layer
, "ancestor-or-self::wms:Layer/@fixedHeight");
526 public String
getLayerFixedWidth(Element layer
)
528 return this.getText(layer
, "ancestor-or-self::wms:Layer/@fixedWidth");
531 public Element
[] getLayerIdentifiers(Element layer
)
533 return this.getUniqueElements(layer
, "wms:Identifier", "wms:authority");
536 public String
[] getLayerKeywordList(Element layer
)
538 return this.getTextArray(layer
, "wms:KeywordList/wms:Keyword");
541 public abstract String
getLayerMaxScaleDenominator(Element layer
);
543 public Element
[] getLayerMetadataURLs(Element layer
)
545 return this.getElements(layer
, "wms:MetadataURL");
548 public abstract String
getLayerMinScaleDenominator(Element layer
);
550 public String
getLayerName(Element layerElement
)
552 Layer layer
= this.namedLayerElements
.get(layerElement
);
553 return layer
!= null && layer
.name
!= null ? layer
.name
: this.getText(layerElement
, "wms:Name");
556 public String
getLayerNoSubsets(Element layer
)
558 return this.getText(layer
, "ancestor-or-self::wms:Layer/@noSubsets");
561 public String
getLayerOpaque(Element layer
)
563 return this.getText(layer
, "ancestor-or-self::wms:Layer/@opaque");
566 public String
getLayerQueryable(Element layer
)
568 return this.getText(layer
, "ancestor-or-self::wms:Layer/@queryable");
571 public String
[] getLayerSRS(Element layer
)
573 return this.getUniqueText(layer
, "ancestor-or-self::wms:Layer/wms:SRS");
576 public Element
[] getLayerStyles(Element layerElement
)
578 Layer layer
= this.namedLayerElements
.get(layerElement
);
582 if (layer
.styleElements
!= null)
583 return layer
.styleElements
.keySet().toArray(new Element
[1]);
585 Element
[] styleElements
= this.getUniqueElements(layerElement
, "ancestor-or-self::wms:Layer/wms:Style", "Name");
586 if (styleElements
== null)
589 layer
.styleElements
= new HashMap
<Element
, Style
>();
590 for (Element se
: styleElements
)
592 Style style
= new Style(se
, layer
);
593 layer
.styleElements
.put(se
, style
);
594 this.styleElements
.put(se
, style
);
597 return layer
.styleElements
.keySet().toArray(new Element
[1]);
600 public Element
[] getLayerSubLayers(Element layer
)
602 return this.getElements(layer
, "wms:Layer");
605 public String
getLayerTitle(Element layerElement
)
607 Layer layer
= this.namedLayerElements
.get(layerElement
);
611 return layer
.title
!= null ? layer
.title
: (layer
.title
= this.getText(layerElement
, "wms:Title"));
614 public Element
getLayerStyleByName(Element layerElement
, String styleName
)
616 Layer layer
= this.namedLayerElements
.get(layerElement
);
620 if (layer
.styleElements
== null || layer
.styleElements
.size() == 0)
622 // Initialize the layer's style list.
623 this.getLayerStyles(layerElement
);
624 if (layer
.styleElements
== null || layer
.styleElements
.size() == 0)
628 Collection
<Style
> styles
= layer
.styleElements
.values();
629 for (Style s
: styles
)
631 if (s
!= null && s
.equals(styleName
))
638 // ********* Style Items ********* //
640 protected HashMap
<Element
, Style
> styleElements
= new HashMap
<Element
, Style
>();
642 protected static class Style
644 protected final Layer layer
;
645 protected final Element element
;
646 protected String name
;
647 protected String title
;
649 public Style(Element element
, Layer layer
)
651 this.element
= element
;
656 public String
getStyleAbstract(Element styleElement
)
658 return this.getText(styleElement
, "wms:Abstract");
661 public String
getStyleLegendFormat(Element styleElement
)
663 return this.getText(styleElement
, "wms:LegendURL/wms:Format");
666 public String
getStyleLegendHeight(Element styleElement
)
668 return this.getText(styleElement
, "wms:LegendURL/@height");
671 public String
getStyleLegendURL(Element styleElement
)
673 return this.getText(styleElement
, "wms:LegendURL/wms:OnlineResource/@xlink:href");
676 public String
getStyleLegendWidth(Element styleElement
)
678 return this.getText(styleElement
, "wms:LegendURL/@width");
681 public String
getStyleName(Element styleElement
)
683 Style style
= this.styleElements
.get(styleElement
);
684 return style
!= null && style
.title
!= null ? style
.title
: this.getText(styleElement
, "wms:Name");
687 public String
getStyleName(Element layerElement
, Element styleElement
)
689 Layer layer
= this.namedLayerElements
.get(layerElement
);
690 if (layer
== null || layer
.styleElements
== null)
691 return this.getStyleName(layerElement
, styleElement
);
693 Style style
= layer
.styleElements
.get(styleElement
);
695 return style
!= null && style
.name
!= null ? style
.title
: this.getText(styleElement
, "wms:Name");
698 public String
getStyleSheetURLFormat(Element styleElement
)
700 return this.getText(styleElement
, "wms:StyleSheetURL/wms:Format");
703 public String
getStyleSheetURL(Element styleElement
)
705 return this.getText(styleElement
, "wms:StyleSheetURL/wms:OnlineResource/@xlink:href");
708 public String
getStyleTitle(Element styleElement
)
710 Style style
= this.styleElements
.get(styleElement
);
711 return style
!= null && style
.title
!= null ? style
.title
: this.getText(styleElement
, "wms:Title");
714 public String
getStyleTitle(Element layerElement
, Element styleElement
)
716 Layer layer
= this.namedLayerElements
.get(layerElement
);
717 if (layer
== null || layer
.styleElements
== null)
718 return this.getStyleTitle(styleElement
);
720 Style style
= this.styleElements
.get(styleElement
);
721 return style
!= null && style
.title
!= null ? style
.title
: this.getText(styleElement
, "wms:Title");
724 public String
getStyleURL(Element styleElement
)
726 return this.getText(styleElement
, "wms:StyleURL/wms:OnlineResource/@xlink:href");
729 public String
getStyleURLFormat(Element styleElement
)
731 return this.getText(styleElement
, "wms:StyleURL/wms:Format");
734 // ********* Authority Items ********* //
736 public String
getAuthorityName(Element authority
)
738 return this.getText(authority
, "@wms:name");
741 public String
getAuthorityURL(Element authority
)
743 return this.getText(authority
, "wms:OnlineResource/@xlink:href");
746 // ********* Identifier Items ********* //
748 public String
getIdentifier(Element identifier
)
750 return this.getText(identifier
, ".");
753 public String
getIdentifierAuthority(Element identifier
)
755 return this.getText(identifier
, "@wms:authority");
758 // ********* Metadata Items ********* //
760 public String
getMetadataFormat(Element metadata
)
762 return this.getText(metadata
, "wms:Format");
765 public String
getMetadataURL(Element metadata
)
767 return this.getText(metadata
, "wms:OnlineResource/@xlink:href");
770 public String
getMetadataType(Element metadata
)
772 return this.getText(metadata
, "@wms:type");
775 // ********* EX_GeographicBoundingBox Items ********* //
777 public String
getWestBoundLongitude(Element bbox
)
779 return this.getText(bbox
, "wms:westBoundLongitude");
782 public String
getEastBoundLongitude(Element bbox
)
784 return this.getText(bbox
, "wms:eastBoundLongitude");
787 public String
getSouthBoundLatitude(Element bbox
)
789 return this.getText(bbox
, "wms:southBoundLatitude");
792 public String
getNorthBoundLatitude(Element bbox
)
794 return this.getText(bbox
, "wms:northBoundLatitude");
797 // ********* BoundingBox Items ********* //
799 public String
getBoundingBoxCRS(Element bbox
)
801 return this.getText(bbox
, "@wms:CRS");
804 public String
getBoundingBoxMinx(Element bbox
)
806 return this.getText(bbox
, "@wms:minx");
809 public String
getBoundingBoxMiny(Element bbox
)
811 return this.getText(bbox
, "@wms:miny");
814 public String
getBoundingBoxMaxx(Element bbox
)
816 return this.getText(bbox
, "@wms:maxx");
819 public String
getBoundingBoxMaxy(Element bbox
)
821 return this.getText(bbox
, "@wms:maxy");
824 public String
getBoundingBoxResx(Element bbox
)
826 return this.getText(bbox
, "@wms:resx");
829 public String
getBoundingBoxResy(Element bbox
)
831 return this.getText(bbox
, "@wms:resy");
834 public String
getBoundingBoxSRS(Element bbox
)
836 return this.getText(bbox
, "@wms:SRS");
839 // ********* Dimension Items ********* //
841 public String
getDimensionName(Element dimension
)
843 return this.getText(dimension
, "@wms:name");
846 public String
getDimensionUnits(Element dimension
)
848 return this.getText(dimension
, "@wms:units");
851 public String
getDimensionUnitSymbol(Element dimension
)
853 return this.getText(dimension
, "@wms:unitSymbol");
856 public String
getDimensionDefault(Element dimension
)
858 return this.getText(dimension
, "@wms:default");
861 public String
getDimensionMultipleValues(Element dimension
)
863 return this.getText(dimension
, "@wms:multipleValues");
866 public String
getDimensionNearestValue(Element dimension
)
868 return this.getText(dimension
, "@wms:nearestValue");
871 public String
getDimensionCurrent(Element dimension
)
873 return this.getText(dimension
, "@wms:current");
876 public String
getDimensionExtent(Element dimension
)
878 return this.getText(dimension
, ".");
881 // ********* Extent Items, wms 1.1 only ********* //
883 public String
getExtentName(Element dimension
)
885 return this.getText(dimension
, "@wms:name");
888 public String
getExtentDefault(Element dimension
)
890 return this.getText(dimension
, "@wms:default");
893 public String
getExtentMultipleValues(Element dimension
)
895 return this.getText(dimension
, "@wms:multipleValues");
898 public String
getExtentNearestValue(Element dimension
)
900 return this.getText(dimension
, "@wms:nearestValue");
903 public String
getExtentCurrent(Element dimension
)
905 return this.getText(dimension
, "@wms:current");
908 public String
getExtentText(Element dimension
)
910 return this.getText(dimension
, ".");