diff options
Diffstat (limited to 'sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util')
3 files changed, 566 insertions, 0 deletions
diff --git a/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/CTSUtil.java b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/CTSUtil.java new file mode 100644 index 0000000000..4b734a2ee3 --- /dev/null +++ b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/CTSUtil.java @@ -0,0 +1,207 @@ +/** + * + * 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 test.sdo21.tests.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.List; + +import test.sdo21.framework.TestHelper; + +import commonj.sdo.DataObject; +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.HelperContext; + +public class CTSUtil { + /** + * Convenience method for creating a unique name that can be used for a + * property or type. + * + * @return String containing a unique name + */ + public static DataObject createTypeDef(String uri, String name, boolean open, + HelperContext helperContext) { + DataObject typeDef = helperContext.getDataFactory().create("commonj.sdo", + "Type"); + typeDef.set("uri", uri); + typeDef.set("name", name); + typeDef.set("open", Boolean.valueOf(open)); + return typeDef; + } + + public static DataObject createPropertyDef(DataObject typeDef, String propertyName, + Type type, boolean isMany, boolean isContainment) { + DataObject propertyDef = typeDef.createDataObject("property"); + propertyDef.set("name", propertyName); + propertyDef.set("type", type); + propertyDef.set("many", isMany); + propertyDef.set("containment", isContainment); + return propertyDef; + } + + public static DataObject createPropertyDef(DataObject typeDef, String propertyName, + String typeName, boolean isMany, boolean isContainment, + HelperContext helperContext) { + int pos = typeName.indexOf('#'); + String uri = ""; + String name; + if (pos > 0) { + uri = typeName.substring(0, pos); + name = typeName.substring(pos + 1); + } else { + name = typeName; + } + Type propertyType = helperContext.getTypeHelper().getType(uri, name); + return createPropertyDef(typeDef, propertyName, propertyType, isMany, + isContainment); + } + + public static String createUniqueName() { + return "name-" + System.currentTimeMillis() + "-" + + ((int) (1000 * Math.random())); + } + + /** + * areEqualTypes is used to determine of two Types are equivalent even if + * not identically equal. The names of the Types are compared, as well as + * the Types of each of the Properties making up the Type. + * + * @param type1 + * @param type2 + * @return + */ + public static boolean areEqualTypes(Type type1, Type type2) { + List properties1, properties2; + Property property1, property2; + int size = 0, j = 0, k; + boolean found; + + // Equivalent Types have the same name + + if (!(type1.getName().equals(type2.getName()))) + return false; + + // Equivalent Types have the same number of Properties + + properties1 = type1.getProperties(); + properties2 = type2.getProperties(); + size = properties1.size(); + + if (size != properties2.size()) + return false; + + // Equivalent Types have Properties of the same name and Type + + for (int i = 0; i < size; i++) { + property1 = (Property)properties1.get(i); + k = 0; + found = false; + + while (k < size && !found) { + // j is used to prevent the initial Properties in properties2 + // from being checked every time + // j is particularly useful when the Types have Properties in + // the order + + property2 = (Property)properties2.get((k + j) % size); + + if (property1.getName().equals(property2.getName())) { + j++; + found = true; + + // Should not use recursion here to compare the Types of the + // Properties, because + // it is possible that a Type may recursively contain + // itself. + + if (!(property1.getType().getName().equals(property2.getType().getName()))) + return false; + } + k++; + } + if (!found) + return false; + } + return true; + } + + /** + * Uses the XMLHelper to serialize the input DataObject + * + * @param dataObject + * @param baos + * @param helperContexgt + * @throws IOException + */ + public static void serializeDataObjectXML(DataObject dataObject, ByteArrayOutputStream baos, HelperContext helperContext) throws IOException { + Type type = dataObject.getType(); + helperContext.getXMLHelper().save(dataObject, type.getURI(), type.getName(), baos); + } + + /** + * Uses the XMLHelper to deserialize the input XML file + * + * @param bais + * @param helperContext + * @return + * @throws IOException + * @throws ClassNotFoundException + */ + public static DataObject deserializeDataObjectXML(ByteArrayInputStream bais, HelperContext helperContext) throws IOException, ClassNotFoundException { + return helperContext.getXMLHelper().load(bais).getRootObject(); + } + + /** + * Uses Java serialization to serialize the input DataObject + * + * @param dataObject + * @param baos + * @param helperContext + * @throws IOException + */ + public static void serializeDataObjectJava(TestHelper testHelper, DataObject dataObject, ByteArrayOutputStream baos, HelperContext helperContext) throws IOException { + ObjectOutputStream out = testHelper.createObjectOutputStream(baos, helperContext); + out.writeObject(dataObject); + out.close(); + } + + /** + * Uses Java deserialization to deserialize the input XML file + * + * @param bais + * @param helperContext + * @return + * @throws IOException + * @throws ClassNotFoundException + */ + public static DataObject deserializeDataObjectJava(TestHelper testHelper, ByteArrayInputStream bais, HelperContext helperContext) throws IOException, ClassNotFoundException { + ObjectInputStream input = testHelper.createObjectInputStream(bais, helperContext); + DataObject dataObject = (DataObject)input.readObject(); + input.close(); + return dataObject; + } + + + +} diff --git a/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLDifferenceException.java b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLDifferenceException.java new file mode 100644 index 0000000000..67bd0daea9 --- /dev/null +++ b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLDifferenceException.java @@ -0,0 +1,35 @@ +/** + * + * 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 test.sdo21.tests.util; + +public class XMLDifferenceException extends Exception { + + public XMLDifferenceException(String message) { + super(message); + } + + public XMLDifferenceException(String message, Throwable cause) { + super(message, cause); + } + + public XMLDifferenceException(String difference, Object value1, Object value2) { + super( difference + ": " + value1 + " versus " + value2 ); + } +} diff --git a/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLEqualityChecker.java b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLEqualityChecker.java new file mode 100644 index 0000000000..dee5f84ea9 --- /dev/null +++ b/sdo-java/trunk-cts/sdo2.1/src/main/java/test/sdo21/tests/util/XMLEqualityChecker.java @@ -0,0 +1,324 @@ +/** + * + * 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 test.sdo21.tests.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Provides a series of methods for comparing output from the XMLHelper with an + * expected XML file. + */ +public class XMLEqualityChecker { + + private static final String XSI_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema-instance"; + + /** + * Places the nodes in nodeList into a indexed list. + * + * @param nodeList + * @param nodes + */ + private static void getAllNodes(NodeList nodeList, List nodes) { + int length = nodeList.getLength(); + if (length == 0) + return; + + for (int i = 0; i < length; i++) { + Node node = nodeList.item(i); + nodes.add(node); + getAllNodes(node.getChildNodes(), nodes); + } // for + } + + /** + * Compares two NamedNodeMap instances and throws an exception if they are not equivalent. + * + * @param mapA + * @param mapB + */ + private static void compareNamedNodeMap(NamedNodeMap mapA, NamedNodeMap mapB) throws XMLDifferenceException { + if (mapA == null) { + if (mapB == null) { + return; + } + throw new XMLDifferenceException( "mapA was null, mapB wasn't" ); + } + if (mapA.getLength() != mapB.getLength()) { + throw new XMLDifferenceException( "map length", mapA.getLength(), mapB.getLength() ); + } + for (int i = 0; i < mapA.getLength(); i++) { + Node trialNode = mapA.item(i); + if (trialNode == null) { + throw new XMLDifferenceException("mapB did not contain value at index " + i); + } + if (trialNode.getNodeName().startsWith("xmlns:")) { + // ignore namespace declarations since these will be checked on each element + // using the namespace + continue; + } + Node checkNode = mapB.getNamedItem(trialNode.getNodeName()); + if (checkNode == null) { + throw new XMLDifferenceException("mapB did not contain value named '" + trialNode.getNodeName() + "'"); + } + compareNode(trialNode, checkNode); + } + } + + /** + * Compares two Node instances and throws an exception if they are not equivalent. + * + * @param nodeA + * @param nodeB + */ + private static void compareNode(Node nodeA, Node nodeB) throws XMLDifferenceException { + if (nodeA == null) { + if (nodeB == null) { + return; + } + throw new XMLDifferenceException( "nodeA was null, nodeB wasn't" ); + } + // following is intended to provide same function as 1.5 isEqualNode() + if (nodeA.getNodeType() != nodeB.getNodeType()) { + throw new XMLDifferenceException( "node type", nodeA.getNodeType(), nodeB.getNodeType() ); + } + if (!equalString(nodeA.getLocalName(), nodeB.getLocalName())) { + throw new XMLDifferenceException( "local name", nodeA.getLocalName(), nodeB.getLocalName() ); + } + if (!equalString(nodeA.getNamespaceURI(), nodeB.getNamespaceURI())) { + throw new XMLDifferenceException( "namespace URI", nodeA.getNamespaceURI(), nodeB.getNamespaceURI() ); + } + + // special handling for xsi:type + if (XSI_NAMESPACE_URI.equals(nodeA.getNamespaceURI()) + && nodeA.getLocalName().equals("type")) { + + // because the gold xml file might use a different namespace prefix + // than the sdo implementation under test, we need to ignore the + // prefix used in any xsi:type attribute + + String nodeValueA = nodeA.getNodeValue(); + String nodeValueB = nodeB.getNodeValue(); + + int posA = nodeValueA.indexOf(':'); + int posB = nodeValueB.indexOf(':'); + + if (posA != -1 && posB != -1 && nodeValueA.substring(posA+1).equals(nodeValueB.substring(posB+1))) { + // the type name does match + } + else { + if (!equalString(nodeA.getNodeValue(), nodeB.getNodeValue())) { + throw new XMLDifferenceException ("node value", nodeA.getNodeValue(), nodeB.getNodeValue() ); + } + } + } + else { + if (!equalString(nodeA.getNodeValue(), nodeB.getNodeValue())) { + throw new XMLDifferenceException( + "value of node '" + nodeA.getLocalName() + "' in namespace '" + nodeA.getNamespaceURI() + "'", + nodeA.getNodeValue(), nodeB.getNodeValue() ); + } + + compareNamedNodeMap(nodeA.getAttributes(), nodeB.getAttributes()); + compareNodeList( nodeA.getChildNodes(), nodeB.getChildNodes()); + if (nodeA.getNodeType() == Node.DOCUMENT_TYPE_NODE) { + DocumentType documentTypeA = (DocumentType)nodeA; + DocumentType documentTypeB = (DocumentType)nodeB; + if (!equalString(documentTypeA.getPublicId(), documentTypeB.getPublicId())) { + throw new XMLDifferenceException( "public ID", documentTypeA.getPublicId(), documentTypeB.getPublicId() ); + } + if (!equalString(documentTypeA.getSystemId(), documentTypeB.getSystemId())) { + throw new XMLDifferenceException( "system ID", documentTypeA.getSystemId(), documentTypeB.getSystemId() ); + } + if (!equalString(documentTypeA.getInternalSubset(), documentTypeB.getInternalSubset())) { + throw new XMLDifferenceException( "internal subset", documentTypeA.getInternalSubset(), documentTypeB.getInternalSubset() ); + } + compareNamedNodeMap(documentTypeA.getEntities(), documentTypeB.getEntities()); + compareNamedNodeMap(documentTypeA.getNotations(), documentTypeB.getNotations()); + } + } + } + + /** + * Compares two NodeList instances and throws an exception if they are not equivalent. + * + * @param nodeListA + * @param nodeListB + */ + private static void compareNodeList(NodeList nodeListA, NodeList nodeListB) throws XMLDifferenceException { + if (nodeListA == null) { + if (nodeListB == null) { + return; + } + throw new XMLDifferenceException( "nodeListA was null, nodeListB wasn't" ); + } + compareNodes(nodeListA, nodeListB); + } + + /** + * Returns true of the two Strings are equivalent, false otherwise. + * + * @param stringA + * @param stringB + */ + private static boolean equalString(String stringA, String stringB) { + if (stringA == null) { + if (stringB == null) { + return true; + } + return false; + } + return stringA.equals(stringB); + } + + /** + * Returns true if the two NodeLists are equivalent, false otherwise. + * + * @param sourceNodeList + * @param targetNodeList + */ + private static void compareNodes(NodeList sourceNodeList, NodeList targetNodeList) + throws XMLDifferenceException { + + ArrayList sourceNodes = new ArrayList(); + ArrayList targetNodes = new ArrayList(); + + getAllNodes(sourceNodeList, sourceNodes); + getAllNodes(targetNodeList, targetNodes); + + int sourceLength = sourceNodes.size(); + int targetLength = targetNodes.size(); + + if (sourceLength != targetLength) { + throw new XMLDifferenceException( + "node count", + sourceLength, + targetLength + ); + } + + for (int i = 0; i < sourceLength; i++) { + Node sourceNode = (Node)sourceNodes.get(i); + Node targetNode = (Node)targetNodes.get(i); + + compareNode(sourceNode, targetNode); + } // for + } + + /** + * Throws exception if the two XML files are not equivalent. + * Accepts as input two URLs which identify the XML files, and calls + * equalXMLFiles(InputStream, InputStream). + * + * @param source + * @param target + */ + public static void compareXmlFiles(URL source, URL target) + throws XMLDifferenceException, IOException { + compareXmlFiles(source.openStream(), target.openStream()); + } + + /** + * Throws exception if the two XML files are not equivalent. + * Accepts as input an InputStream and a URL which identify the XML files, + * and calls equalXMLFiles(InputStream, InputStream). + * + * @param sourceStream + * @param target + */ + public static void compareXmlFiles(InputStream sourceStream, URL target) + throws XMLDifferenceException, IOException { + compareXmlFiles(sourceStream, target.openStream()); + } + + /** + * Throws exception if the two XML files are not equivalent. + * Accepts as input a URL and an InputStream which identify the XML files, + * and calls equalXMLFiles(InputStream, InputStream). + * + * @param source + * @param targetStream + */ + public static void compareXmlFiles(URL source, InputStream targetStream) + throws XMLDifferenceException, IOException { + compareXmlFiles(source.openStream(), targetStream); + } + + /** + * Throws exception if the two XML files are not equivalent. + * Accepts as input two InputStreams which identify the XML files. + * + * @param sourceStream + * @param targetStream + */ + public static void compareXmlFiles(InputStream sourceStream, InputStream targetStream) + throws XMLDifferenceException, IOException { + + DocumentBuilder builder; + Document sourceDocument; + Document targetDocument; + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + builder = factory.newDocumentBuilder(); + sourceDocument = builder.parse(sourceStream); + targetDocument = builder.parse(targetStream); + } catch (IOException ie) { + throw ie; + } catch (Exception e) { + throw new XMLDifferenceException( "Failed to parse files", e ); + } + + sourceDocument.normalize(); + targetDocument.normalize(); + + /* + * remove comment when migrated to Java 1.5 if + * (!sourceDocument.getXmlVersion().equals(targetDocument.getXmlVersion())) + * return false; String sourceXmlEncoding = + * sourceDocument.getXmlEncoding(); String targetXmlEncoding = + * targetDocument.getXmlEncoding(); if (sourceXmlEncoding != null && + * targetXmlEncoding != null && + * sourceXmlEncoding.equalsIgnoreCase(targetXmlEncoding)) { // continue } + * else { return false; } + */ + + NodeList sourceNodes = sourceDocument.getChildNodes(); + NodeList targetNodes = targetDocument.getChildNodes(); + + compareNodes(sourceNodes, targetNodes); + } +} |