/*
* Copyright (c) 2010-2013 Evolveum
*
* 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 com.evolveum.midpoint.prism;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNull;
import static com.evolveum.midpoint.prism.PrismInternalTestUtil.*;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;
import com.evolveum.midpoint.prism.schema.SchemaRegistryImpl;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.evolveum.midpoint.prism.foo.UserType;
import com.evolveum.midpoint.prism.schema.PrismSchema;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.SchemaException;
public class TestExtraSchema {
public static final String NS_USER_2_EXT = "http://example.com/xml/ns/user-2-extension";
private static final QName USER_EXTENSION_TYPE_QNAME = new QName(NS_USER_EXT,"UserExtensionType");
private static final QName USER_2_EXTENSION_TYPE_QNAME = new QName(NS_USER_2_EXT,"User2ExtensionType");
private static final QName USER_EXT_2_ELEMENT = new QName(NS_USER_2_EXT, "ext2");
/**
* Test is extra schema can be loaded to the schema registry and whether the file compliant to that
* schema can be validated.
*/
@Test
public void testExtraSchema() throws SAXException, IOException, SchemaException {
System.out.println("===[ testExtraSchema ]===");
Document dataDoc = DOMUtil.parseFile(new File(COMMON_DIR_PATH, "root-foo.xml"));
PrismContext context = constructPrismContext();
SchemaRegistryImpl reg = (SchemaRegistryImpl) context.getSchemaRegistry();
Document extraSchemaDoc = DOMUtil.parseFile(new File(EXTRA_SCHEMA_DIR, "root.xsd"));
reg.registerSchema(extraSchemaDoc, "file root.xsd");
reg.initialize();
Schema javaxSchema = reg.getJavaxSchema();
assertNotNull(javaxSchema);
Validator validator = javaxSchema.newValidator();
DOMResult validationResult = new DOMResult();
validator.validate(new DOMSource(dataDoc),validationResult);
// System.out.println("Validation result:");
// System.out.println(DOMUtil.serializeDOMToString(validationResult.getNode()));
}
/**
* Test if a schema directory can be loaded to the schema registry. This contains definition of
* user extension, therefore check if it is applied to the user definition.
*/
@Test
public void testUserExtensionSchemaLoad() throws SAXException, IOException, SchemaException {
System.out.println("===[ testUserExtensionSchemaLoad ]===");
PrismContext context = constructPrismContext();
SchemaRegistryImpl reg = (SchemaRegistryImpl) context.getSchemaRegistry();
reg.registerPrismSchemasFromDirectory(EXTRA_SCHEMA_DIR);
context.initialize();
System.out.println("Initialized registry");
System.out.println(reg.debugDump());
// Try midpoint schemas by parsing a XML file
PrismSchema schema = reg.getSchema(NS_FOO);
System.out.println("Parsed foo schema:");
System.out.println(schema.debugDump());
// TODO: assert user
schema = reg.getSchema(NS_USER_EXT);
System.out.println("Parsed user ext schema:");
System.out.println(schema.debugDump());
ComplexTypeDefinition userExtComplexType = schema.findComplexTypeDefinition(USER_EXTENSION_TYPE_QNAME);
assertEquals("Extension type ref does not match", USER_TYPE_QNAME, userExtComplexType.getExtensionForType());
}
@Test
public void testUserExtensionSchemaParseUser() throws SAXException, IOException, SchemaException {
System.out.println("===[ testUserExtensionSchemaParseUser ]===");
Document dataDoc = DOMUtil.parseFile(USER_JACK_FILE_XML);
PrismContext context = constructPrismContext();
SchemaRegistryImpl reg = (SchemaRegistryImpl) context.getSchemaRegistry();
reg.registerPrismSchemasFromDirectory(EXTRA_SCHEMA_DIR);
context.initialize();
// Parsing user
PrismObject<UserType> user = context.parserFor(DOMUtil.getFirstChildElement(dataDoc)).compat().parse(); // items from user extension are not correctly defined in the schema
assertNotNull("No definition for user", user.getDefinition());
System.out.println("Parsed root object:");
System.out.println(user.debugDump());
// TODO: assert user
// Try javax schemas by validating a XML file
Schema javaxSchema = reg.getJavaxSchema();
assertNotNull(javaxSchema);
Validator validator = javaxSchema.newValidator();
DOMResult validationResult = new DOMResult();
validator.validate(new DOMSource(dataDoc),validationResult);
// System.out.println("Validation result:");
// System.out.println(DOMUtil.serializeDOMToString(validationResult.getNode()));
}
@Test
public void testUserExtensionSchemaSchemaRegistry() throws SAXException, IOException, SchemaException {
System.out.println("===[ testUserExtensionSchemaAsObjectSchema ]===");
PrismContext context = constructPrismContext();
SchemaRegistryImpl reg = (SchemaRegistryImpl) context.getSchemaRegistry();
reg.registerPrismSchemasFromDirectory(EXTRA_SCHEMA_DIR);
context.initialize();
PrismObjectDefinition<UserType> userDef = reg.findObjectDefinitionByType(USER_TYPE_QNAME);
System.out.println("User definition:");
System.out.println(userDef.debugDump());
assertUserDefinition(userDef);
PrismObjectDefinition<UserType> usedDefByClass = reg.findObjectDefinitionByCompileTimeClass(UserType.class);
assertUserDefinition(usedDefByClass);
PrismObjectDefinition<UserType> userDefByElement = reg.findObjectDefinitionByElementName(USER_QNAME);
assertUserDefinition(userDefByElement);
}
private void assertUserDefinition(PrismObjectDefinition<UserType> userDef) {
PrismContainerDefinition extDef = userDef.findContainerDefinition(USER_EXTENSION_QNAME);
System.out.println("User extension");
System.out.println(extDef.debugDump());
assertTrue("Extension is not dynamic", extDef.isRuntimeSchema());
assertTrue("Wrong extension type "+extDef.getTypeName(),
USER_EXTENSION_TYPE_QNAME.equals(extDef.getTypeName()) || USER_2_EXTENSION_TYPE_QNAME.equals(extDef.getTypeName()));
assertEquals("Wrong extension displayOrder", (Integer)1000, extDef.getDisplayOrder());
PrismPropertyDefinition barPropDef = extDef.findPropertyDefinition(USER_EXT_BAR_ELEMENT);
assertNotNull("No 'bar' definition in user extension", barPropDef);
PrismAsserts.assertDefinition(barPropDef, USER_EXT_BAR_ELEMENT, DOMUtil.XSD_STRING, 1, 1);
assertTrue("'bar' not indexed", barPropDef.isIndexed());
PrismPropertyDefinition foobarPropDef = extDef.findPropertyDefinition(USER_EXT_FOOBAR_ELEMENT);
assertNotNull("No 'foobar' definition in user extension", foobarPropDef);
PrismAsserts.assertDefinition(foobarPropDef, USER_EXT_FOOBAR_ELEMENT, DOMUtil.XSD_STRING, 0, 1);
assertNull("'foobar' has non-null indexed flag", foobarPropDef.isIndexed());
PrismPropertyDefinition multiPropDef = extDef.findPropertyDefinition(USER_EXT_MULTI_ELEMENT);
assertNotNull("No 'multi' definition in user extension", multiPropDef);
PrismAsserts.assertDefinition(multiPropDef, USER_EXT_MULTI_ELEMENT, DOMUtil.XSD_STRING, 0, -1);
assertFalse("'multi' not indexed", multiPropDef.isIndexed());
PrismPropertyDefinition ext2Def = extDef.findPropertyDefinition(USER_EXT_2_ELEMENT);
assertNotNull("No 'ext2' definition in user extension", ext2Def);
PrismAsserts.assertDefinition(ext2Def, USER_EXT_2_ELEMENT, DOMUtil.XSD_STRING, 1, 1);
// Make sure that the ordering is OK. If it is not then a serialization will produce XML that
// does not comply to schema
List<? extends ItemDefinition> definitions = userDef.getDefinitions();
assertDefinitionOrder(definitions, USER_NAME_QNAME, 0);
assertDefinitionOrder(definitions, USER_DESCRIPTION_QNAME, 1);
assertDefinitionOrder(definitions, USER_EXTENSION_QNAME, 2);
assertDefinitionOrder(definitions, USER_PARENT_ORG_REF_QNAME, 3);
assertDefinitionOrder(definitions, USER_FULLNAME_QNAME, 4);
}
private void assertDefinitionOrder(List<? extends ItemDefinition> definitions, QName elementName, int i) {
assertEquals("Wrong definition, expected that "+PrettyPrinter.prettyPrint(elementName)+" definition will be at index " +
i + " but there was a "+definitions.get(i).getName()+" instead", elementName, definitions.get(i).getName());
}
/**
* Test if a schema directory can be loaded to the schema registry. This contains definition of
* user extension, therefore check if it is applied to the user definition.
*/
@Test
public void testTypeOverride() throws SAXException, IOException, SchemaException {
System.out.println("===[ testTypeOverride ]===");
PrismContext context = constructPrismContext();
SchemaRegistryImpl reg = (SchemaRegistryImpl) context.getSchemaRegistry();
reg.registerPrismSchemasFromDirectory(EXTRA_SCHEMA_DIR);
context.initialize();
PrismSchema schema = reg.getSchema(NS_ROOT);
System.out.println("Parsed root schema:");
System.out.println(schema.debugDump());
PrismContainerDefinition rootContDef = schema.findContainerDefinitionByElementName(new QName(NS_ROOT,"root"));
assertNotNull("Not <root> definition", rootContDef);
PrismContainerDefinition extensionContDef = rootContDef.findContainerDefinition(new QName(NS_FOO, "extension"));
assertNotNull("Not <extension> definition", extensionContDef);
assertEquals("Wrong <extension> type", new QName(NS_ROOT, "MyExtensionType"), extensionContDef.getTypeName());
}
}