/* * � Copyright IBM Corp. 2013 * * 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. */ /* * Author: Maire Kehoe (mkehoe@ie.ibm.com) * Date: 27 Apr 2011 * SerializationStructureCompare.java */ package com.ibm.xsp.test.framework.serialize; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.faces.component.StateHolder; import javax.faces.component.UIComponent; import javax.faces.el.MethodBinding; import javax.faces.el.ValueBinding; import javax.faces.model.DataModel; import junit.framework.Assert; import com.ibm.xsp.test.framework.XspTestUtil; /** * Used by {@link ReflectionCompareSerializer} to compare the restored * UIComponent tree to the initial tree. * * @author Maire Kehoe (mkehoe@ie.ibm.com) */ public class SerializationStructureCompare extends Assert{ public static String compareWithFailsResult(SerializationCompareContext context, String message, String methodName, Object object1, Object object2) { // System.out.println("SerializationStructureCompare.compareWithFailsResult() checking "+message); if( null == object1 || null == object2 || context.nonRecursiveComparators.isHasComparator(object1.getClass()) ){ return context.nonRecursiveComparators.applyComparator(context, message, methodName, object1, object2); } if (object1 instanceof UIComponent){ if(context.isSkipMethod(object1.getClass(), methodName)){ return ""; // pass } if( !"getChildren".equals(methodName) && !"getFacets".equals(methodName) ){ return message+" get method should not return a UIComponent\n"; } UIComponent comp1 = (UIComponent)object1; UIComponent comp2 = (UIComponent)object2; return new SerializationFullComparator(context).compareWithFailsResult(comp1, comp2); }else if( object1 instanceof StateHolder ){ // most complex-types are StateHolders, and will be reflection compared context.pushMessage(message +"(" +XspTestUtil.getShortClass(object1)+")"); try{ return new SerializationFullComparator(context).compareWithFailsResult(object1, object2); }finally{ context.popMessage(); } }else if (object1 instanceof Map) { return compareMaps(context, message, methodName, (Map<?,?>)object1, (Map<?,?>)object2); } else if (object1 instanceof List) { return compareLists(context, message, methodName, (List<?>)object1, (List<?>)object2); } else if (object1 instanceof Iterator) { return compareIterators(context, message, methodName, (Iterator<?>)object1, (Iterator<?>)object2); } else if (object1 instanceof Object[]) { return compareObjectArrays(context, message, methodName, (Object[])object1, (Object[])object2); } else if (object1 instanceof MethodBinding) { return compareMethodBindings(context, message, methodName, object1, object2); } else if (object1 instanceof ValueBinding) { return compareValueBindings(context, message, methodName, object1, object2); } else if (object1 instanceof DataModel) { return compareDataModels(context, message, methodName, object1, object2); } else if ("com.ibm.jscript.types.FBSGlobalObject".equals(object1 .getClass().getName())) { // not comparing FBSGlobalObject instances, // as they are directly generated from the Server script libraries // so if the scripts are the same these objects will be the same. } else{ // Package package1 = object1.getClass().getPackage(); // if( null != package1 && package1.getName().startsWith("xsp.") ){ // // not compare the test beans. // return; // } System.out.println(message + " (Unhandled Class) -> " + object1.getClass().getName()); } return ""; } private static String compareDataModels( SerializationCompareContext context, String message, String methodName, Object object1, Object object2 ){ DataModel dataModel1 = (DataModel)object1; DataModel dataModel2 = (DataModel)object2; String fails = ""; fails += context.nonRecursiveComparators.applyComparator(context, message+".getClass()", "getClass", dataModel1.getClass(), dataModel2.getClass()); if( fails.length() > 0 ){ return fails; } message += "(" +XspTestUtil.getShortClass(dataModel1)+")"; Object rowCount1; try{ rowCount1 = dataModel1.getRowCount(); }catch (Exception e) { rowCount1 = e; } Object rowCount2; try { rowCount2 = dataModel2.getRowCount(); } catch (Exception e) { rowCount2 = e; } fails += context.nonRecursiveComparators.applyComparator(context, message+" getRowCount()", "getRowCount", rowCount1, rowCount2); if( fails.length() > 0 ){ return fails; } if( rowCount1 instanceof Exception || rowCount2 instanceof Exception ){ // exception thrown return fails; } int count = (Integer)rowCount1; // check each row in the datamodel... for(int i = 0; i < count; i++){ dataModel1.setRowIndex(i); dataModel2.setRowIndex(i); fails += compareWithFailsResult(context, message + "[" +i+"].getRowData()", "getRowData", dataModel1.getRowData(), dataModel2.getRowData() ); if( fails.length() > 0 ){ return fails; } } return fails; } // end compareDataModels private static String compareIterators(SerializationCompareContext context, String message, String methodName, Iterator<?> iterator1, Iterator<?> iterator2) { String fails =""; int i = 0; while (iterator1.hasNext() || iterator2.hasNext()) { fails += compareWithFailsResult(context, message + "[" +i+"].hasNext()", "hasNext", iterator1.hasNext(), iterator2.hasNext()); Object value1 = iterator1.next(); Object value2 = iterator2.next(); fails += compareWithFailsResult(context, message + "[" +i+"]", methodName, value1, value2); if( fails.length() > 0 ){ return fails; } i++; } return fails; } private static String compareLists(SerializationCompareContext context, String message, String methodName, List<?> list1, List<?> list2) { String fails = ""; if (list1.size() != list2.size()) { fails += compareWithFailsResult(context, message + ".size()", "size", list1.size(), list1.size()); return fails; } for (int i=0; i<list1.size(); i++) { Object value1 = list1.get(i); Object value2 = list2.get(i); fails += compareWithFailsResult(context, message + "["+i+"]", methodName, value1, value2); if( fails.length() > 0 ){ return fails; } } return fails; } private static String compareMaps(SerializationCompareContext context, String message, String methodName, Map<?,?> map1, Map<?,?> map2) { if( "getTransientMap".equals(methodName) ){ // not compare the contents of the UIViewRootEx transient Maps return ""; } if( map1.getClass().getName().endsWith("RequestHeaderValuesMap") || map1.getClass().getName().endsWith("RequestHeaderMap") ){ // not compare request header maps returned by a value binding // as .size() throws an UnsupportedOperationException return ""; } String map1ClassNm = map1.getClass().getName(); if( map1ClassNm.endsWith("RequestMap") && map1ClassNm.equals(map2.getClass().getName())){ // do not compare the contents of the request maps. return ""; } String fails =""; if (map1.size() != map2.size()) { fails += compareWithFailsResult(context, message + ".size()", "size", map1.size(), map2.size()); return fails; } for (Map.Entry<?, ?> pair : map1.entrySet()) { Object key = pair.getKey(); Object value1 = pair.getValue(); Object value2 = map2.get(key); fails += compareWithFailsResult(context, message + "(Map)[key="+key+"]", methodName, value1, value2); if( fails.length() > 0 ){ return fails; } } return fails; } private static String compareMethodBindings( SerializationCompareContext context, String message, String methodName, Object object1, Object object2 ){ MethodBinding mb1 = (MethodBinding)object1; MethodBinding mb2 = (MethodBinding)object2; String expr1 = mb1.getExpressionString(); String expr2 = mb2.getExpressionString(); String fails = ""; fails += context.nonRecursiveComparators.applyComparator(context, message+"(MethodBinding).getExpressionString()", "getExpressionString", expr1, expr2); return fails; } private static String compareObjectArrays( SerializationCompareContext context, String message, String methodName, Object[] objArr1, Object[] objArr2) { String fails = ""; if(objArr1.length != objArr2.length){ fails += context.nonRecursiveComparators.applyComparator(context, message+"(Object[]).length", "length", objArr1.length, objArr2.length); return fails; } for(int i = 0; i < objArr1.length; i++){ fails += compareWithFailsResult(context, message + "[" +i+"]", methodName, objArr1[i], objArr2[i]); if( fails.length() > 0 ){ return fails; } } return fails; } private static String compareValueBindings(SerializationCompareContext context, String message, String methodName, Object object1, Object object2){ ValueBinding vb1 = (ValueBinding)object1; ValueBinding vb2 = (ValueBinding)object2; String expr1 = vb1.getExpressionString(); String expr2 = vb2.getExpressionString(); String fails = ""; fails += context.nonRecursiveComparators.applyComparator(context, message+"(ValueBinding).getExpressionString()", "getExpressionString", expr1, expr2); return fails; // assertEquals(message + " ValueBinding type mismatch: " + // ((ValueBinding)object1).getType(context.createContext) + " -> " + // ((ValueBinding)object2).getType(context.restoreContext), // ((ValueBinding)object1).getType(context.createContext), // ((ValueBinding)object2).getType(context.restoreContext) // ); } }