📄 xmlschemaencoder.java
字号:
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.wfs.xml.v1_0_0;
import net.opengis.wfs.DescribeFeatureTypeType;
import org.geoserver.ows.util.RequestUtils;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFS;
import org.geoserver.wfs.WFSDescribeFeatureTypeOutputFormat;
import org.geoserver.wfs.WFSException;
import org.geotools.feature.FeatureType;
import org.geotools.gml.producer.FeatureTypeTransformer;
import org.vfny.geoserver.global.Data;
import org.vfny.geoserver.global.FeatureTypeInfo;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.TransformerException;
public class XmlSchemaEncoder extends WFSDescribeFeatureTypeOutputFormat {
/** Standard logging instance for class */
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.responses");
// Initialize some generic GML information
// ABSTRACT OUTSIDE CLASS, IF POSSIBLE
private static final String SCHEMA_URI = "\"http://www.w3.org/2001/XMLSchema\"";
private static final String XS_NAMESPACE = "\n xmlns:xs=" + SCHEMA_URI;
private static final String GML_URL = "\"http://www.opengis.net/gml\"";
private static final String GML_NAMESPACE = "\n xmlns:gml=" + GML_URL;
private static final String ELEMENT_FORM_DEFAULT = "\n elementFormDefault=\"qualified\"";
private static final String ATTR_FORM_DEFAULT = "\n attributeFormDefault=\"unqualified\" version=\"1.0\">";
private static final String TARGETNS_PREFIX = "\n targetNamespace=\"";
private static final String TARGETNS_SUFFIX = "\" ";
/** Fixed return footer information */
private static final String FOOTER = "\n</xs:schema>";
WFS wfs;
Data catalog;
public XmlSchemaEncoder(WFS wfs, Data catalog) {
super("XMLSCHEMA");
this.wfs = wfs;
this.catalog = catalog;
}
public String getMimeType(Object value, Operation operation)
throws ServiceException {
return "text/xml";
}
protected void write(FeatureTypeInfo[] featureTypeInfos, OutputStream output,
Operation describeFeatureType) throws IOException {
//generates response, using general function
String xmlResponse = generateTypes(featureTypeInfos, (DescribeFeatureTypeType) describeFeatureType.getParameters()[0]);
if (!wfs.isVerbose()) {
//strip out the formatting. This is pretty much the only way we
//can do this, as the user files are going to have newline
//characters and whatnot, unless we can get rid of formatting
//when we read the file, which could be worth looking into if
//this slows things down.
xmlResponse = xmlResponse.replaceAll(">\n[ \\t\\n]*", ">");
xmlResponse = xmlResponse.replaceAll("\n[ \\t\\n]*", " ");
}
byte[] content = xmlResponse.getBytes();
output.write(content);
}
/**
* Internal method to generate the XML response object, using feature
* types.
*
* @param wfsRequest The request object.
*
* @return The XMLSchema describing the features requested.
*
* @throws WFSException For any problems.
*/
private final String generateTypes(FeatureTypeInfo[] infos, DescribeFeatureTypeType request)
throws IOException {
// Initialize return information and intermediate return objects
StringBuffer tempResponse = new StringBuffer();
tempResponse.append("<?xml version=\"1.0\" encoding=\"" + wfs.getCharSet().displayName()
+ "\"?>" + "\n<xs:schema ");
String proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(request.getBaseUrl(), wfs.getGeoServer().getProxyBaseUrl());
//allSameType will throw WFSException if there are types that are not found.
if (allSameType(infos)) {
//all the requested have the same namespace prefix, so return their
//schemas.
FeatureTypeInfo ftInfo = infos[0];
String targetNs = ftInfo.getNameSpace().getURI();
//String targetNs = nsInfoType.getXmlns();
tempResponse.append(TARGETNS_PREFIX + targetNs + TARGETNS_SUFFIX);
//namespace
tempResponse.append("\n " + "xmlns:" + ftInfo.getNameSpace().getPrefix() + "=\""
+ targetNs + "\"");
//xmlns:" + nsPrefix + "=\"" + targetNs
//+ "\"");
tempResponse.append(GML_NAMESPACE);
tempResponse.append(XS_NAMESPACE);
tempResponse.append(ELEMENT_FORM_DEFAULT + ATTR_FORM_DEFAULT);
//request.getBaseUrl should actually be GeoServer.getSchemaBaseUrl()
//but that method is broken right now. See the note there.
//JD: need a good way to publish resources under a web url, at the
// same time abstracting away the httpness of the service, for
// now replacing the schemas.opengis.net
// tempResponse.append("\n\n<xs:import namespace=" + GML_URL
// + " schemaLocation=\"" + request.getSchemaBaseUrl()
// + "gml/2.1.2/feature.xsd\"/>\n\n");
tempResponse.append("\n\n<xs:import namespace=" + GML_URL + " schemaLocation=\"" +
ResponseUtils.appendPath(proxifiedBaseUrl, "schemas/gml/2.1.2.1/feature.xsd") + "\"/>\n\n");
tempResponse.append(generateSpecifiedTypes(infos));
} else {
//the featureTypes do not have all the same prefixes.
tempResponse.append(XS_NAMESPACE);
tempResponse.append(ELEMENT_FORM_DEFAULT + ATTR_FORM_DEFAULT);
Set prefixes = new HashSet();
//iterate through the types, and make a set of their prefixes.
for (int i = 0; i < infos.length; i++) {
FeatureTypeInfo ftInfo = infos[i];
prefixes.add(ftInfo.getNameSpace().getPrefix());
}
Iterator prefixIter = prefixes.iterator();
while (prefixIter.hasNext()) {
//iterate through prefixes, and add the types that have that prefix.
String prefix = prefixIter.next().toString();
String wfsBaseUrl;
if(proxifiedBaseUrl.endsWith("/"))
wfsBaseUrl = proxifiedBaseUrl + request.getService().toLowerCase();
else
wfsBaseUrl = proxifiedBaseUrl + "/" + request.getService().toLowerCase();
tempResponse.append(getNSImport(prefix, infos, wfsBaseUrl));
}
}
tempResponse.append(FOOTER);
return tempResponse.toString();
}
/**
* Creates a import namespace element, for cases when requests contain
* multiple namespaces, as you can not have more than one target
* namespace. See wfs spec. 8.3.1. All the typeNames that have the
* correct prefix are added to the import statement.
*
* @param prefix the namespace prefix, which must be mapped in the main
* ConfigInfo, for this import statement.
* @param typeNames a list of all requested typeNames, only those that
* match the prefix will be a part of this import statement.
* @param r DOCUMENT ME!
*
* @return The namespace element.
*/
private StringBuffer getNSImport(String prefix, FeatureTypeInfo[] infos, String baseUrl) {
LOGGER.finer("prefix is " + prefix);
StringBuffer retBuffer = new StringBuffer("\n <xs:import namespace=\"");
String namespace = catalog.getNameSpace(prefix).getURI();
retBuffer.append(namespace + "\"");
retBuffer.append("\n schemaLocation=\"" + baseUrl
+ "?request=DescribeFeatureType&service=wfs&version=1.0.0&typeName=");
for (int i = 0; i < infos.length; i++) {
FeatureTypeInfo info = infos[i];
String typeName = info.getName();
if (typeName.startsWith(prefix + ":")) {
retBuffer.append(typeName + ",");
}
//JD: some of this logic should be fixed by poplulating the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -