001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.camel.processor.validation; 018 019 import java.io.File; 020 import java.io.IOException; 021 import java.net.URL; 022 023 import javax.xml.XMLConstants; 024 import javax.xml.transform.Source; 025 import javax.xml.transform.dom.DOMResult; 026 import javax.xml.transform.dom.DOMSource; 027 import javax.xml.validation.Schema; 028 import javax.xml.validation.SchemaFactory; 029 import javax.xml.validation.Validator; 030 031 import org.xml.sax.SAXException; 032 033 import org.apache.camel.Exchange; 034 import org.apache.camel.Processor; 035 036 /** 037 * A processor which validates the XML version of the inbound message body 038 * against some schema either in XSD or RelaxNG 039 * 040 * @version $Revision: 35332 $ 041 */ 042 public class ValidatingProcessor implements Processor { 043 private Schema schema; 044 private ValidatorErrorHandler errorHandler = new DefaultValidationErrorHandler(); 045 046 // for lazy creation of the Schema 047 private String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI; 048 private Source schemaSource; 049 private SchemaFactory schemaFactory; 050 private URL schemaUrl; 051 private File schemaFile; 052 053 public void process(Exchange exchange) throws Exception { 054 Schema schema = getSchema(); 055 Validator validator = schema.newValidator(); 056 057 Source source = exchange.getIn().getBody(DOMSource.class); 058 if (source == null) { 059 throw new NoXmlBodyValidationException(exchange); 060 } 061 062 // create a new errorHandler and set it on the validator 063 errorHandler.reset(); 064 validator.setErrorHandler(errorHandler); 065 066 DOMResult result = new DOMResult(); 067 validator.validate(source, result); 068 069 errorHandler.handleErrors(exchange, schema, result); 070 /* 071 * Fault fault = exchange.createFault(); if (errorHandler.hasErrors()) { // 072 * set the schema and source document as properties on the fault 073 * fault.setProperty("org.apache.servicemix.schema", schema); 074 * fault.setProperty("org.apache.servicemix.xml", source); 075 * 076 *//* 077 * check if this error handler supports the capturing of error 078 * messages. 079 *//* 080 * if (errorHandler.capturesMessages()) { 081 * 082 *//* 083 * In descending order of preference select a format to use. If 084 * neither DOMSource, StringSource or String are supported throw a 085 * messaging exception. 086 *//* 087 * if (errorHandler.supportsMessageFormat(DOMSource.class)) { 088 * fault.setContent( (DOMSource) 089 * errorHandler.getMessagesAs(DOMSource.class)); } else if 090 * (errorHandler.supportsMessageFormat(StringSource.class)) { 091 * fault.setContent(sourceTransformer.toDOMSource( (StringSource) 092 * errorHandler.getMessagesAs(StringSource.class))); } else if 093 * (errorHandler.supportsMessageFormat(String.class)) { 094 * fault.setContent( sourceTransformer.toDOMSource( new 095 * StringSource( (String) 096 * errorHandler.getMessagesAs(String.class)))); } else { throw new 097 * MessagingException("MessageAwareErrorHandler implementation " + 098 * errorHandler.getClass().getName() + " does not support a 099 * compatible error message format."); } } else { 100 *//* 101 * we can't do much here if the ErrorHandler implementation does not 102 * support capturing messages 103 *//* 104 * fault.setContent(new DOMSource(result.getNode(), 105 * result.getSystemId())); } throw new FaultException("Failed to 106 * validate against schema: " + schema, exchange, fault); } else { // 107 * Retrieve the ouput of the validation // as it may have been 108 * changed by the validator out.setContent(new 109 * DOMSource(result.getNode(), result.getSystemId())); } } 110 */ 111 } 112 113 // Properties 114 // ----------------------------------------------------------------------- 115 116 public Schema getSchema() throws IOException, SAXException { 117 if (schema == null) { 118 schema = createSchema(); 119 } 120 return schema; 121 } 122 123 public void setSchema(Schema schema) { 124 this.schema = schema; 125 } 126 127 public String getSchemaLanguage() { 128 return schemaLanguage; 129 } 130 131 public void setSchemaLanguage(String schemaLanguage) { 132 this.schemaLanguage = schemaLanguage; 133 } 134 135 public Source getSchemaSource() throws IOException { 136 if (schemaSource == null) { 137 schemaSource = createSchemaSource(); 138 } 139 return schemaSource; 140 } 141 142 public void setSchemaSource(Source schemaSource) { 143 this.schemaSource = schemaSource; 144 } 145 146 public URL getSchemaUrl() { 147 return schemaUrl; 148 } 149 150 public void setSchemaUrl(URL schemaUrl) { 151 this.schemaUrl = schemaUrl; 152 } 153 154 public File getSchemaFile() { 155 return schemaFile; 156 } 157 158 public void setSchemaFile(File schemaFile) { 159 this.schemaFile = schemaFile; 160 } 161 162 public SchemaFactory getSchemaFactory() { 163 if (schemaFactory == null) { 164 schemaFactory = createSchemaFactory(); 165 } 166 return schemaFactory; 167 } 168 169 public void setSchemaFactory(SchemaFactory schemaFactory) { 170 this.schemaFactory = schemaFactory; 171 } 172 173 public ValidatorErrorHandler getErrorHandler() { 174 return errorHandler; 175 } 176 177 public void setErrorHandler(ValidatorErrorHandler errorHandler) { 178 this.errorHandler = errorHandler; 179 } 180 181 // Implementation methods 182 // ----------------------------------------------------------------------- 183 184 protected SchemaFactory createSchemaFactory() { 185 return SchemaFactory.newInstance(schemaLanguage); 186 } 187 188 protected Source createSchemaSource() throws IOException { 189 throw new IllegalArgumentException("You must specify a schema, " 190 + "schemaFile, schemaSource or schemaUrl property"); 191 } 192 193 protected Schema createSchema() throws SAXException, IOException { 194 SchemaFactory factory = getSchemaFactory(); 195 196 URL url = getSchemaUrl(); 197 if (url != null) { 198 return factory.newSchema(url); 199 } 200 File file = getSchemaFile(); 201 if (file != null) { 202 return factory.newSchema(file); 203 } 204 return factory.newSchema(getSchemaSource()); 205 } 206 207 }