/webportal/src/main/java/au/org/emii/portal/wms/WMSSupportXmlbeans.java

http://alageospatialportal.googlecode.com/ · Java · 301 lines · 207 code · 47 blank · 47 comment · 33 complexity · ceade25dd5e5ad7361c49ba90286a2db MD5 · raw file

  1. package au.org.emii.portal.wms;
  2. import au.org.emii.portal.menu.MapLayer;
  3. import au.org.emii.portal.util.Sequence;
  4. import au.org.emii.portal.util.Validate;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.ArrayList;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import net.opengis.wms.LayerDocument;
  11. import net.opengis.wms.WMSCapabilitiesDocument;
  12. import net.opengis.wms.LayerDocument.Layer;
  13. import net.opengis.wms.StyleDocument.Style;
  14. import net.opengis.wms.WMSCapabilitiesDocument.WMSCapabilities;
  15. import org.apache.xmlbeans.XmlException;
  16. import au.org.emii.portal.config.xmlbeans.Discovery;
  17. import au.org.emii.portal.menu.MapLayerMetadata;
  18. import net.opengis.wms.AuthorityURLDocument.AuthorityURL;
  19. import net.opengis.wms.MetadataURLDocument.MetadataURL;
  20. public abstract class WMSSupportXmlbeans extends WMSSupport {
  21. @Override
  22. public MapLayer discover(Discovery discovery, boolean displayAllChildren, boolean queryableDisabled, boolean quiet) {
  23. this.quiet = quiet;
  24. this.queryableDisabled = queryableDisabled;
  25. this.cache = discovery.getCache();
  26. MapLayer mapLayer = null;
  27. // setup defaults provided in discovery object
  28. opacity = discovery.getOpacity();
  29. String discoveryUri = uriResolver.resolve(discovery);
  30. id = discovery.getId();
  31. description = discovery.getDescription();
  32. discoveryName = discovery.getName();
  33. /*
  34. * find out the base URI for http requests - its a nested attribute with
  35. * the xpath: /WMS_Capabilities/Capability/Request/GetCapabilities/DCPType/HTTP/Get/OnlineResource[@href]
  36. *
  37. * Since the xpath is so long with scope for various parts being null, we need to
  38. * protect against NPEs here...
  39. */
  40. try {
  41. // configure an InputStream with a timeout
  42. InputStream is = httpConnection.configureURLConnection(discoveryUri).getInputStream();
  43. WMSCapabilitiesDocument doc = WMSCapabilitiesDocument.Factory.parse(is);
  44. WMSCapabilities type = doc.getWMSCapabilities();
  45. // the first listed DCP HTTP server will be used as a base uri
  46. baseUri =
  47. type.getCapability().
  48. getRequest().
  49. getGetCapabilities()
  50. .getDCPTypeList()
  51. .get(0)
  52. .getHTTP()
  53. .getGet()
  54. .getOnlineResource()
  55. .getHref();
  56. // the first listed imageformat will be used for rendering
  57. imageFormat =
  58. type.getCapability()
  59. .getRequest()
  60. .getGetMap()
  61. .getFormatList()
  62. .get(0);
  63. /* no name for the menu specified - try and find one from the
  64. * capabilities document
  65. */
  66. if (discoveryName == null) {
  67. discoveryName =
  68. type.getService()
  69. .getTitle();
  70. if (Validate.empty(discoveryName)) {
  71. /* discovery name is still empty (server misconfiguration)
  72. * use our default name from config file
  73. */
  74. discoveryName = languagePack.getLang("wms_unamed_server");
  75. }
  76. }
  77. if (baseUri != null) {
  78. if (cache) {
  79. logger.debug("+ indirect caching " + discovery.getId());
  80. baseUri = layerUtilities.getIndirectCacheUrl(baseUri);
  81. }
  82. // root layer for this server
  83. mapLayer = new MapLayer();
  84. LayerDocument.Layer layer = type.getCapability().getLayer();
  85. processLayer(mapLayer, layer, new Sequence(), displayAllChildren);
  86. }
  87. else {
  88. lastErrorMessage = "Unable to parse a GetCapabilities document from '" +
  89. discoveryUri + "'(missing OnlineResource href attribute) ";
  90. }
  91. }
  92. catch (NullPointerException e) {
  93. parseError = true;
  94. lastErrorMessage =
  95. "Unable to parse a GetCapabilities document at '" +
  96. discoveryUri + "' (a required field was missing)";
  97. }
  98. catch (XmlException e) {
  99. parseError = true;
  100. lastErrorMessage =
  101. "Unable to parse the GetCapabilities document " +
  102. "from '" + discoveryUri + "' " +
  103. "(parse error - did you set the " +
  104. "correct WMS version if manually specified?). " +
  105. "Root cause: " + e.getMessage();
  106. }
  107. catch (IOException e) {
  108. // for 404 errors, the message will be the requested url
  109. readError = true;
  110. lastErrorMessage = "IO error connecting to server at '" +
  111. discoveryUri + "'. Root cause: " + e.getMessage();
  112. }
  113. return checkErrorFlags(discovery, mapLayer);
  114. }
  115. private void processLayer(MapLayer parent, Layer layer, Sequence sequence, boolean displayAllChildren) {
  116. MapLayer mapLayer;
  117. String label;
  118. if (sequence.getValue() == 0) {
  119. mapLayer = parent;
  120. /* use the name supplied in the config file for the discovery
  121. * root label
  122. */
  123. label = discoveryName;
  124. }
  125. else {
  126. mapLayer = new MapLayer();
  127. parent.addChild(mapLayer);
  128. label = layer.getTitle();
  129. }
  130. mapLayer.setName(label);
  131. mapLayer.setId(id + WMSSupport.sequenceFragment(sequence));
  132. // if the abstract has been set for this layer, use it instead of the
  133. // description from the config file
  134. mapLayer.setDescription(
  135. (layer.getAbstract() != null) ?
  136. layer.getAbstract(): description
  137. );
  138. // displayable layers have a 'name' element that is not null
  139. String name = layer.getName();
  140. if (name != null) {
  141. // add this layer and do not process its children
  142. mapLayer.setLayer(name);
  143. logger.debug("...adding layer: " + mapLayer.getName());
  144. mapLayer.setUri(baseUri);
  145. mapLayer.setImageFormat(imageFormat);
  146. mapLayer.setDisplayable(true);
  147. mapLayer.setOpacity(opacity);
  148. mapLayer.setQueryable(
  149. (! queryableDisabled) &&
  150. layer.isSetQueryable()
  151. );
  152. //attempt to add boundingbox, TODO: test & fix
  153. try {
  154. List<Double> bbox = new ArrayList<Double>();
  155. bbox.add(new Double(layer.getBoundingBoxArray(0).getMinx()));
  156. bbox.add(new Double(layer.getBoundingBoxArray(0).getMiny()));
  157. bbox.add(new Double(layer.getBoundingBoxArray(0).getMaxx()));
  158. bbox.add(new Double(layer.getBoundingBoxArray(0).getMaxy()));
  159. MapLayerMetadata md = new MapLayerMetadata();
  160. md.setBbox(bbox);
  161. mapLayer.setMapLayerMetadata(md);
  162. } catch (Exception e) {
  163. }
  164. /* sometimes people don't setup servers right and leave off the label
  165. * names - if this is the case, substitute the layer name instead
  166. */
  167. if (Validate.empty(mapLayer.getName())) {
  168. mapLayer.setName(mapLayer.getLayer());
  169. }
  170. layerSettings(mapLayer, layer);
  171. mapLayer.addStyles(
  172. processStyles(layer.getStyleList())
  173. );
  174. // generate a URI to get the legend for the default style
  175. mapLayer.setDefaultStyleLegendUri(layerUtilities.coerceLegendUri(mapLayer));
  176. }
  177. else {
  178. mapLayer.setDisplayable(false);
  179. }
  180. boolean hasMetadata = false;
  181. List<MetadataURL> metadataURLList = layer.getMetadataURLList();
  182. if (metadataURLList != null) {
  183. if (metadataURLList.size() > 0) {
  184. MapLayerMetadata mlmd = mapLayer.getMapLayerMetadata();
  185. if (mlmd == null) {
  186. mlmd = new MapLayerMetadata();
  187. }
  188. mlmd.setMoreInfo(metadataURLList.get(0).getOnlineResource().getHref());
  189. mapLayer.setMapLayerMetadata(mlmd);
  190. hasMetadata = true;
  191. }
  192. }
  193. if (!hasMetadata) {
  194. List<AuthorityURL> authorityURLList = layer.getAuthorityURLList();
  195. if (authorityURLList != null) {
  196. if (authorityURLList.size() > 0) {
  197. MapLayerMetadata mlmd = mapLayer.getMapLayerMetadata();
  198. if (mlmd == null) {
  199. mlmd = new MapLayerMetadata();
  200. }
  201. mlmd.setMoreInfo(authorityURLList.get(0).getOnlineResource().getHref());
  202. mapLayer.setMapLayerMetadata(mlmd);
  203. }
  204. }
  205. }
  206. /* process all children if this layer is not displayable
  207. * (no name field) or we are forced to display all children
  208. */
  209. if (name == null || displayAllChildren) {
  210. // process any children...
  211. List<Layer> layerChildren = layer.getLayerList();
  212. Iterator<Layer> it = layerChildren.iterator();
  213. while (it.hasNext()) {
  214. sequence.increment();
  215. processLayer(mapLayer, it.next(), sequence, displayAllChildren);
  216. }
  217. }
  218. }
  219. private List<WMSStyle> processStyles(List<Style> serverStyles) {
  220. List<WMSStyle> styles = new ArrayList<WMSStyle>();
  221. for (Style serverStyle : serverStyles) {
  222. // adjust the uri for caching if necessary
  223. String uri = serverStyle.getLegendURLList().get(0).getOnlineResource().getHref();
  224. if (cache) {
  225. uri =
  226. layerUtilities.getFQUri(
  227. layerUtilities.getIndirectCacheUrl(uri)
  228. );
  229. }
  230. WMSStyle style = new WMSStyle();
  231. style.setName(serverStyle.getName());
  232. style.setTitle(serverStyle.getTitle());
  233. style.setDescription(serverStyle.getAbstract());
  234. // use the first listed online resource as the HREF
  235. style.setLegendUri(uri);
  236. style.setLegendFormat(serverStyle.getLegendURLList().get(0).getFormat());
  237. styleSettings(style, serverStyle);
  238. styles.add(style);
  239. }
  240. return styles;
  241. }
  242. /**
  243. * Implementation specific layer settings (will be executed once per layer)
  244. * @param mapLayer
  245. * @param layer
  246. */
  247. protected abstract void layerSettings(MapLayer mapLayer, Layer layer);
  248. /**
  249. * Implementation specific layer settings (will be executed once per layer)
  250. * @param style
  251. * @param serverStyle
  252. */
  253. protected abstract void styleSettings(WMSStyle style, Style serverStyle);
  254. }