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: 630591 $
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 }