All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.predic8.membrane.core.interceptor.schemavalidation.ValidatorInterceptor Maven / Gradle / Ivy

There is a newer version: 5.6.0
Show newest version
/* Copyright 2011, 2012 predic8 GmbH, www.predic8.com

   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 com.predic8.membrane.core.interceptor.schemavalidation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.predic8.membrane.annot.MCAttribute;
import com.predic8.membrane.annot.MCElement;
import com.predic8.membrane.core.Router;
import com.predic8.membrane.core.exchange.Exchange;
import com.predic8.membrane.core.interceptor.AbstractInterceptor;
import com.predic8.membrane.core.interceptor.Outcome;
import com.predic8.membrane.core.resolver.ResolverMap;
import com.predic8.membrane.core.rules.Rule;
import com.predic8.membrane.core.rules.SOAPProxy;
import com.predic8.membrane.core.util.TextUtil;

/**
 * Basically switches over {@link WSDLValidator}, {@link XMLSchemaValidator},
 * {@link JSONValidator} and {@link SchematronValidator} depending on the
 * attributes.
 * @topic 8. SOAP based Web Services
 */
@MCElement(name="validator")
public class ValidatorInterceptor extends AbstractInterceptor implements ApplicationContextAware {
	private static Logger log = LoggerFactory.getLogger(ValidatorInterceptor.class.getName());

	private String wsdl;
	private String schema;
	private String jsonSchema;
	private String schematron;
	private String failureHandler;
	private boolean skipFaults;

	private IValidator validator;
	private ResolverMap resourceResolver;
	private ApplicationContext applicationContext;

	private void setValidator(IValidator validator) throws Exception {
		if (this.validator != null)
			throw new Exception(" cannot have more than one validator attribute.");
		this.validator = validator;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	public void init() throws Exception {
		validator = null;

		String baseLocation = router == null ? null : router.getBaseLocation();

		if (wsdl != null) {
			name="SOAP Validator";
			setValidator(new WSDLValidator(resourceResolver, ResolverMap.combine(baseLocation, wsdl), createFailureHandler(), skipFaults));
		}
		if (schema != null) {
			name="XML Schema Validator";
			setValidator(new XMLSchemaValidator(resourceResolver, ResolverMap.combine(baseLocation, schema), createFailureHandler()));
		}
		if (jsonSchema != null) {
			name="JSON Schema Validator";
			setValidator(new JSONValidator(resourceResolver, ResolverMap.combine(baseLocation, jsonSchema), createFailureHandler()));
		}
		if (schematron != null) {
			name="Schematron Validator";
			setValidator(new SchematronValidator(resourceResolver, ResolverMap.combine(baseLocation, schematron), createFailureHandler(), router, applicationContext));
		}

		if (validator == null) {
			Rule parent = router.getParentProxy(this);
			if (parent instanceof SOAPProxy) {
				wsdl = ((SOAPProxy)parent).getWsdl();
				name = "SOAP Validator";
				setValidator(new WSDLValidator(resourceResolver, ResolverMap.combine(baseLocation, wsdl), createFailureHandler(), skipFaults));
			}
			if (validator == null)
				throw new Exception(" must have an attribute specifying the validator.");
		}

		if (skipFaults && wsdl == null)
			throw new Exception("validator/@skipFaults only makes sense with validator/@wsdl");
	}

	@Override
	public Outcome handleRequest(Exchange exc) throws Exception {
		if (exc.getRequest().isBodyEmpty())
			return Outcome.CONTINUE;

		return validator.validateMessage(exc, exc.getRequest(), "request");
	}

	@Override
	public Outcome handleResponse(Exchange exc) throws Exception {
		if (exc.getResponse().isBodyEmpty())
			return Outcome.CONTINUE;

		return validator.validateMessage(exc, exc.getResponse(), "response");
	}

	/**
	 * @description The WSDL (URL or file) to validate against.
	 * @example http://predic8.com:8080/material/ArticleService?wsdl
	 */
	@MCAttribute
	public void setWsdl(String wsdl) {
		this.wsdl = wsdl;
	}

	public String getWsdl() {
		return wsdl;
	}

	public String getSchema() {
		return schema;
	}

	/**
	 * @description The XSD Schema (URL or file) to validate against.
	 * @example http://www.predic8.com/schemas/order.xsd
	 */
	@MCAttribute
	public void setSchema(String schema) {
		this.schema = schema;
	}

	public String getFailureHandler() {
		return failureHandler;
	}

	/**
	 * @description If "response", the HTTP response will include a detailled error message. If "log", the response will
	 *              be generic and the validation error will be logged.
	 * @default response
	 * @example log
	 */
	@MCAttribute
	public void setFailureHandler(String failureHandler) {
		this.failureHandler = failureHandler;
	}

	public String getJsonSchema() {
		return jsonSchema;
	}

	/**
	 * @description The JSON Schema (URL or file) to validate against.
	 * @example examples/validation/json-schema/schema2000.json
	 */
	@MCAttribute
	public void setJsonSchema(String jsonSchema) {
		this.jsonSchema = jsonSchema;
	}

	public String getSchematron() {
		return schematron;
	}

	/**
	 * @description The Schematron schema (URL or file) to validate against.
	 * @example examples/validation/schematron/car-schematron.xml
	 */
	@MCAttribute
	public void setSchematron(String schematron) {
		this.schematron = schematron;
	}

	public boolean isSkipFaults() {
		return skipFaults;
	}

	/**
	 * @description Whether to skip validation for SOAP fault messages.
	 * @default false
	 */
	@MCAttribute
	public void setSkipFaults(boolean skipFaults) {
		this.skipFaults = skipFaults;
	}

	@Override
	public void init(Router router) throws Exception {
		resourceResolver = router.getResolverMap();
		super.init(router);
	}

	public void setResourceResolver(ResolverMap resourceResolver) {
		this.resourceResolver = resourceResolver;
	}

	@Override
	public String getShortDescription() {
		return validator.getInvalid() + " of " + (validator.getValid() + validator.getInvalid()) + " messages have been invalid.";
	}

	@Override
	public String getLongDescription() {
		StringBuilder sb = new StringBuilder(getShortDescription());
		sb.deleteCharAt(sb.length()-1);
		sb.append(" according to ");
		if (wsdl != null) {
			sb.append("the WSDL at 
"); sb.append(TextUtil.linkURL(wsdl)); } if (schema != null) { sb.append("the XML Schema at
"); sb.append(TextUtil.linkURL(schema)); } if (jsonSchema != null) { sb.append("the JSON Schema at
"); sb.append(TextUtil.linkURL(jsonSchema)); } if (schematron != null) { sb.append("the Schematron at
"); sb.append(TextUtil.linkURL(schematron)); } sb.append(" ."); return sb.toString(); } public static interface FailureHandler { public static final FailureHandler VOID = new FailureHandler(){ @Override public void handleFailure(String message, Exchange exc) { }}; void handleFailure(String message, Exchange exc); } private FailureHandler createFailureHandler() { if (failureHandler == null || failureHandler.equals("response")) return null; if (failureHandler.equals("log")) return new FailureHandler() { @Override public void handleFailure(String message, Exchange exc) { log.info("Validation failure: " + message); } }; throw new IllegalArgumentException("Unknown failureHandler type: " + failureHandler); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy