I'm trying to use a spring ws source code and spring xml api to create an xfire 
handler to validate xml payload like spring xs, with xds file param, and 
returned xfirefault.
Now I have a code like this:


import java.io.IOException;
import java.util.Locale;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.exchange.InMessage;
import org.codehaus.xfire.exchange.OutMessage;
import org.codehaus.xfire.fault.XFireFault;
import org.codehaus.xfire.handler.AbstractHandler;
import org.codehaus.xfire.handler.Phase;
import org.codehaus.xfire.soap.handler.ReadHeadersHandler;
import org.codehaus.xfire.util.jdom.StaxBuilder;
import org.codehaus.xfire.util.stax.JDOMStreamReader;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.transform.JDOMSource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.xml.namespace.QNameUtils;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * @author hamdi_makni
 * @since V18
 */
public class PayloadValidator extends AbstractHandler {

        /**
         * log user by this class
         */
        protected final Log log = LogFactory.getLog(getClass());

        /**
         * Default SOAP Fault Detail name used when a validation errors occur 
on the
         * request.
         * 
         * @see #setDetailElementName(javax.xml.namespace.QName)
         */
        public static final QName DEFAULT_DETAIL_ELEMENT_NAME = QNameUtils
                        .createQName("http://springframework.org/spring-ws";,
                                        "ValidationError", "spring-ws");

        /**
         * Default SOAP Fault string used when a validation errors occur on the
         * request.
         * 
         * @see #setFaultStringOrReason(String)
         */
        public static final String DEFAULT_FAULTSTRING_OR_REASON = "Validation 
error";

        /**
         * addValidationErrorDetail
         */
        private boolean addValidationErrorDetail = true;

        /**
         * detailElementName
         */
        private QName detailElementName = DEFAULT_DETAIL_ELEMENT_NAME;

        /**
         * faultStringOrReason
         */
        private String faultStringOrReason = DEFAULT_FAULTSTRING_OR_REASON;

        /**
         * faultStringOrReasonLocale
         */
        private Locale faultStringOrReasonLocale = Locale.ENGLISH;

        /**
         * schemaLanguage
         */
        private String schemaLanguage = XmlValidatorFactory.SCHEMA_W3C_XML;

        /**
         * schemas
         */
        private Resource[] schemas;

        /**
         * validateRequest
         */
        private boolean validateRequest = true;

        /**
         * validateResponse
         */
        private boolean validateResponse = false;

        /**
         * validator
         */
        private XmlValidator validator;

        /**
         * document
         */
        protected Document doc;

        /**
         * constructeur sans param utilisé par SpringIOC
         * 
         * @throws Exception
         *             Exception
         */
        public PayloadValidator() throws Exception {
                super();
                setPhase(Phase.PARSE);
                before(ReadHeadersHandler.class.getName());

                System
                                .setProperty(
                                                
"javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema";,
                                                
"org.apache.xerces.jaxp.validation.XMLSchemaFactory");

        }

        public String getSchemaLanguage() {
                return schemaLanguage;
        }

        /**
         * Sets the schema language. Default is the W3C XML Schema:
         * <code>http://www.w3.org/2001/XMLSchema";</code>.
         * 
         * @see 
org.springframework.xml.validation.XmlValidatorFactory#SCHEMA_W3C_XML
         * @see 
org.springframework.xml.validation.XmlValidatorFactory#SCHEMA_RELAX_NG
         * @param schemaLanguage
         *            schemaLanguage
         */
        public void setSchemaLanguage(String schemaLanguage) {
                this.schemaLanguage = schemaLanguage;
        }

        /**
         * Returns the schema resources to use for validation.
         * 
         * @return schemas
         */
        public Resource[] getSchemas() {
                return schemas;
        }

        /**
         * Sets the schema resources to use for validation. Setting either this
         * property or <code>schema</code> is required.
         * 
         * @param schemas
         *            schemas
         */
        public void setSchemas(Resource[] schemas) {
                Assert.notEmpty(schemas, "schemas must not be empty or null");
                for (int i = 0; i < schemas.length; i++) {
                        Assert.notNull(schemas[i], "schema must not be null");
                        Assert.isTrue(schemas[i].exists(), "schema \"" + 
schemas[i]
                                        + "\" does not exit");
                }
                this.schemas = schemas;
        }

        /**
         * Sets the schema resource to use for validation. Setting either this
         * property or <code>schemas</code> is required.
         * 
         * @param schema
         *            schema
         */
        public void setSchema(Resource schema) {
                setSchemas(new Resource[] { schema });
        }

        /**
         * Indicates whether the request should be validated against the schema.
         * Default is <code>true</code>.
         * 
         * @param validateRequest
         *            validateRequest
         */
        public void setValidateRequest(boolean validateRequest) {
                this.validateRequest = validateRequest;
        }

        /**
         * Indicates whether the response should be validated against the 
schema.
         * Default is <code>false</code>.
         * 
         * @param validateResponse
         *            validateResponse
         */
        public void setValidateResponse(boolean validateResponse) {
                this.validateResponse = validateResponse;
        }

        /**
         * Validates the request message in the given message context. 
Validation
         * only occurs if <code>validateRequest</code> is set to 
<code>true</code>,
         * which is the default. <p/> Returns <code>true</code> if the request 
is
         * valid, or <code>false</code> if it isn't. Additionally, when the
         * <code>messageContext</code> is a <code>SoapMessageContext</code>, a
         * SOAP Fault is added as response.
         * 
         * @param messageContext
         *            the message context
         * @return <code>true</code> if the message is valid; <code>false</code>
         *         otherwise
         * @throws XMLStreamException
         *             XMLStreamException
         * @throws IOException
         *             IOException
         * @throws SAXException
         *             SAXException
         * @throws TransformerException
         *             TransformerException
         * @throws XFireFault XFireFault
         * @see #setValidateRequest(boolean)
         */
        public boolean handleRequest(MessageContext messageContext)
                        throws IOException, SAXException, TransformerException,
                        XMLStreamException, XFireFault {
                if (validateRequest) {
                        Source requestSource = 
getValidationRequestSource(messageContext);
                        if (requestSource != null) {
                                SAXParseException[] errors = 
validator.validate(requestSource);
                                if (!ObjectUtils.isEmpty(errors)) {
                                        return 
handleRequestValidationErrors(messageContext, errors);
                                } else if (log.isDebugEnabled()) {
                                        log.debug("Request message validated");
                                }
                        }
                }
                return true;
        }

        /**
         * Validates the response message in the given message context. 
Validation
         * only occurs if <code>validateResponse</code> is set to
         * <code>true</code>, which is <strong>not</strong> the default. <p/>
         * Returns <code>true</code> if the request is valid, or
         * <code>false</code> if it isn't.
         * 
         * @param messageContext
         *            the message context.
         * @return <code>true</code> if the response is valid; 
<code>false</code>
         *         otherwise
         * @throws IOException
         *             IOException
         * @throws SAXException
         *             SAXException
         * @see #setValidateResponse(boolean)
         */
        public boolean handleResponse(MessageContext messageContext)
                        throws IOException, SAXException {
                if (validateResponse) {
                        Source responseSource = 
getValidationResponseSource(messageContext);
                        if (responseSource != null) {
                                SAXParseException[] errors = 
validator.validate(responseSource);
                                if (!ObjectUtils.isEmpty(errors)) {
                                        return 
handleResponseValidationErrors(messageContext,
                                                        errors);
                                } else if (log.isDebugEnabled()) {
                                        log.debug("Response message validated");
                                }
                        }
                }
                return true;
        }

        /**
         * Template method that is called when the response message contains
         * validation errors. Default implementation logs all errors, and 
returns
         * <code>false</code>, i.e. do not send the response.
         * 
         * @param messageContext
         *            the message context
         * @param errors
         *            the validation errors
         * @return <code>true</code> to continue sending the response,
         *         <code>false</code> (the default) otherwise
         */
        protected boolean handleResponseValidationErrors(
                        MessageContext messageContext, SAXParseException[] 
errors) {
                for (int i = 0; i < errors.length; i++) {
                        log.error("XML validation error on response: "
                                        + errors[i].getMessage());
                }
                return false;
        }

        /**
         * afterPropertiesSet
         * 
         * @throws Exception
         *             Exception
         */
        public void afterPropertiesSet() throws Exception {
                Assert.notEmpty(schemas,
                                "setting either the schema or schemas property 
is required");
                Assert.hasLength(schemaLanguage, "schemaLanguage is required");
                for (int i = 0; i < schemas.length; i++) {
                        Assert.isTrue(schemas[i].exists(), "schema [" + 
schemas[i]
                                        + "] does not exist");
                }
                if (log.isInfoEnabled()) {
                        log.info("Validating using "
                                        + 
StringUtils.arrayToCommaDelimitedString(schemas));
                }
                validator = XmlValidatorFactory
                                .createValidator(schemas, schemaLanguage);
        }

        /**
         * Returns whether a SOAP Fault detail element should be created when a
         * validation error occurs. This detail element will contain the exact
         * validation errors. It is only added when the underlying message is a
         * <code>SoapMessage</code>. Defaults to <code>true</code>.
         * 
         * @see org.springframework.ws.soap.SoapFault#addFaultDetail()
         * @return addValidationErrorDetail
         */
        public boolean getAddValidationErrorDetail() {
                return addValidationErrorDetail;
        }

        /**
         * Indicates whether a SOAP Fault detail element should be created when 
a
         * validation error occurs. This detail element will contain the exact
         * validation errors. It is only added when the underlying message is a
         * <code>SoapMessage</code>. Defaults to <code>true</code>.
         * 
         * @param addValidationErrorDetail
         *            addValidationErrorDetail
         * @see org.springframework.ws.soap.SoapFault#addFaultDetail()
         */
        public void setAddValidationErrorDetail(boolean 
addValidationErrorDetail) {
                this.addValidationErrorDetail = addValidationErrorDetail;
        }

        /**
         * Returns the fault detail element name when validation errors occur 
on the
         * request.
         * 
         * @return detailElementName
         */
        public QName getDetailElementName() {
                return detailElementName;
        }

        /**
         * Sets the fault detail element name when validation errors occur on 
the
         * request. Defaults to <code>DEFAULT_DETAIL_ELEMENT_NAME</code>.
         * 
         * @param detailElementName
         *            detailElementName
         * @see #DEFAULT_DETAIL_ELEMENT_NAME
         */
        public void setDetailElementName(QName detailElementName) {
                this.detailElementName = detailElementName;
        }

        /**
         * Sets the SOAP <code>faultstring</code> or <code>Reason</code> used
         * when validation errors occur on the request.
         * 
         * @return faultStringOrReason
         */
        public String getFaultStringOrReason() {
                return faultStringOrReason;
        }

        /**
         * Sets the SOAP <code>faultstring</code> or <code>Reason</code> used
         * when validation errors occur on the request. It is only added when 
the
         * underlying message is a <code>SoapMessage</code>. Defaults to
         * <code>DEFAULT_FAULTSTRING_OR_REASON</code>.
         * 
         * @param faultStringOrReason
         *            faultStringOrReason
         * @see #DEFAULT_FAULTSTRING_OR_REASON
         */
        public void setFaultStringOrReason(String faultStringOrReason) {
                this.faultStringOrReason = faultStringOrReason;
        }

        /**
         * Returns the SOAP fault reason locale used when validation errors 
occur on
         * the request.
         * 
         * @return faultStringOrReasonLocale
         */
        public Locale getFaultStringOrReasonLocale() {
                return faultStringOrReasonLocale;
        }

        /**
         * Sets the SOAP fault reason locale used when validation errors occur 
on
         * the request. It is only added when the underlying message is a
         * <code>SoapMessage</code>. Defaults to English.
         * 
         * @param faultStringOrReasonLocale
         *            faultStringOrReasonLocale
         * @see java.util.Locale#ENGLISH
         */
        public void setFaultStringOrReasonLocale(Locale 
faultStringOrReasonLocale) {
                this.faultStringOrReasonLocale = faultStringOrReasonLocale;
        }

        protected boolean handleRequestValidationErrors(
                        MessageContext messageContext, SAXParseException[] 
errors)
                        throws TransformerException, XFireFault {
                for (int i = 0; i < errors.length; i++) {
                        log.warn("XML validation error on request: "
                                        + errors[i].getMessage());
                }
                
                
                throw new XFireFault("Error Validation payload. 
"+errors[0].getMessage(), errors[0], XFireFault.SENDER);

        }

        /**
         * Returns the payload source of the given message.
         * 
         * @throws XMLStreamException
         *             zz
         */
        protected Source getValidationRequestSource(MessageContext request)
                        throws XMLStreamException {

                InMessage message = request.getInMessage();

                XMLStreamReader streamReader = message.getXMLStreamReader();
                log.debug("streamReader " + streamReader);

                StaxBuilder builder = new StaxBuilder();
                log.debug("builder " + builder);

                doc = builder.build(streamReader);

                log.debug("doc " + doc);
                log.debug("documentRoot: " + doc.getRootElement());
                log.debug("First children of documentRoot: "
                                + ((Element) 
doc.getRootElement().getChildren().get(0))
                                                .getName());
                Element body = (Element) 
doc.getRootElement().getChildren().get(1);
                log.debug("Second children of documentRoot: " + body.getName());

                Element payload = (Element) body.getChildren().get(0);

                return new JDOMSource(payload);
        }

        /**
         * Returns the payload source of the given message.
         */
        protected Source getValidationResponseSource(MessageContext response) {

                OutMessage message = response.getOutMessage();
                
                return null;
        }

        /**
         * [EMAIL PROTECTED]
         */
        public void invoke(MessageContext messageContext) throws Exception {
                log.debug("Begin validation");
                afterPropertiesSet();
                if (handleRequest(messageContext))
                        log.debug("Validation of requested payload finished by 
SUCESS");
                else
                        log.debug("Validation of requested payload finished by 
FAULT");
                messageContext.getInMessage().setXMLStreamReader(
                                new JDOMStreamReader(doc));

        }

}

And a config file like:
        <bean ...>      
                ....
                <property name="inHandlers">
                        <list>
                                <ref local="maqValidationHandler"/>
                        </list>
                </property>
        </bean>

        <bean id="maqValidationHandler"
                class="com.xxx.mobile.ws.validation.PayloadValidator">
                <property name="schema" value="maq.xsd" />
                <property name="validateRequest" value="true" />
                <property name="validateResponse" value="false" />
                <property name="addValidationErrorDetail" value="true" />
        </bean>
I'll do some modifications, there are some undesired code till now.

-----Message d'origine-----
De : Tomek Sztelak [mailto:[EMAIL PROTECTED] 
Envoyé : vendredi 20 avril 2007 15:45
À : [email protected]
Objet : Re: [xfire-user] How can I make validation for my payload?

Hi
When do you plan to finish this ? Maybe me could add support for your
framework to XFire distro.

On 4/20/07, Henning Jensen <[EMAIL PROTECTED]> wrote:
> Makni Hamdi wrote:
> > Hello,
> >
> >
> >
> > I'm using Xfire1.2.4, aegis, Spring 2 with java 1.4, and I want to make
> > validation for my payload.
> >
> > How can I do it? What framework should I use?
>
> Hi!
>
> I'm working on a framework that does exactly what you are asking for.
> With the framework you can define validation rules in a xml file and
> just add a handler to your service definitions.
>
> This work is part of a master thesis and you can find the project on:
>
> http://henning.fjas.no/ws-validator
>
> Not to much documentation yet, but a simple example and a download link
> is provided. The project uses Maven 2 and you can build it with mvn
> package to get jar files to put in your own project.
>
> --
> Henning Jensen
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>


-- 
-----
When one of our products stops working, we'll blame another vendor
within 24 hours.

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply via email to