/**
* 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.avro.xml;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.SortedMap;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamSource;
import org.apache.avro.Schema;
import org.apache.avro.xml.AvroRecordInfo;
import org.apache.avro.xml.AvroSchemaApplier;
import org.apache.avro.xml.AvroSchemaGenerator;
import org.apache.avro.xml.Utils;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.docpath.XmlSchemaDocumentNode;
import org.apache.ws.commons.schema.docpath.XmlSchemaPathFinder;
import org.apache.ws.commons.schema.docpath.XmlSchemaPathNode;
import org.apache.ws.commons.schema.docpath.XmlSchemaStateMachineGenerator;
import org.apache.ws.commons.schema.docpath.XmlSchemaStateMachineNode;
import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xml.sax.SAXException;
public class TestAvroSchemaApplier {
private static XmlSchemaStateMachineNode root;
private static SAXParserFactory spf;
private static Schema avroSchema;
private SAXParser saxParser;
private XmlSchemaPathFinder pathCreator;
@BeforeClass
public static void createStateMachine() throws FileNotFoundException {
File file =
UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
ArrayList<File> schemaFiles = new ArrayList<File>(1);
schemaFiles.add(file);
// 1. Construct the Avro Schema
XmlSchemaCollection collection = null;
FileReader fileReader = null;
AvroSchemaGenerator visitor =
new AvroSchemaGenerator(null, null, schemaFiles);
try {
fileReader = new FileReader(file);
collection = new XmlSchemaCollection();
collection.read(new StreamSource(fileReader, file.getAbsolutePath()));
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
XmlSchemaElement elem = getElementOf(collection, "root");
XmlSchemaWalker walker = new XmlSchemaWalker(collection, visitor);
walker.setUserRecognizedTypes( Utils.getAvroRecognizedTypes() );
walker.walk(elem);
avroSchema = visitor.getSchema();
visitor.clear();
walker.clear();
// 2. Construct the state machine.
XmlSchemaStateMachineGenerator generator =
new XmlSchemaStateMachineGenerator();
walker.removeVisitor(visitor).addVisitor(generator);
walker.walk(elem);
root = generator.getStartNode();
spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
}
@Before
public void createSaxParser() throws Exception {
saxParser = spf.newSAXParser();
pathCreator = new XmlSchemaPathFinder(root);
}
@Test
public void test() throws Exception {
// 1. Build the XML Document Path.
final File xsdFile =
UtilsForTests.buildFile(
"src",
"test",
"resources",
"test3_grandchildren.xml");
try {
saxParser.parse(xsdFile, pathCreator);
} catch (SAXException e) {
e.printStackTrace();
throw e;
}
XmlSchemaPathNode rootPath =
pathCreator.getXmlSchemaTraversal();
XmlSchemaDocumentNode<AvroRecordInfo> rootDoc = rootPath.getDocumentNode();
assertNotNull(rootPath);
assertNotNull(rootDoc);
// 2. Confirm the Avro Schema conforms to the XML Schema
AvroSchemaApplier applier = new AvroSchemaApplier(avroSchema, true);
applier.apply(rootPath);
final int numElemsProcessed = checkDoc(rootDoc);
assertEquals(18, numElemsProcessed);
}
private int checkDoc(XmlSchemaDocumentNode<AvroRecordInfo> doc) {
int numElemsProcessed = 0;
if (doc
.getStateMachineNode()
.getNodeType()
.equals(XmlSchemaStateMachineNode.Type.ELEMENT)) {
assertNotNull( doc.getUserDefinedContent() );
final AvroRecordInfo recordInfo = doc.getUserDefinedContent();
final Schema schema = recordInfo.getAvroSchema();
assertTrue(
schema.getType().equals(Schema.Type.RECORD)
|| schema.getType().equals(Schema.Type.MAP));
assertEquals(
doc.getStateMachineNode().getElement().getName(),
schema.getName());
++numElemsProcessed;
} else {
assertNull( doc.getUserDefinedContent() );
}
for (int iter = 1; iter <= doc.getIteration(); ++iter) {
final SortedMap<Integer, XmlSchemaDocumentNode<AvroRecordInfo>>
children = doc.getChildren(iter);
if (children != null) {
for (Map.Entry<Integer, XmlSchemaDocumentNode<AvroRecordInfo>> child :
children.entrySet()) {
numElemsProcessed += checkDoc(child.getValue());
}
}
}
return numElemsProcessed;
}
private static XmlSchemaElement getElementOf(
XmlSchemaCollection collection,
String name) {
XmlSchemaElement elem = null;
for (XmlSchema schema : collection.getXmlSchemas()) {
elem = schema.getElementByName(name);
if (elem != null) {
break;
}
}
return elem;
}
}