PageRenderTime 62ms CodeModel.GetById 46ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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}