f5aaa49dba43db0e99f06476534a8749820515dbcsovant/*
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * CDDL HEADER START
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * The contents of this file are subject to the terms of the
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * Common Development and Distribution License, Version 1.0 only
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * (the "License"). You may not use this file except in compliance
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * with the License.
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * or http://forgerock.org/license/CDDLv1.0.html.
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * See the License for the specific language governing permissions
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * and limitations under the License.
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * When distributing Covered Code, include this CDDL HEADER in each
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * file and include the License file at legal-notices/CDDLv1_0.txt.
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * If applicable, add the following below this CDDL HEADER, with the
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * fields enclosed by brackets "[]" replaced with your own identifying
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * information:
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * Portions Copyright [yyyy] [name of copyright owner]
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * CDDL HEADER END
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
f5aaa49dba43db0e99f06476534a8749820515dbcsovant *
f5aaa49dba43db0e99f06476534a8749820515dbcsovant * Portions Copyright 2009 Sun Microsystems, Inc.
f5aaa49dba43db0e99f06476534a8749820515dbcsovant */
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovantpackage com.ibm.staf.service.opends.tester;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.lang.reflect.Method;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.ArrayList;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.HashMap;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.HashSet;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.List;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.Map;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.Set;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.Stack;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport javax.xml.bind.JAXBElement;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.Collection;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport java.util.Collections;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport org.opends.dsml.protocol.DsmlAttr;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport org.opends.server.core.DirectoryServer;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport org.opends.server.types.DN;
f5aaa49dba43db0e99f06476534a8749820515dbcsovantimport org.opends.server.types.DirectoryException;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovantpublic class Checker {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static final String JAXB_GENERATED_PACKAGE_NAME = "org.opends.dsml.protocol";
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // Key=JAXB classes, Value=List of methods to get attribute
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static final Map<Class, List<Method>> CACHE = new HashMap<Class, List<Method>>();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // Helpfull to keep track of what argument is currently processed
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static final Stack<Method> STACK = new Stack<Method>();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // A list of attribute that are prevented to be checked
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static final Set<String> DO_NOT_CHECK = new HashSet<String>();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant static {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant DO_NOT_CHECK.add("ResultCode.getDescr"); // ResultCode.getCode is enough
f5aaa49dba43db0e99f06476534a8749820515dbcsovant DO_NOT_CHECK.add("LDAPResult.getErrorMessage"); // LDAPResult.getResultCode is enough
f5aaa49dba43db0e99f06476534a8749820515dbcsovant DO_NOT_CHECK.add("ErrorResponse.getMessage");
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static DsmlAttrCompare dsmlAttrCompare = new DsmlAttrCompare();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant static {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // needed otherwise the SearchResultEntry like in test moddn998.res fail
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // in the equals() method on DN.decode((String) o1....
f5aaa49dba43db0e99f06476534a8749820515dbcsovant DirectoryServer.bootstrapClient();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static List<Method> getAttributes(Class clazz) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant List<Method> result = CACHE.get(clazz);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (result == null) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant result = new ArrayList<Method>();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Method method : clazz.getMethods()) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant String methodName = method.getName();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Class returnType = method.getReturnType();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!method.getDeclaringClass().getName().startsWith(JAXB_GENERATED_PACKAGE_NAME)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant continue;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (((methodName.startsWith("get") && (methodName.length() > 3) && (!returnType.equals(void.class))) || (methodName.startsWith("is") && (methodName.length() > 2) && (returnType.equals(boolean.class)))) && (method.getParameterTypes().length == 0)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant result.add(method);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant CACHE.put(clazz, result);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return result;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant private static String buildMessage() {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // return "";
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant StringBuilder sb = new StringBuilder(STACK.peek().toGenericString()).append(" in JAXB ");
f5aaa49dba43db0e99f06476534a8749820515dbcsovant int size = STACK.size();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (int i = 0; i < size; i++) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant sb.append(i == 0 ? "" : ".").append(STACK.get(i).getName()).append("()");
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return sb.toString();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant public static boolean equals(Object o1, Object o2) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (o1 == null && o2 == null) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return true;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (o1 == null || o2 == null) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("One of the two is null : " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // both are not null
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Class c1 = o1.getClass();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!o2.getClass().equals(c1)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("Type mismatch (" + c1.getName() + " vs " + o2.getClass().getName() + ") : " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (c1.getName().startsWith(JAXB_GENERATED_PACKAGE_NAME)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Method method : getAttributes(c1)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant String fullName = method.getDeclaringClass().getName() + "." + method.getName();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant String s = fullName.substring(JAXB_GENERATED_PACKAGE_NAME.length() + 1, fullName.length());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (DO_NOT_CHECK.contains(s)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant continue;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Object r1, r2;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant try {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant STACK.push(method);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant r1 = method.invoke(o1);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant r2 = method.invoke(o2);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!equals(r1, r2)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // if false an exception will be thown
f5aaa49dba43db0e99f06476534a8749820515dbcsovant STACK.pop();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return false;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant STACK.pop();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } catch (Exception e) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw (RuntimeException) e;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else if (o1 instanceof List) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // Transering into sets whenever ordering is required
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collection l1;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collection l2;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l1 = (List) o1;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l2 = (List) o2;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (l1 != null &&
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l1.size() > 1 &&
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l1.toArray()[0] instanceof DsmlAttr) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collections.sort((List) l1, dsmlAttrCompare);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collections.sort((List) l2, dsmlAttrCompare);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else if (l1 != null &&
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l1.size() > 1 &&
f5aaa49dba43db0e99f06476534a8749820515dbcsovant l1.toArray()[0] instanceof String) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collections.sort((List) l1);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant Collections.sort((List) l2);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant /*
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (((List) o2).size() != l2.size()) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Object o : l2) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant System.out.println("collection2 : " + o);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Object o : (List) o2) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant System.out.println("list2 : " + o);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw (new RuntimeException("object2 size changed"));
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant*/
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (l1.size() != l2.size()) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Object o : l1) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant System.out.println("list1 : " + o);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (Object o : l2) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant System.out.println("list2 : " + o);
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("List size mismatch (received=" + l1.size() + ", expected=" + l2.size() + "): " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant for (int i = 0; i < l1.size(); i++) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // could be optimized :(
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!equals(l1.toArray()[i], l2.toArray()[i])) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // if false an exception will be thown
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return false;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else if (o1 instanceof JAXBElement) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return equals(((JAXBElement) o1).getValue(), ((JAXBElement) o2).getValue());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else if (o1 instanceof String) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // special case in case a DN must be checked
f5aaa49dba43db0e99f06476534a8749820515dbcsovant // This is not a full check for DN but DN.decode(String) needs a DS to run
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (STACK.size() > 0) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant String s = STACK.peek().getName();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (s.equalsIgnoreCase("getDn") ||
f5aaa49dba43db0e99f06476534a8749820515dbcsovant s.equalsIgnoreCase("getMatchedDN")) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant try {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!DN.decode((String) o1).equals(DN.decode((String) o2))) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("DN mismatch : " + o1 + " vs " + o2 + " " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } catch (DirectoryException ex) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("DN mismatch : " + o1 + " vs " + o2 + " " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant// String oo1 = ((String) o1).replace(" ", "");
f5aaa49dba43db0e99f06476534a8749820515dbcsovant// String oo2 = ((String) o2).replace(" ", "");
f5aaa49dba43db0e99f06476534a8749820515dbcsovant// if (!oo1.equalsIgnoreCase(oo2)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant// throw new JAXBCheckerException("DN mismatch : " + o1 + " vs " + o2 + " " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant// }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else if (s.equalsIgnoreCase("getName")) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!((String) o1).equalsIgnoreCase((String) o2)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("Attribute mismatch : " + o1 + " vs " + o2 + " " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!o1.equals(o2)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("String mismatch : " + o1 + " vs " + o2 + " " + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (!o1.equals(o2)) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (STACK.size() > 0) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant String s = STACK.peek().getName();
f5aaa49dba43db0e99f06476534a8749820515dbcsovant if (s.equalsIgnoreCase("getCode")) {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("Error code mismatch : " + LDAPResultCode.toString((Integer) o1) + "[" + o1 + "] vs " + LDAPResultCode.toString((Integer) o2) + "[" + o2 + "]" + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant } else {
f5aaa49dba43db0e99f06476534a8749820515dbcsovant throw new JAXBCheckerException("Object mismatch : [class = " + o1.getClass().getSimpleName() + "]" + buildMessage());
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant
f5aaa49dba43db0e99f06476534a8749820515dbcsovant return true;
f5aaa49dba43db0e99f06476534a8749820515dbcsovant }
f5aaa49dba43db0e99f06476534a8749820515dbcsovant}