org.apache.cxf.transport.http.spring.HttpConduitBeanDefinitionParser Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.transport.http.spring;
import javax.xml.namespace.QName;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.configuration.jsse.TLSClientParametersConfig;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.configuration.security.CertificateConstraintsType;
import org.apache.cxf.configuration.security.CipherSuites;
import org.apache.cxf.configuration.security.FiltersType;
import org.apache.cxf.configuration.security.KeyManagersType;
import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
import org.apache.cxf.configuration.security.SecureRandomParameters;
import org.apache.cxf.configuration.security.TrustManagersType;
import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.MessageTrustDecider;
import org.apache.cxf.transport.http.auth.HttpAuthSupplier;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
public class HttpConduitBeanDefinitionParser
extends AbstractBeanDefinitionParser {
private static final String HTTP_NS =
"http://cxf.apache.org/transports/http/configuration";
private static final String SECURITY_NS =
"http://cxf.apache.org/configuration/security";
@Override
public void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean) {
bean.setAbstract(true);
mapElementToJaxbProperty(element, bean,
new QName(HTTP_NS, "client"), "client",
HTTPClientPolicy.class);
mapElementToJaxbProperty(element, bean,
new QName(HTTP_NS, "proxyAuthorization"), "proxyAuthorization",
ProxyAuthorizationPolicy.class);
mapElementToJaxbProperty(element, bean,
new QName(HTTP_NS, "authorization"), "authorization",
AuthorizationPolicy.class);
mapSpecificElements(element, bean);
}
/**
* This method specifically maps the "trustDecider" and "basicAuthSupplier"
* elements to properties on the HttpConduit.
*
* @param parent This should represent "conduit".
* @param bean The bean parser.
*/
private void mapSpecificElements(
Element parent,
BeanDefinitionBuilder bean
) {
Node n = parent.getFirstChild();
while (n != null) {
if (Node.ELEMENT_NODE != n.getNodeType()
|| !HTTP_NS.equals(n.getNamespaceURI())) {
n = n.getNextSibling();
continue;
}
String elementName = n.getLocalName();
// Schema should require that no more than one each of these exist.
if ("trustDecider".equals(elementName)) {
mapBeanOrClassElement((Element)n, bean, MessageTrustDecider.class);
} else if ("authSupplier".equals(elementName)) {
mapBeanOrClassElement((Element)n, bean, HttpAuthSupplier.class);
} else if ("basicAuthSupplier".equals(elementName)) {
mapBeanOrClassElement((Element)n, bean, HttpAuthSupplier.class);
} else if ("tlsClientParameters".equals(elementName)) {
mapTLSClientParameters((Element)n, bean);
}
n = n.getNextSibling();
}
}
/**
* Inject the "setTlsClientParameters" method with
* a TLSClientParametersConfig object initialized with the JAXB
* generated type unmarshalled from the selected node.
*/
@SuppressWarnings("deprecation")
public void mapTLSClientParameters(Element e, BeanDefinitionBuilder bean) {
BeanDefinitionBuilder paramsbean
= BeanDefinitionBuilder.rootBeanDefinition(TLSClientParametersConfig.TLSClientParametersTypeInternal.class);
// read the attributes
NamedNodeMap as = e.getAttributes();
for (int i = 0; i < as.getLength(); i++) {
Attr a = (Attr) as.item(i);
if (a.getNamespaceURI() == null) {
String aname = a.getLocalName();
if ("useHttpsURLConnectionDefaultSslSocketFactory".equals(aname)
|| "useHttpsURLConnectionDefaultHostnameVerifier".equals(aname)
|| "disableCNCheck".equals(aname)
|| "jsseProvider".equals(aname)
|| "secureSocketProtocol".equals(aname)
|| "sslCacheTimeout".equals(aname)) {
paramsbean.addPropertyValue(aname, a.getValue());
}
}
}
// read the child elements
Node n = e.getFirstChild();
while (n != null) {
if (Node.ELEMENT_NODE != n.getNodeType()
|| !SECURITY_NS.equals(n.getNamespaceURI())) {
n = n.getNextSibling();
continue;
}
String ename = n.getLocalName();
// Schema should require that no more than one each of these exist.
String ref = ((Element)n).getAttribute("ref");
if ("keyManagers".equals(ename)) {
if (ref != null && ref.length() > 0) {
paramsbean.addPropertyReference("keyManagersRef", ref);
} else {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
KeyManagersType.class);
}
} else if ("trustManagers".equals(ename)) {
if (ref != null && ref.length() > 0) {
paramsbean.addPropertyReference("trustManagersRef", ref);
} else {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
TrustManagersType.class);
}
} else if ("cipherSuites".equals(ename)) {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
CipherSuites.class);
} else if ("cipherSuitesFilter".equals(ename)) {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
FiltersType.class);
} else if ("secureRandomParameters".equals(ename)) {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
SecureRandomParameters.class);
} else if ("certConstraints".equals(ename)) {
mapElementToJaxbProperty((Element)n, paramsbean, ename,
CertificateConstraintsType.class);
} else if ("certAlias".equals(ename)) {
paramsbean.addPropertyValue(ename, n.getTextContent());
}
n = n.getNextSibling();
}
BeanDefinitionBuilder jaxbbean
= BeanDefinitionBuilder.rootBeanDefinition(TLSClientParametersConfig.class);
jaxbbean.getRawBeanDefinition().setFactoryMethodName("createTLSClientParametersFromType");
jaxbbean.addConstructorArg(paramsbean.getBeanDefinition());
bean.addPropertyValue("tlsClientParameters", jaxbbean.getBeanDefinition());
}
/**
* This method finds the class or bean associated with the named element
* and sets the bean property that is associated with the same name as
* the element.
*
* The element has either a "class" attribute or "bean" attribute, but
* not both.
*
* @param element The element.
* @param bean The Bean Definition Parser.
* @param elementClass The Class a bean or class is supposed to be.
*/
protected void mapBeanOrClassElement(
Element element,
BeanDefinitionBuilder bean,
Class elementClass
) {
String elementName = element.getLocalName();
String classProperty = element.getAttribute("class");
if (classProperty != null && !classProperty.equals("")) {
try {
Object obj =
ClassLoaderUtils.loadClass(
classProperty, getClass()).newInstance();
if (!elementClass.isInstance(obj)) {
throw new IllegalArgumentException(
"Element '" + elementName + "' must be of type "
+ elementClass.getName() + ".");
}
bean.addPropertyValue(elementName, obj);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException(
"Element '" + elementName + "' could not load "
+ classProperty
+ " - " + ex);
} catch (ClassNotFoundException ex) {
throw new IllegalArgumentException(
"Element '" + elementName + "' could not load "
+ classProperty
+ " - " + ex);
} catch (InstantiationException ex) {
throw new IllegalArgumentException(
"Element '" + elementName + "' could not load "
+ classProperty
+ " - " + ex);
}
}
String beanref = element.getAttribute("bean");
if (beanref != null && !beanref.equals("")) {
if (classProperty != null && !classProperty.equals("")) {
throw new IllegalArgumentException(
"Element '" + elementName + "' cannot have both "
+ "\"bean\" and \"class\" attributes.");
}
bean.addPropertyReference(elementName, beanref);
} else if (classProperty == null || classProperty.equals("")) {
throw new IllegalArgumentException(
"Element '" + elementName
+ "' requires at least one of the "
+ "\"bean\" or \"class\" attributes.");
}
}
@Override
protected Class getBeanClass(Element arg0) {
return HTTPConduit.class;
}
}