/*
* Copyright 2008 Lukas Lang, Filip Hianik
*
* 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.exolab.castor.xml.schema.reader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import junit.framework.TestCase;
import org.castor.xml.BackwardCompatibilityContext;
import org.castor.xml.InternalContext;
import org.exolab.castor.xml.XMLException;
import org.exolab.castor.xml.schema.Annotation;
import org.exolab.castor.xml.schema.AppInfo;
import org.exolab.castor.xml.schema.ComplexType;
import org.exolab.castor.xml.schema.ElementDecl;
import org.exolab.castor.xml.schema.Schema;
import org.exolab.castor.xml.schema.SchemaContext;
import org.exolab.castor.xml.schema.SchemaContextImpl;
import org.exolab.castor.xml.schema.annotations.jdo.Column;
import org.exolab.castor.xml.schema.annotations.jdo.OneToMany;
import org.exolab.castor.xml.schema.annotations.jdo.OneToOne;
import org.exolab.castor.xml.schema.annotations.jdo.Table;
import org.xml.sax.InputSource;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
/**
* This test is a integration test. It verifies whether a SchemaUnmarshaller
* correctly unmarshalles a JDO annoted Schema. As a test Schema it uses a
* Schema with an element declaration referring to a complexType including
* various elements.
*
* @author Lukas Lang
*
*/
public class SchemaUnmarshallerTest extends TestCase {
/**
* Test tries to unmarshall jdo specific content in appinfo elements within
* a complete annoted schema.<br>
* <br>
* Action: Parse an annoted schema.<br>
* Precondition: schema-entity.xml holds a correct annoted schema with
* appinfo content.<br>
* Postcondition: The complexType bookType holds a table object in it's
* annotations. The element declaration of isbn holds a column object. The
* element declaration of title also holds a column object.
* @throws IOException
* @throws SAXException
* @throws FileNotFoundException
*/
public void testUnmarshallSchema() throws FileNotFoundException, SAXException, IOException {
Schema schema = unmarshalSchema("schema-entity.xsd");
ComplexType bookType = schema.getComplexType("bookType");
Enumeration annotations = bookType.getAnnotations();
Annotation annotation = (Annotation) annotations.nextElement();
Enumeration appInfos = annotation.getAppInfo();
AppInfo appInfo = (AppInfo) appInfos.nextElement();
List jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Table t = (Table) jdoContent.get(0);
assertEquals("book", t.getName());
assertEquals("isbn", t.getPrimaryKey().getKey(0));
ElementDecl isbn = bookType.getElementDecl("isbn");
annotations = isbn.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Column c = (Column) jdoContent.get(0);
assertEquals("isbn", c.getName());
assertEquals("jdo:string", c.getType());
ElementDecl title = bookType.getElementDecl("title");
annotations = title.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
c = (Column) jdoContent.get(0);
assertEquals("title", c.getName());
assertEquals("jdo:string", c.getType());
}
/**
* Test tries to unmarshall non-jdo specific content in appinfo elements
* within a complete annoted schema.<br>
* <br>
* Action: Parse an annoted schema.<br>
* Precondition: schema-entity-non-jdo.xml holds a correct annoted schema
* with NO JDO content.<br>
* Postcondition: The complexType bookType, isbn and title have no
* jdo-specific content in it's annotations.
* @throws IOException
* @throws SAXException
*/
public void testUnmarshallNonJdoSchema() throws SAXException, IOException {
Schema schema = unmarshalSchema("schema-entity-non-jdo.xsd");
ComplexType bookType = schema.getComplexType("bookType");
Enumeration annotations = bookType.getAnnotations();
Annotation annotation = (Annotation) annotations.nextElement();
Enumeration appInfos = annotation.getAppInfo();
AppInfo appInfo = (AppInfo) appInfos.nextElement();
List jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
ElementDecl isbn = bookType.getElementDecl("isbn");
annotations = isbn.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
ElementDecl title = bookType.getElementDecl("title");
annotations = title.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
}
/**
* Test tries to unmarshall non-jdo specific content in appinfo elements
* within a complete annoted schema.<br>
* <br>
* Action: Parse an annoted schema.<br>
* Precondition: schema-entity-mixed.xml holds a correct annoted schema
* with NO JDO content, but encapsulated JDO elements.<br>
* Postcondition: The complexType bookType, isbn and title have no
* jdo-specific content in it's annotations.
* @throws IOException
* @throws SAXException
*/
public void testUnmarshallMixedSchema() throws SAXException, IOException {
Schema schema = unmarshalSchema("schema-entity-mixed.xsd");
ComplexType bookType = schema.getComplexType("bookType");
Enumeration annotations = bookType.getAnnotations();
Annotation annotation = (Annotation) annotations.nextElement();
Enumeration appInfos = annotation.getAppInfo();
AppInfo appInfo = (AppInfo) appInfos.nextElement();
List jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
ElementDecl isbn = bookType.getElementDecl("isbn");
annotations = isbn.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
ElementDecl title = bookType.getElementDecl("title");
annotations = title.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(0, jdoContent.size());
}
/**
* Test tries to unmarshall jdo specific content in appinfo elements within
* a complete annoted schema.<br>
* <br>
* Action: Parse an annoted schema.<br>
* Precondition: schema-one-to-many.xml holds a correct annoted schema with
* appinfo content.<br>
* Postcondition: The complexType bookType holds a table object in it's
* annotations. The element declaration of isbn holds a column object. The
* element declaration of title also holds a column object. The element
* declaration of author holds a one-to-many object.
* @throws IOException
* @throws SAXException
*/
public void testUnmarshallOneToManySchema() throws SAXException, IOException {
Schema schema = unmarshalSchema("schema-one-to-many.xsd");
ComplexType bookType = schema.getComplexType("bookType");
Enumeration annotations = bookType.getAnnotations();
Annotation annotation = (Annotation) annotations.nextElement();
Enumeration appInfos = annotation.getAppInfo();
AppInfo appInfo = (AppInfo) appInfos.nextElement();
List jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Table t = (Table) jdoContent.get(0);
assertEquals("book", t.getName());
assertEquals("isbn", t.getPrimaryKey().getKey(0));
ElementDecl isbn = bookType.getElementDecl("isbn");
annotations = isbn.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Column c = (Column) jdoContent.get(0);
assertEquals("isbn", c.getName());
assertEquals("varchar", c.getType());
ElementDecl title = bookType.getElementDecl("title");
annotations = title.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
c = (Column) jdoContent.get(0);
assertEquals("title", c.getName());
assertEquals("varchar", c.getType());
ElementDecl author = bookType.getElementDecl("author");
annotations = author.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
OneToMany oneToMany = (OneToMany) jdoContent.get(0);
assertEquals("author_id", oneToMany.getName());
assertTrue(oneToMany.isReadOnly());
assertTrue(oneToMany.isDirty());
}
/**
* This test tries to instantiate a Table object via reflection.
*/
public void testDomainObjectReflectionInstantiation() {
try {
Table table = (Table) Class.forName(
"org.exolab.castor.xml.schema.annotations.jdo.Table")
.newInstance();
table.setName("book");
assertEquals("book", table.getName());
} catch (InstantiationException e) {
e.printStackTrace();
fail(e.getMessage());
} catch (IllegalAccessException e) {
e.printStackTrace();
fail(e.getMessage());
} catch (ClassNotFoundException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
/**
* Test tries to unmarshall jdo specific content in appinfo elements within
* a complete annoted schema.<br>
* <br>
* Action: Parse an annoted schema.<br>
* Precondition: schema-entity.xml holds a correct annoted schema with
* appinfo content.<br>
* Postcondition: The complexType bookType holds a table object in it's
* annotations. The element declaration of isbn holds a column object. The
* element declaration of title also holds a column object.
* @throws IOException
* @throws SAXException
*/
public void testUnmarshallOneToOneSchema() throws SAXException, IOException {
Schema schema = unmarshalSchema("schema-one-to-one.xsd");
ComplexType bookType = schema.getComplexType("bookType");
Enumeration annotations = bookType.getAnnotations();
Annotation annotation = (Annotation) annotations.nextElement();
Enumeration appInfos = annotation.getAppInfo();
AppInfo appInfo = (AppInfo) appInfos.nextElement();
List jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Table t = (Table) jdoContent.get(0);
assertEquals("book", t.getName());
assertEquals("isbn", t.getPrimaryKey().getKey(0));
ElementDecl isbn = bookType.getElementDecl("isbn");
annotations = isbn.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
Column c = (Column) jdoContent.get(0);
assertEquals("isbn", c.getName());
assertEquals("varchar", c.getType());
ElementDecl title = bookType.getElementDecl("title");
annotations = title.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
c = (Column) jdoContent.get(0);
assertEquals("title", c.getName());
assertEquals("varchar", c.getType());
ElementDecl author = bookType.getElementDecl("author");
annotations = author.getAnnotations();
annotation = (Annotation) annotations.nextElement();
appInfos = annotation.getAppInfo();
appInfo = (AppInfo) appInfos.nextElement();
jdoContent = appInfo.getJdoContent();
assertEquals(1, jdoContent.size());
OneToOne oneToOne = (OneToOne) jdoContent.get(0);
assertEquals("author_id", oneToOne.getName());
assertTrue(oneToOne.isDirty());
assertTrue(oneToOne.isReadOnly());
}
/**
* Helper method that (manually) unmarshals an XML schema and returns a
* {@link Schema} object instance.
* @param schemaName Name of the XML schema to be unmarshalled.
* @return {@link Schema} object instance.
* @throws SAXException When a problem with XML data binding occurs.
* @throws IOException When the XML schema file cannot be accessed.
*/
private Schema unmarshalSchema(final String schemaName) throws SAXException, IOException {
Parser parser = null;
InternalContext internalContext = new BackwardCompatibilityContext();
try {
parser = internalContext.getParser();
} catch (RuntimeException rte) {
fail("Can't optain sax parser!");
}
if (parser == null) {
fail("Unable to create SAX parser.");
}
SchemaContext schemaContext = new SchemaContextImpl();
SchemaUnmarshaller schemaUnmarshaller = null;
try {
schemaUnmarshaller = new SchemaUnmarshaller(schemaContext);
} catch (XMLException e) {
fail(e.getMessage());
}
Sax2ComponentReader handler = new Sax2ComponentReader(
schemaUnmarshaller);
parser.setDocumentHandler(handler);
parser.setErrorHandler(handler);
parser.parse(new InputSource(getClass().getResource(schemaName).toExternalForm()));
Schema schema = schemaUnmarshaller.getSchema();
return schema;
}
}