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