<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="org.osgeo.mapguide.*" %> <%@ page import="java.util.*" %> <%@ page import="java.lang.*" %> <%@ page import="java.io.*" %> <%@ page import="java.text.*" %> <%@ page import="javax.xml.parsers.DocumentBuilder" %> <%@ page import="javax.xml.parsers.DocumentBuilderFactory" %> <%@ page import="org.w3c.dom.Document" %> <%@ page import="org.w3c.dom.Element" %> <%@ page import="org.w3c.dom.Node" %> <%@ page import="org.w3c.dom.NodeList" %> <%@ page import="javax.servlet.jsp.*" %> <%@ page import="javax.servlet.http.*" %> <%@ include file="common.jsp" %> <%@ page isThreadSafe="false" %> <%! String mapName; String sessionId; String localeCode; Locale locale; class SelectionSet { private HashMap> _layers; public SelectionSet() { _layers = new HashMap>(); } public void addFeature(Feature feat) { if (!_layers.containsKey(feat.LayerName)) _layers.put(feat.LayerName, new Vector()); _layers.get(feat.LayerName).add(feat); } public String[] getLayers() { String[] layers = new String[_layers.keySet().size()]; _layers.keySet().toArray(layers); return layers; } public Feature[] getFeatures(String layerName) { if (_layers.containsKey(layerName)) { Vector layerFeatures = _layers.get(layerName); Feature[] feats = new Feature[layerFeatures.size()]; layerFeatures.toArray(feats); return feats; } return null; } } class ZoomBox { public double MinX; public double MinY; public double MaxX; public double MaxY; } class FeatureProperty { public String Name; public String Value; } class Feature { public String LayerName; public ZoomBox Zoom; private HashMap _properties; public Feature(String layerName) { this.LayerName = layerName; _properties = new HashMap(); } public void addProperty(FeatureProperty prop) { _properties.put(prop.Name, prop); } public FeatureProperty[] getProperties() { Collection values = _properties.values(); FeatureProperty[] props = new FeatureProperty[values.size()]; values.toArray(props); return props; } } static String getTextValue(Element el, String tagName) { String textVal = null; NodeList nl = el.getElementsByTagName(tagName); if (nl != null && nl.getLength() > 0) { Element e = (Element)nl.item(0); textVal = e.getFirstChild().getNodeValue(); } return textVal; } static HashMap GetLayerPropertyMappings(MgResourceService resSvc, MgLayerBase layer) throws Exception { HashMap mappings = new HashMap(); MgByteReader content = resSvc.GetResourceContent(layer.GetLayerDefinition()); ByteArrayInputStream contentReader = new ByteArrayInputStream(content.ToString().getBytes("UTF-8")); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(contentReader); doc.getDocumentElement().normalize(); NodeList propNodes = doc.getElementsByTagName("PropertyMapping"); for (int i = 0; i < propNodes.getLength(); i++) { Element propEl = (Element)propNodes.item(i); String name = getTextValue(propEl, "Name"); String value = getTextValue(propEl, "Value"); if (name != null && value != null) mappings.put(name, value); } return mappings; } String GetPropertyValueFromFeatureReader(MgFeatureReader reader, MgAgfReaderWriter agfRw, int propType, String propName) throws Exception { String value = ""; switch(propType) { case MgPropertyType.Boolean: value = String.format(locale, "%s", reader.GetBoolean(propName)); break; case MgPropertyType.Byte: value = String.format(locale, "%d", reader.GetByte(propName)); break; case MgPropertyType.DateTime: value = GetDateTimeString(reader.GetDateTime(propName)); // yyyy-mm-dd is enforced regardless of locale break; case MgPropertyType.Single: value = String.format(locale, "%f", reader.GetSingle(propName)); break; case MgPropertyType.Double: value = String.format(locale, "%f", reader.GetDouble(propName)); break; case MgPropertyType.Int16: value = String.format(locale, "%d", reader.GetInt16(propName)); break; case MgPropertyType.Int32: value = String.format(locale, "%d", reader.GetInt32(propName)); break; case MgPropertyType.Int64: value = String.format(locale, "%d", reader.GetInt64(propName)); break; case MgPropertyType.String: value = JsonEscape(reader.GetString(propName)); // string content is arbitrary value = value.replaceAll("\\s+", " ").trim(); break; default: //NOT PRESENTABLE IN PROPERTY GRID value = ""; break; } return value; } static String GetDateTimeString(MgDateTime value) throws MgException { return value.GetYear() + "-" + value.GetMonth() + "-" + value.GetDay(); } void GetParameters(HttpServletRequest request) { mapName = GetParameter(request, "MAPNAME"); sessionId = GetParameter(request, "SESSION"); localeCode = GetParameter(request, "LOCALE"); } String JsonEscape(String str) { return EscapeForHtml(str).replace("\\", "\\\\"); } String JsonifyError(Exception ex) { if (ex == null) return ""; /* { "Error" : { "Message" : , "StackTrace" : } } */ StringBuffer sb = new StringBuffer(); //Use exception message or type name if no message found String msg = ex.getMessage(); if (msg == null || msg.length() == 0) { msg = MgLocalizer.GetString("SERVERERROR", localeCode); } //Begin response sb.append("{\"Error\":{"); //Exception message sb.append("\"Message\":\"" + JsonEscape(msg) + "\","); StringBuffer strace = new StringBuffer(); StackTraceElement[] st = ex.getStackTrace(); for (int i = 0; i < st.length; i++) { strace.append(st[i].getClassName() + "." + st[i].getMethodName() + "(" + st[i].getLineNumber() + ")\\n"); } sb.append("\"StackTrace\":\"" + JsonEscape(strace.toString()) + "\""); //End response sb.append("}}"); return sb.toString(); } static String GetJson(SelectionSet set) { /* A sample of the JSON output this method will produce: { "Layer1" : [ { 'values' { "name" : "name1" , "value" : "value1" }, 'zoom' : { x: num1, y: num2 } } , .., .., .., ], "Layer2" : [ { 'values' { "name" : "name2" , "value" : "value2" }, 'zoom' : { x: num1, y: num2 } } , .., .., .., ] } */ if (set == null) return ""; StringBuffer sb = new StringBuffer(); //Begin selection set sb.append("{"); String[] layers = set.getLayers(); for (int i = 0; i < layers.length; i++) { //Begin layer sb.append("\"" + layers[i] + "\" : ["); Feature[] features = set.getFeatures(layers[i]); for (int j = 0; j < features.length; j++) { Feature feat = features[j]; //begin feature //begin feature properties sb.append("{\"values\" : ["); FeatureProperty[] properties = feat.getProperties(); for(int k = 0; k < properties.length; k++) { FeatureProperty fp = properties[k]; sb.append("{\"name\" : \"" + fp.Name + "\", \"value\" : \"" + fp.Value + "\" }"); if (k != properties.length - 1) sb.append(","); } //end feature properties //begin zoom sb.append("], \"zoom\" : "); if (feat.Zoom == null) sb.append("null"); else sb.append(String.format(Locale.ROOT, "{\"minx\" : %f, \"miny\" : %f, \"maxx\" : %f, \"maxy\" : %f }", feat.Zoom.MinX, feat.Zoom.MinY, feat.Zoom.MaxX, feat.Zoom.MaxY)); //end zoom //end feature sb.append("}"); if (j != features.length - 1) sb.append(","); } //End Layer sb.append("]"); if (i != layers.length - 1) sb.append(","); } //End selection set sb.append("}"); return sb.toString(); } %> <% mapName = ""; sessionId = ""; localeCode = ""; GetParameters(request); if (null == localeCode || localeCode.length() == 0) localeCode = GetDefaultLocale(); locale = new Locale(localeCode); try { MgUserInformation cred = new MgUserInformation(sessionId); cred.SetClientIp(GetClientIp(request)); cred.SetClientAgent(GetClientAgent()); MgSiteConnection site = new MgSiteConnection(); site.Open(cred); MgResourceService resSvc = (MgResourceService)site.CreateService(MgServiceType.ResourceService); MgMap map = new MgMap(site); map.Open(mapName); MgSelection selection = new MgSelection(map); selection.Open(resSvc, mapName); MgReadOnlyLayerCollection layers = selection.GetLayers(); if (layers != null && layers.GetCount() > 0) { int layerCount = layers.GetCount(); MgAgfReaderWriter agfRW = new MgAgfReaderWriter(); SelectionSet selectionSet = new SelectionSet(); for (int i = 0; i < layerCount; i++) { MgLayerBase layer = layers.GetItem(i); String layerName = layer.GetName(); MgResourceIdentifier fsId = new MgResourceIdentifier(layer.GetFeatureSourceId()); String className = layer.GetFeatureClassName(); String geomName = layer.GetFeatureGeometryName(); MgFeatureQueryOptions query = new MgFeatureQueryOptions(); HashMap mappings = GetLayerPropertyMappings(resSvc, layer); Set propNames = mappings.keySet(); for (String name : propNames) { query.AddFeatureProperty(name); } query.AddFeatureProperty(geomName); String filter = selection.GenerateFilter(layer, className); query.SetFilter(filter); MgFeatureReader reader = layer.SelectFeatures(query); MgClassDefinition clsDef = reader.GetClassDefinition(); MgPropertyDefinitionCollection props = clsDef.GetProperties(); while (reader.ReadNext()) { Feature feat = new Feature(layerName); ZoomBox zoom = null; for (int k = 0; k < props.GetCount(); k++) { MgPropertyDefinition propDef = props.GetItem(k); String propName = propDef.GetName(); int propType = reader.GetPropertyType(propName); if (mappings.get(propName) != null || propType == MgPropertyType.Geometry) { String value = ""; if (!reader.IsNull(propName)) { if (propName.equals(geomName)) { MgByteReader agf = reader.GetGeometry(propName); MgGeometry geom = agfRW.Read(agf); MgEnvelope env = geom.Envelope(); MgCoordinate ll = env.GetLowerLeftCoordinate(); MgCoordinate ur = env.GetUpperRightCoordinate(); zoom = new ZoomBox(); zoom.MinX = ll.GetX(); zoom.MinY = ll.GetY(); zoom.MaxX = ur.GetX(); zoom.MaxY = ur.GetY(); feat.Zoom = zoom; } else { value = GetPropertyValueFromFeatureReader(reader, agfRW, propType, propName); } if (mappings.get(propName) != null) { FeatureProperty fp = new FeatureProperty(); fp.Name = mappings.get(propName); fp.Value = value; feat.addProperty(fp); } } } } selectionSet.addFeature(feat); } reader.Close(); } //Now output the selection set response.addHeader("Content-Type", "application/json"); response.addHeader("X-JSON", "true"); response.getWriter().write(GetJson(selectionSet)); } } catch (MgException ex) { response.addHeader("Content-Type", "application/json"); response.addHeader("X-JSON", "true"); response.getWriter().write(JsonifyError(ex)); } catch (Exception ex) { response.addHeader("Content-Type", "application/json"); response.addHeader("X-JSON", "true"); response.getWriter().write(JsonifyError(ex)); } %>