/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.wsdl.service.factory;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.transform.TransformerException;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaSerializer;
/**
*
*/
class XercesSchemaValidationUtils {
static class DOMLSInput implements LSInput {
private String systemId;
private String data;
DOMLSInput(Document doc, String systemId) throws TransformerException {
this.systemId = systemId;
data = StaxUtils.toString(doc);
}
/** {@inheritDoc}*/
public String getBaseURI() {
return null;
}
/** {@inheritDoc}*/
public InputStream getByteStream() {
return null;
}
/** {@inheritDoc}*/
public boolean getCertifiedText() {
return false;
}
/** {@inheritDoc}*/
public Reader getCharacterStream() {
return null;
}
/** {@inheritDoc}*/
public String getEncoding() {
return "utf-8";
}
/** {@inheritDoc}*/
public String getPublicId() {
return null;
}
/** {@inheritDoc}*/
public String getStringData() {
return data;
}
/** {@inheritDoc}*/
public String getSystemId() {
return systemId;
}
/** {@inheritDoc}*/
public void setBaseURI(String baseURI) {
}
/** {@inheritDoc}*/
public void setByteStream(InputStream byteStream) {
}
/** {@inheritDoc}*/
public void setCertifiedText(boolean certifiedText) {
}
/** {@inheritDoc}*/
public void setCharacterStream(Reader characterStream) {
}
/** {@inheritDoc}*/
public void setEncoding(String encoding) {
}
/** {@inheritDoc}*/
public void setPublicId(String publicId) {
}
/** {@inheritDoc}*/
public void setStringData(String stringData) {
}
/** {@inheritDoc}*/
public void setSystemId(String systemId) {
}
}
private DOMImplementation impl;
XercesSchemaValidationUtils() throws ClassNotFoundException, InstantiationException,
IllegalAccessException, ClassCastException {
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
impl = registry.getDOMImplementation("XS-Loader");
}
Method findMethod(Object o, String name) {
for (Method m : o.getClass().getMethods()) {
if (m.getName() != null && m.getName().equals(name)) {
m.setAccessible(true);
return m;
}
}
return null;
}
void tryToParseSchemas(XmlSchemaCollection collection, DOMErrorHandler handler)
throws Exception {
final List<DOMLSInput> inputs = new ArrayList<>();
final Map<String, LSInput> resolverMap = new HashMap<>();
for (XmlSchema schema : collection.getXmlSchemas()) {
if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schema.getTargetNamespace())) {
continue;
}
Document document = new XmlSchemaSerializer().serializeSchema(schema, false)[0];
DOMLSInput input = new DOMLSInput(document, schema.getTargetNamespace());
resolverMap.put(schema.getTargetNamespace(), input);
inputs.add(input);
}
try {
Object schemaLoader = findMethod(impl, "createXSLoader").invoke(impl, new Object[1]);
DOMConfiguration config = (DOMConfiguration)findMethod(schemaLoader, "getConfig").invoke(schemaLoader);
config.setParameter("validate", Boolean.TRUE);
config.setParameter("error-handler", handler);
config.setParameter("resource-resolver", new LSResourceResolver() {
public LSInput resolveResource(String type, String namespaceURI, String publicId,
String systemId, String baseURI) {
return resolverMap.get(namespaceURI);
}
});
Method m = findMethod(schemaLoader, "loadInputList");
String name = m.getParameterTypes()[0].getName() + "Impl";
name = name.replace("xs.LS", "impl.xs.util.LS");
Class<?> c = Class.forName(name);
Object inputList = c.getConstructor(LSInput[].class, Integer.TYPE)
.newInstance(inputs.toArray(new LSInput[inputs.size()]), inputs.size());
m.invoke(schemaLoader, inputList);
} catch (InvocationTargetException e) {
throw (Exception)e.getTargetException();
}
}
}