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.component.validator.jing; 018 019 import java.io.IOException; 020 import java.io.InputStream; 021 022 import javax.xml.XMLConstants; 023 import javax.xml.transform.Source; 024 import javax.xml.transform.sax.SAXSource; 025 026 import org.xml.sax.InputSource; 027 import org.xml.sax.SAXException; 028 import org.xml.sax.XMLReader; 029 030 import com.thaiopensource.relaxng.SchemaFactory; 031 import com.thaiopensource.util.PropertyMap; 032 import com.thaiopensource.util.PropertyMapBuilder; 033 import com.thaiopensource.validate.IncorrectSchemaException; 034 import com.thaiopensource.validate.Schema; 035 import com.thaiopensource.validate.ValidateProperty; 036 import com.thaiopensource.validate.Validator; 037 import com.thaiopensource.xml.sax.Jaxp11XMLReaderCreator; 038 039 import org.apache.camel.Exchange; 040 import org.apache.camel.Message; 041 import org.apache.camel.Processor; 042 import org.apache.camel.processor.validation.DefaultValidationErrorHandler; 043 import org.apache.camel.util.ExchangeHelper; 044 import org.apache.commons.logging.Log; 045 import org.apache.commons.logging.LogFactory; 046 047 import org.springframework.core.io.Resource; 048 049 /** 050 * A validator which uses the <a 051 * href="http://www.thaiopensource.com/relaxng/jing.html">Jing</a> library to 052 * validate XML against RelaxNG 053 * 054 * @version $Revision: 1.1 $ 055 */ 056 public class JingValidator implements Processor { 057 private static final transient Log LOG = LogFactory.getLog(JingValidator.class); 058 private Schema schema; 059 private SchemaFactory schemaFactory; 060 private String schemaNamespace = XMLConstants.RELAXNG_NS_URI; 061 private Resource schemaResource; 062 private InputSource inputSource; 063 private boolean compactSyntax; 064 065 public void process(Exchange exchange) throws Exception { 066 Jaxp11XMLReaderCreator xmlCreator = new Jaxp11XMLReaderCreator(); 067 DefaultValidationErrorHandler errorHandler = new DefaultValidationErrorHandler(); 068 069 PropertyMapBuilder mapBuilder = new PropertyMapBuilder(); 070 mapBuilder.put(ValidateProperty.XML_READER_CREATOR, xmlCreator); 071 mapBuilder.put(ValidateProperty.ERROR_HANDLER, errorHandler); 072 PropertyMap propertyMap = mapBuilder.toPropertyMap(); 073 074 Validator validator = getSchema().createValidator(propertyMap); 075 076 Message in = exchange.getIn(); 077 SAXSource saxSource = in.getBody(SAXSource.class); 078 if (saxSource == null) { 079 Source source = ExchangeHelper.getMandatoryInBody(exchange, Source.class); 080 saxSource = ExchangeHelper.convertToMandatoryType(exchange, SAXSource.class, source); 081 } 082 InputSource bodyInput = saxSource.getInputSource(); 083 084 // now lets parse the body using the validator 085 XMLReader reader = xmlCreator.createXMLReader(); 086 reader.setContentHandler(validator.getContentHandler()); 087 reader.setDTDHandler(validator.getDTDHandler()); 088 reader.setErrorHandler(errorHandler); 089 reader.parse(bodyInput); 090 091 errorHandler.handleErrors(exchange, schema); 092 } 093 094 // Properties 095 // ------------------------------------------------------------------------- 096 097 public Schema getSchema() throws IOException, IncorrectSchemaException, SAXException { 098 if (schema == null) { 099 SchemaFactory factory = getSchemaFactory(); 100 schema = factory.createSchema(getInputSource()); 101 } 102 return schema; 103 } 104 105 public void setSchema(Schema schema) { 106 this.schema = schema; 107 } 108 109 public InputSource getInputSource() throws IOException { 110 if (inputSource == null) { 111 Resource resource = getSchemaResource(); 112 if (resource == null) { 113 throw new IllegalArgumentException("No schemaResource or inputSource specified"); 114 } else { 115 InputStream inputStream = resource.getInputStream(); 116 if (inputStream == null) { 117 throw new IllegalArgumentException("No inputStream available for: " + resource); 118 } 119 inputSource = new InputSource(inputStream); 120 } 121 } 122 return inputSource; 123 } 124 125 public void setInputSource(InputSource inputSource) { 126 this.inputSource = inputSource; 127 } 128 129 public SchemaFactory getSchemaFactory() { 130 if (schemaFactory == null) { 131 schemaFactory = new SchemaFactory(); 132 schemaFactory.setCompactSyntax(compactSyntax); 133 schemaFactory.setXMLReaderCreator(new Jaxp11XMLReaderCreator()); 134 } 135 return schemaFactory; 136 } 137 138 public void setSchemaFactory(SchemaFactory schemaFactory) { 139 this.schemaFactory = schemaFactory; 140 } 141 142 public Resource getSchemaResource() { 143 return schemaResource; 144 } 145 146 public void setSchemaResource(Resource schemaResource) { 147 this.schemaResource = schemaResource; 148 } 149 150 public String getSchemaNamespace() { 151 return schemaNamespace; 152 } 153 154 public void setSchemaNamespace(String schemaNamespace) { 155 this.schemaNamespace = schemaNamespace; 156 } 157 158 public boolean isCompactSyntax() { 159 return compactSyntax; 160 } 161 162 public void setCompactSyntax(boolean compactSyntax) { 163 this.compactSyntax = compactSyntax; 164 } 165 }