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: 1020 $
041     */
042    public class ValidatingProcessor implements Processor {
043        // for lazy creation of the Schema
044        private String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI;
045        private Schema schema;
046        private Source schemaSource;
047        private SchemaFactory schemaFactory;
048        private URL schemaUrl;
049        private File schemaFile;
050        private ValidatorErrorHandler errorHandler = new DefaultValidationErrorHandler();
051    
052        public void process(Exchange exchange) throws Exception {
053            Schema schema = getSchema();
054            Validator validator = schema.newValidator();
055    
056            Source source = exchange.getIn().getBody(DOMSource.class);
057            if (source == null) {
058                throw new NoXmlBodyValidationException(exchange);
059            }
060    
061            // create a new errorHandler and set it on the validator
062            // must be a local instance to avoid problems with concurrency (to be thread safe)
063            ValidatorErrorHandler handler = errorHandler.getClass().newInstance();
064            validator.setErrorHandler(handler);
065    
066            DOMResult result = new DOMResult();
067            validator.validate(source, result);
068    
069            handler.handleErrors(exchange, schema, result);
070        }
071    
072        // Properties
073        // -----------------------------------------------------------------------
074    
075        public Schema getSchema() throws IOException, SAXException {
076            if (schema == null) {
077                schema = createSchema();
078            }
079            return schema;
080        }
081    
082        public void setSchema(Schema schema) {
083            this.schema = schema;
084        }
085    
086        public String getSchemaLanguage() {
087            return schemaLanguage;
088        }
089    
090        public void setSchemaLanguage(String schemaLanguage) {
091            this.schemaLanguage = schemaLanguage;
092        }
093    
094        public Source getSchemaSource() throws IOException {
095            if (schemaSource == null) {
096                schemaSource = createSchemaSource();
097            }
098            return schemaSource;
099        }
100    
101        public void setSchemaSource(Source schemaSource) {
102            this.schemaSource = schemaSource;
103        }
104    
105        public URL getSchemaUrl() {
106            return schemaUrl;
107        }
108    
109        public void setSchemaUrl(URL schemaUrl) {
110            this.schemaUrl = schemaUrl;
111        }
112    
113        public File getSchemaFile() {
114            return schemaFile;
115        }
116    
117        public void setSchemaFile(File schemaFile) {
118            this.schemaFile = schemaFile;
119        }
120    
121        public SchemaFactory getSchemaFactory() {
122            if (schemaFactory == null) {
123                schemaFactory = createSchemaFactory();
124            }
125            return schemaFactory;
126        }
127    
128        public void setSchemaFactory(SchemaFactory schemaFactory) {
129            this.schemaFactory = schemaFactory;
130        }
131    
132        public ValidatorErrorHandler getErrorHandler() {
133            return errorHandler;
134        }
135    
136        public void setErrorHandler(ValidatorErrorHandler errorHandler) {
137            this.errorHandler = errorHandler;
138        }
139    
140        // Implementation methods
141        // -----------------------------------------------------------------------
142    
143        protected SchemaFactory createSchemaFactory() {
144            return SchemaFactory.newInstance(schemaLanguage);
145        }
146    
147        protected Source createSchemaSource() throws IOException {
148            throw new IllegalArgumentException("You must specify a schema, "
149                                               + "schemaFile, schemaSource or schemaUrl property");
150        }
151    
152        protected Schema createSchema() throws SAXException, IOException {
153            SchemaFactory factory = getSchemaFactory();
154    
155            URL url = getSchemaUrl();
156            if (url != null) {
157                return factory.newSchema(url);
158            }
159            File file = getSchemaFile();
160            if (file != null) {
161                return factory.newSchema(file);
162            }
163            return factory.newSchema(getSchemaSource());
164        }
165    
166    }