org.switchyard.validate.xml.internal.XmlValidator Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
*
* 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 org.switchyard.validate.xml.internal;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.jboss.logging.Logger;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;
import org.switchyard.Message;
import org.switchyard.SwitchYardException;
import org.switchyard.common.type.Classes;
import org.switchyard.config.model.Scannable;
import org.switchyard.validate.BaseValidator;
import org.switchyard.validate.ValidationResult;
import org.switchyard.validate.config.model.FileEntryModel;
import org.switchyard.validate.config.model.XmlSchemaType;
import org.switchyard.validate.config.model.XmlValidateModel;
import org.switchyard.validate.internal.ValidateLogger;
import org.switchyard.validate.internal.ValidateMessages;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/**
* XML Validator {@link org.switchyard.validate.Validator}.
*
* @author Tomohisa Igarashi
*/
@Scannable(false)
public class XmlValidator extends BaseValidator {
private static final Logger LOGGER = Logger.getLogger(XmlValidator.class);
private XmlSchemaType _schemaType;
private String _schemaTypeUri;
private boolean _failOnWarning;
private boolean _isNamespaceAware;
private List _schemaConfig;
private List _catalogConfig;
private SAXParserFactory _parserFactory;
private XmlValidatorCatalogResolver _catalogResolver;
private XmlValidatorDTDResolver _dtdResolver;
private List _schemaFileNames = new ArrayList();
private List _catalogFileNames = new ArrayList();
/**
* constructor.
* @param name name
* @param model model
*/
public XmlValidator(QName name, XmlValidateModel model) {
super(name);
_schemaType = model.getSchemaType();
if (_schemaType == null) {
throw ValidateMessages.MESSAGES.couldNotInstantiateXmlValidator();
}
switch(_schemaType) {
case DTD:
_schemaTypeUri = XMLConstants.XML_DTD_NS_URI;
break;
case XML_SCHEMA:
_schemaTypeUri = XMLConstants.W3C_XML_SCHEMA_NS_URI;
break;
case RELAX_NG:
_schemaTypeUri = XMLConstants.RELAXNG_NS_URI;
break;
default:
StringBuilder builder = new StringBuilder();
for (XmlSchemaType s : XmlSchemaType.values()) {
builder.append(s.name() + ", ");
}
if (builder.length() >= 2) {
builder.delete(builder.length()-2, builder.length());
}
throw ValidateMessages.MESSAGES.couldNotInstantiateXmlValidatorBadSchemaType(_schemaType.toString(),
builder.toString());
}
_failOnWarning = model.failOnWarning();
_isNamespaceAware = model.namespaceAware();
if (model.getSchemaFiles() != null) {
_schemaConfig = model.getSchemaFiles().getEntries();
}
if (model.getSchemaCatalogs() != null) {
_catalogConfig = model.getSchemaCatalogs().getEntries();
}
setup();
}
protected void setup() {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(new StringBuffer("Setting up XmlValidator:[").append(formatUnparsedConfigs()).append("]"));
}
_parserFactory = SAXParserFactory.newInstance();
_parserFactory.setXIncludeAware(true);
_parserFactory.setNamespaceAware(_isNamespaceAware);
if (_catalogConfig != null) {
List foundCatalogs = new ArrayList();
for (FileEntryModel entry : _catalogConfig) {
URL located = locateFile(entry.getFile());
if (located != null) {
foundCatalogs.add(located);
} else {
ValidateLogger.ROOT_LOGGER.schemaCatalogNotLocated(entry.getFile());
}
}
if (foundCatalogs.size() > 0) {
CatalogManager manager = new CatalogManager();
manager.setIgnoreMissingProperties(true);
manager.setAllowOasisXMLCatalogPI(true);
manager.setPreferPublic(true);
manager.setRelativeCatalogs(false);
manager.setUseStaticCatalog(false);
manager.setVerbosity(0);
_catalogResolver = new XmlValidatorCatalogResolver(manager);
_catalogResolver.namespaceAware = _isNamespaceAware;
_catalogFileNames = new ArrayList();
for (URL catalog : foundCatalogs) {
try {
_catalogResolver.getCatalog().parseCatalog(catalog);
_catalogFileNames.add(catalog.toString());
} catch (Exception e) {
ValidateLogger.ROOT_LOGGER.schemaCatalogNotParsed(catalog.toString(), e.getMessage());
}
}
}
}
if (XMLConstants.XML_DTD_NS_URI.equals(_schemaTypeUri)) {
// set up for DTD validation - DTD file is located by DOCTYPE element in the Document itself
_parserFactory.setValidating(true);
if (_schemaConfig != null) {
for (FileEntryModel entry : _schemaConfig) {
if (entry.getFile() != null) {
_schemaFileNames.add(entry.getFile());
}
}
}
_dtdResolver = new XmlValidatorDTDResolver(_schemaFileNames);
} else {
// setup for XML Schema or Relax NG validation
if (_schemaConfig == null) {
throw ValidateMessages.MESSAGES.schemaFileMustBeSpecified(_schemaType.toString());
}
SchemaFactory schemaFactory = SchemaFactory.newInstance(_schemaTypeUri);
if (_catalogResolver != null) {
schemaFactory.setResourceResolver(_catalogResolver);
}
List