Amila Suriarachchi wrote:


On Thu, Jun 10, 2010 at 1:40 AM, Jack Sprat <[email protected] <mailto:[email protected]>> wrote:

    Is there a simple way to perform schema validation when using
    ADB?  Examples would be quite helpful.
    I know this is simple with XMLBeans but have a service using ADB
    where I need to validate the inbound request.


ADB validates the incoming request while parsing the request.


Hi Amila,

Do you really mean that ADB validates the incoming request, or that it checks consistency with the ADB data model? Unless ADB actually turns on schema validation by the parser (which I very much doubt) it's not correct to say that it validates the request.

I did write a handler for this purpose a while ago. I haven't tried it out with the current code, but I'll attach the files to this email in case the gastrically-challenged questioner wants to give it a try.

 - Dennis

--
Dennis M. Sosnoski
Java XML and Web Services
Axis2 Training and Consulting
http://www.sosnoski.com - http://www.sosnoski.co.nz
Seattle, WA +1-425-939-0576 - Wellington, NZ +64-4-298-6117

<module name="validate" class="com.sosnoski.axis2.handler.ValidateModule">
  <Description>Schema validation module. In order to be used by a service, the
    service must include the module reference and also define a validationSchema
    parameter giving the URL of the schema definition.
  </Description>
  <InFlow>
    <handler name="ValidateHandler" class="com.sosnoski.axis2.handler.ValidateHandler">
      <order phase="PreDispatch"/>
    </handler>
  </InFlow>
  <OutFlow>
    <handler name="ValidateHandler" class="com.sosnoski.axis2.handler.ValidateHandler">
      <order phase="MessageOut"/>
    </handler>
  </OutFlow>
</module>
package com.sosnoski.axis2.handler;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * Schema validation handler. This checks each message against the schema
 * configured by the service for the validation module. Results are logged with
 * the service information.
 */
public class ValidateHandler extends AbstractHandler implements Handler
{
    /** Logger for this handler. */
    private static final Log s_log;
    static {
        s_log = LogFactory.getLog(ValidateHandler.class);
    }
    
    /** Map of loaded schemas. */
    private static final Map s_schemaMap = new HashMap();
    
    /**
     * Invoke processing handles the actual validation.
     * 
     * @param ctx 
     * @return response
     */
    public InvocationResponse invoke(MessageContext ctx) {
        
        // make sure a schema has been provided
        AxisService srvc = ctx.getAxisService();
        Parameter parm = srvc.getParameter("validationSchema");
        String name = ctx.getAxisService().getName();
        if (parm == null) {
            s_log.error("ValidationModule engaged for service " +
                 name + " without required 'validationSchema' parameter");
        } else {
            String path = (String)parm.getValue();
            try {
                
                // get the (hopefully cached) schema information
                Schema schema;
                synchronized (s_schemaMap) {
                    schema = (Schema)s_schemaMap.get(path);
                    if (schema == null) {
                        SchemaFactory factory =
                            SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                        URL url = new URL(path);
                        schema = factory.newSchema(new StreamSource(url.openStream(), path));
                        s_schemaMap.put(path, schema);
                    }
                }

                // get the body content element
                Iterator iter = ctx.getEnvelope().getBody().getChildElements();
                OMElement content = null;
                while (iter.hasNext()) {
                    OMNode node = (OMNode)iter.next();
                    if (node.getType() == OMNode.ELEMENT_NODE) {
                        content = (OMElement)node;
                        break;
                    }
                }
                if (content != null) {
                    
                    // serialize element as text
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    content.build();
                    content.serialize(baos);
                    byte[] bytes = baos.toByteArray();
                    
                    // validate the content element against the schema
                    Validator validator = schema.newValidator();
                    ValidationErrorHandler handler = new ValidationErrorHandler(name);
                    validator.setErrorHandler(handler);
                    validator.validate(new SAXSource(new InputSource(new ByteArrayInputStream(bytes))));
                    if (handler.hasError()) {
                        s_log.error("Document text:\n" + new String(bytes, "UTF-8"));
                    } else if (handler.hasWarning()) {
                        s_log.info("Document text:\n" + new String(bytes, "UTF-8"));
                    } else {
                        s_log.info("Successfully validated '" + content.getLocalName() + "' body element for service " + name);
                        if (s_log.isDebugEnabled()) {
                            s_log.debug("Document text:\n" + new String(bytes, "UTF-8"));
                        }
                    }
                    
                }
                
            } catch (Exception e) {
                s_log.error("Error in validation configuration for service " + name, e);
            }
        }
        return InvocationResponse.CONTINUE;
    }
    
    private static class ValidationErrorHandler implements ErrorHandler
    {
        private final String m_serviceName;
        private boolean m_hasError;
        private boolean m_hasWarning;
        
        public ValidationErrorHandler(String name) {
            m_serviceName = name;
        }
        
        public void error(SAXParseException e) throws SAXException {
            s_log.error("Error validating message for service " + m_serviceName + ": " + e.getMessage());
            m_hasError = true;
        }

        public void fatalError(SAXParseException e) throws SAXException {
            s_log.error("Fatal error validating message for service " + m_serviceName + ": " + e.getMessage());
            m_hasError = true;
        }

        public void warning(SAXParseException e) throws SAXException {
            s_log.info("Warning validating message for service " + m_serviceName + ": " + e.getMessage());
            m_hasWarning = true;
        }

        public boolean hasError() {
            return m_hasError;
        }

        public boolean hasWarning() {
            return m_hasWarning;
        }
    }
}
package com.sosnoski.axis2.handler;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.modules.Module;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;

public class ValidateModule implements Module
{

    public void applyPolicy(Policy arg0, AxisDescription arg1) throws AxisFault {
    }

    public boolean canSupportAssertion(Assertion arg0) {
        return false;
    }

    public void engageNotify(AxisDescription arg0) throws AxisFault {
    }

    public void init(ConfigurationContext arg0, AxisModule arg1)
        throws AxisFault {
    }

    public void shutdown(ConfigurationContext arg0) throws AxisFault {
    }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to