⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlschemaencoder.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* 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&amp;service=wfs&amp;version=1.0.0&amp;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 + -