Mercurial > dive4elements > river
diff gwt-client/src/main/java/org/dive4elements/river/client/server/GFIServiceImpl.java @ 5838:5aa05a7a34b7
Rename modules to more fitting names.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 15:23:37 +0200 |
parents | flys-client/src/main/java/org/dive4elements/river/client/server/GFIServiceImpl.java@821a02bbfb4e |
children | a3cd78333185 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/GFIServiceImpl.java Thu Apr 25 15:23:37 2013 +0200 @@ -0,0 +1,275 @@ +package org.dive4elements.river.client.server; + +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.log4j.Logger; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import org.dive4elements.artifacts.common.utils.XMLUtils; + +import org.dive4elements.river.client.shared.exceptions.ServerException; +import org.dive4elements.river.client.shared.model.AttributedTheme; +import org.dive4elements.river.client.shared.model.FeatureInfo; +import org.dive4elements.river.client.shared.model.FeatureInfoResponse; +import org.dive4elements.river.client.shared.model.Theme; + +import org.dive4elements.river.client.client.services.GFIService; + + +/** + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class GFIServiceImpl +extends RemoteServiceServlet +implements GFIService +{ + public static final String ERR_NO_VALID_GFI_URL = + "error_no_valid_gfi_url"; + + public static final String ERR_GFI_REQUEST_FAILED = + "error_gfi_req_failed"; + + public static final String ERR_PARSING_RESPONSE_FAILED = + "error_gfi_parsing_failed"; + + + private static final Logger logger = + Logger.getLogger(GFIServiceImpl.class); + + + /** + * @param theme + * @param format + * @param bbox + * @param height + * @param width + * @param x + * @param y + * + * @return + */ + public FeatureInfoResponse query( + Theme theme, + String format, + String bbox, + String projection, + int height, + int width, + int x, + int y + ) throws ServerException + { + logger.info("GFIServiceImpl.query"); + + String path = createGetFeautureInfoURL( + theme, format, bbox, projection, height, width, x, y); + + logger.debug("URL=" + path); + + try { + URL url = new URL(path); + + URLConnection conn = url.openConnection(); + conn.connect(); + + InputStream is = conn.getInputStream(); + + return parseResponse(is); + + } + catch (IOException ioe) { + logger.warn(ioe, ioe); + } + + throw new ServerException(ERR_GFI_REQUEST_FAILED); + } + + + /** + * @param map + * @param theme + * @param format + * @param x + * @param y + * + * @return + */ + protected String createGetFeautureInfoURL( + Theme theme, + String infoFormat, + String bbox, + String projection, + int height, + int width, + int x, + int y + ) throws ServerException + { + String url = getUrl(theme); + + if (url == null || url.length() == 0) { + throw new ServerException(ERR_NO_VALID_GFI_URL); + } + + String layers = ((AttributedTheme)theme).getAttr("layers"); + + StringBuilder sb = new StringBuilder(); + sb.append(url); + + if (url.indexOf("?") < 0) { + sb.append("?SERVICE=WMS"); + } + else { + sb.append("&SERVICE=WMS"); + } + + sb.append("&VERSION=1.1.1"); + sb.append("&REQUEST=GetFeatureInfo"); + sb.append("&LAYERS=" + layers); + sb.append("&QUERY_LAYERS=" + layers); + sb.append("&BBOX=" + bbox); + sb.append("&HEIGHT=" + height); + sb.append("&WIDTH=" + width); + sb.append("&FORMAT=image/png"); + sb.append("&INFO_FORMAT=" + infoFormat); + sb.append("&SRS=" + projection); + sb.append("&X=" + String.valueOf(x)); + sb.append("&Y=" + String.valueOf(y)); + + return sb.toString(); + } + + + protected String getUrl(Theme theme) { + AttributedTheme attr = (AttributedTheme) theme; + return attr.getAttr("url"); + } + + + protected FeatureInfoResponse parseResponse(InputStream is) { + logger.debug("GFIServiceImpl.parseResponse"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte [] buf = new byte[1024]; + + int r = -1; + try { + while ((r = is.read(buf)) >= 0) { + baos.write(buf, 0, r); + } + } catch (IOException ex) { + logger.warn("GetFeatureInfo response could not be read: ", ex); + return new FeatureInfoResponse(); + } + + String content; + try { + content = baos.toString("UTF-8"); + } + catch (UnsupportedEncodingException uee) { + content = baos.toString(); + } + + Document response = XMLUtils.parseDocument(content); + if (response != null) { + List<FeatureInfo> features = new ArrayList<FeatureInfo>(); + parseFeatureInfos(response, features); + return new FeatureInfoResponse(features, null); + } + // Unable to parse just return the response as is + return new FeatureInfoResponse(new ArrayList<FeatureInfo>(), content); + } + + + protected void parseFeatureInfos(Node node, List<FeatureInfo> features) { + logger.debug("GFIServiceImpl.parseFeatureInfos"); + + String name = node.getNodeName(); + + if (name.endsWith("_layer")) { + features.add(parseFeature(node)); + + return; + } + + NodeList children = node.getChildNodes(); + + if (children != null && children.getLength() > 0) { + for (int i = 0, n = children.getLength(); i < n; i++) { + parseFeatureInfos(children.item(i), features); + } + } + } + + + protected FeatureInfo parseFeature(Node node) { + logger.debug("GFIServiceImpl.parseFeature"); + + String layername = node.getNodeName(); + + FeatureInfo f = new FeatureInfo(layername); + + NodeList children = node.getChildNodes(); + int numChildren = children != null ? children.getLength() : 0; + + logger.debug("Feature '" + layername + "' has " + numChildren + " nodes."); + + for (int i = 0; i < numChildren; i++) { + Node tmp = children.item(i); + String nodeName = tmp.getNodeName(); + + logger.debug(" node name: '" + nodeName + "'"); + + if (nodeName.equals("gml:name")) { + logger.debug("NAME node has child: " + tmp.getFirstChild().getNodeValue()); + f.setLayername(tmp.getFirstChild().getNodeValue()); + } + else if (nodeName.endsWith("_feature")) { + parseFeatureAttributes(tmp, f); + } + } + + return f; + } + + + protected void parseFeatureAttributes(Node node, FeatureInfo f) { + logger.debug("GFIServiceImpl.parseFeatureAttributes"); + + NodeList children = node.getChildNodes(); + int numChildren = children != null ? children.getLength() : 0; + + logger.debug("Has " + numChildren + " attributes."); + + for (int i = 0; i < numChildren; i++) { + Node tmp = children.item(i); + String name = tmp.getNodeName(); + + logger.debug(" tmp attribute name: '" + name + "'"); + + if (name.equals("gml:boundedBy")) { + // TODO + } + else { + Node child = tmp.getFirstChild(); + if (child != null) { + f.addAttr(name, child.getNodeValue()); + } + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :