/** * * 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.openejb.server.axis.assembler; import org.apache.openejb.assembler.classic.InfoObject; import javax.xml.namespace.QName; import java.util.List; import java.util.Map; import java.util.Set; import java.util.HashSet; import java.util.ArrayList; import java.lang.reflect.Field; import org.junit.Assert; public final class TypeInfoTestUtil { private TypeInfoTestUtil() { } public static void assertEqual(InfoObject expected, InfoObject actual) throws Exception { assertEqual(expected, actual, false); } public static void assertEqual(InfoObject expected, InfoObject actual, boolean printExpected) throws Exception { List<String> messages = new ArrayList<String>(); diff(null, expected, actual, messages); if (!messages.isEmpty()) { if (printExpected) { System.out.println("************ Actual " + expected.getClass().getSimpleName() + " ************"); dump("expected", actual); System.out.println("**********************************************"); System.out.println(); } StringBuilder msg = new StringBuilder(); for (String message : messages) { if (msg.length() != 0) msg.append("\n"); msg.append(message); } msg.insert(0, expected.getClass().getSimpleName() + " is different:\n"); Assert.fail(msg.toString()); } } public static void diff(String name, Object expected, Object actual, List<String> messages) throws Exception { for (Field field : expected.getClass().getFields()) { String fieldName = name == null ? field.getName() : name + "." + field.getName(); Object expectedValue = field.get(expected); Object actualValue = field.get(actual); if (expectedValue instanceof InfoObject) { diff(fieldName, expectedValue, actualValue, messages); } else if (expectedValue instanceof Map) { //noinspection unchecked diffMap(fieldName, (Map) expectedValue, (Map) actualValue, messages); } else { diffSimple(fieldName, expectedValue, actualValue, messages); } } } private static void diffMap(String name, Map<Object, Object> expected, Map<Object, Object> actual, List<String> message) throws Exception { // Added Set<Object> keys = new HashSet<Object>(actual.keySet()); keys.removeAll(expected.keySet()); for (Object key : keys) { message.add("A " + name + "[" + key + "]"); } // Removed keys = new HashSet<Object>(expected.keySet()); keys.removeAll(actual.keySet()); for (Object key : keys) { message.add("R " + name + "[" + key + "]"); } // Changed for (Object key : expected.keySet()) { Object expectValue = expected.get(key); Object actualValue = actual.get(key); if (actualValue != null) { diff(name + "[" + key + "]", expectValue, actualValue, message); } } } private static void diffSimple(String name, Object expected, Object actual, List<String> messages) { boolean changed = true; if (expected == null) { if (actual == null) changed = false; } else { if (expected.equals(actual)) changed = false; } if (changed) { messages.add("C " + name + ": " + expected + " ==> " + actual); } } public static void dump(String name, Object value) throws Exception { if (name == null) throw new NullPointerException("name is null"); if (isSimpleValue(value)) { if (name.indexOf('.') > 0) { System.out.println(name + " = " + getSimpleValue(value) + ";"); } else { if (value == null) throw new NullPointerException("value is null"); System.out.println(getTypeDecl(value.getClass(), name) + " = " + getSimpleValue(value) + ";"); } } else { System.out.println(getTypeDecl(value.getClass(), name) + " = new " + value.getClass().getSimpleName() + "();"); for (Field field : value.getClass().getFields()) { String fieldName = name == null ? field.getName() : name + "." + field.getName(); Object fieldValue = field.get(value); if (fieldValue instanceof Map) { //noinspection unchecked dumpMap(fieldName, (Map) fieldValue); } else { dump(fieldName, fieldValue); } } } } private static void dumpMap(String name, Map<Object, Object> map) throws Exception { for (Map.Entry<Object, Object> entry : map.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); if (isSimpleValue(key) && isSimpleValue(value)) { System.out.println(name + ".put(" + getSimpleValue(key) + ", " + getSimpleValue(value) + ");"); } else { String indent = name.substring(0, getIndentSize(name)); String baseName; if (value instanceof InfoObject) { baseName = value.getClass().getSimpleName(); if (baseName.endsWith("Info")) baseName = baseName.substring(0, baseName.length() - 4); baseName = Character.toLowerCase(baseName.charAt(0)) + baseName.substring(1); } else { baseName = name.substring(indent.length()).replace('.', '_'); if (baseName.endsWith("Key")) baseName = baseName.substring(0, baseName.length() - 3); } System.out.println(indent + "{"); dump(indent + " " + baseName + "Key", key); System.out.println(); dump(indent + " " + baseName, value); System.out.println(); System.out.println(" " + name + ".put(" + baseName + "Key, " + baseName + ");"); System.out.println(indent + "}"); } } } private static boolean isSimpleValue(Object value) { return value == null || value instanceof Boolean || value instanceof Number || value instanceof String || value instanceof QName; } private static String getSimpleValue(Object value) { if (!isSimpleValue(value)) throw new IllegalArgumentException("Value is not a simple type " + value.getClass().getName()); String stringValue; if (value == null) { stringValue = "null"; } else if (value instanceof Boolean) { stringValue = value.toString(); } else if (value instanceof Number) { stringValue = value.toString(); } else if (value instanceof QName) { QName qname = (QName) value; stringValue = "new QName(\"" + qname.getNamespaceURI() + "\", \"" + qname.getLocalPart() + "\")"; } else { stringValue = "\"" + value + "\""; } return stringValue; } private static String getTypeDecl(Class type, String name) { int indentSize = getIndentSize(name); return name.substring(0, indentSize) + type.getSimpleName() + " " + name.substring(indentSize); } private static int getIndentSize(String name) { for (int i = 0; i < name.length(); i++) { if (name.charAt(i) != ' ') { return i; } } return 0; } }