org.springframework.ws.transport.http.LocationTransformerObjectSupport.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ws.transport.http.LocationTransformerObjectSupport.java

Source

/*
 * Copyright 2005-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.ws.transport.http;

import java.util.List;
import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.xml.transform.TransformerObjectSupport;
import org.springframework.xml.xpath.XPathExpression;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * Abstract base class for {@link WsdlDefinitionHandlerAdapter} and {@link XsdSchemaHandlerAdapter} that transforms
 * XSD and WSDL location attributes.
 *
 * @author Arjen Poutsma
 * @since 2.1.2
 */
public abstract class LocationTransformerObjectSupport extends TransformerObjectSupport {

    /** Logger available to subclasses. */
    private final Log logger = LogFactory.getLog(getClass());

    /**
     * Transforms the locations of the given definition document using the given XPath expression.
     * @param xPathExpression the XPath expression
     * @param definitionDocument the definition document
     * @param request the request, used to determine the location to transform to
     */
    protected void transformLocations(XPathExpression xPathExpression, Document definitionDocument,
            HttpServletRequest request) {
        Assert.notNull(xPathExpression, "'xPathExpression' must not be null");
        Assert.notNull(definitionDocument, "'definitionDocument' must not be null");
        Assert.notNull(request, "'request' must not be null");

        List<Node> locationNodes = xPathExpression.evaluateAsNodeList(definitionDocument);
        for (Node locationNode : locationNodes) {
            if (locationNode instanceof Attr) {
                Attr location = (Attr) locationNode;
                if (StringUtils.hasLength(location.getValue())) {
                    String newLocation = transformLocation(location.getValue(), request);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Transforming [" + location.getValue() + "] to [" + newLocation + "]");
                    }
                    location.setValue(newLocation);
                }
            }
        }
    }

    /**
     * Transform the given location string to reflect the given request. If the given location is a full url, the
     * scheme, server name, and port are changed. If it is a relative url, the scheme, server name, and port are
     * prepended. Can be overridden in subclasses to change this behavior.
     * <p/>
     * For instance, if the location attribute defined in the WSDL is {@code http://localhost:8080/context/services/myService},
     * and the request URI for the WSDL is {@code http://example.com:80/context/myService.wsdl}, the location
     * will be changed to {@code http://example.com:80/context/services/myService}.
     * <p/>
     * If the location attribute defined in the WSDL is {@code /services/myService}, and the request URI for the
     * WSDL is {@code http://example.com:8080/context/myService.wsdl}, the location will be changed to
     * {@code http://example.com:8080/context/services/myService}.
     * <p/>
     * This method is only called when the {@code transformLocations} property is true.
     */
    protected String transformLocation(String location, HttpServletRequest request) {
        StringBuilder url = new StringBuilder(request.getScheme());
        url.append("://").append(request.getServerName()).append(':').append(request.getServerPort());
        if (location.startsWith("/")) {
            // a relative path, prepend the context path
            url.append(request.getContextPath()).append(location);
            return url.toString();
        } else {
            int idx = location.indexOf("://");
            if (idx != -1) {
                // a full url
                idx = location.indexOf('/', idx + 3);
                if (idx != -1) {
                    String path = location.substring(idx);
                    url.append(path);
                    return url.toString();
                }
            }
        }
        // unknown location, return the original
        return location;
    }
}