ReflectionUtils { public static DeepHierarchyElement[] getDeepFieldHierarchy(Class<?> parentClass, String field, HintContainer deepIndexHintContainer) { if (!MappingUtils.isDeepMapping(field)) { MappingUtils.throwMappingException("Field does not contain deep field delimitor"); } StringTokenizer toks = new StringTokenizer(field, DozerConstants.DEEP_FIELD_DELIMITER); Class<?> latestClass = parentClass; DeepHierarchyElement[] hierarchy = new DeepHierarchyElement[toks.countTokens()]; int index = 0; int hintIndex = 0; while (toks.hasMoreTokens()) { String aFieldName = toks.nextToken(); String theFieldName = aFieldName; int collectionIndex = -1; if (aFieldName.contains("[")) { theFieldName = aFieldName.substring(0, aFieldName.indexOf("[")); collectionIndex = Integer.parseInt(aFieldName.substring(aFieldName.indexOf("[") + 1, aFieldName.indexOf("]"))); } PropertyDescriptor propDescriptor = findPropertyDescriptor(latestClass, theFieldName, deepIndexHintContainer); DeepHierarchyElement r = new DeepHierarchyElement(propDescriptor, collectionIndex); if (propDescriptor == null) { MappingUtils.throwMappingException("Exception occurred determining deep field hierarchy for Class --> " + parentClass.getName() + ", Field --> " + field + ". Unable to determine property descriptor for Class --> " + latestClass.getName() + ", Field Name: " + aFieldName); } latestClass = propDescriptor.getPropertyType(); if (toks.hasMoreTokens()) { if (latestClass.isArray()) { latestClass = latestClass.getComponentType(); } else if (Collection.class.isAssignableFrom(latestClass)) { Class<?> genericType = determineGenericsType(parentClass.getClass(), propDescriptor); if (genericType == null && deepIndexHintContainer == null) { MappingUtils .throwMappingException("Hint(s) or Generics not specified. Hint(s) or Generics must be specified for deep mapping with indexed field(s). " + "Exception occurred determining deep field hierarchy for Class --> " + parentClass.getName() + ", Field --> " + field + ". Unable to determine property descriptor for Class --> " + latestClass.getName() + ", Field Name: " + aFieldName); } if (genericType != null) { latestClass = genericType; } else { latestClass = deepIndexHintContainer.getHint(hintIndex); hintIndex += 1; } } } hierarchy[index++] = r; } return hierarchy; } private  ReflectionUtils(); static PropertyDescriptor findPropertyDescriptor(Class<?> objectClass, String fieldName,
                                                            HintContainer deepIndexHintContainer); static DeepHierarchyElement[] getDeepFieldHierarchy(Class<?> parentClass, String field,
                                                               HintContainer deepIndexHintContainer); static Method getMethod(Object obj, String methodName); static Method getMethod(Class<?> clazz, String methodName); static Method findAMethod(Class<?> clazz, String methodName, BeanContainer beanContainer); static PropertyDescriptor[] getPropertyDescriptors(Class<?> objectClass); static Field getFieldFromBean(Class<?> clazz, String fieldName); static Object invoke(Method method, Object obj, Object[] args); static Method getMethod(Class<?> clazz, String name, Class<?>[] parameterTypes); static T newInstance(Class<T> clazz); static Class<?> determineGenericsType(Class<?> parentClazz, PropertyDescriptor propDescriptor); static Class<?> determineGenericsType(Class<?> clazz, Method method, boolean isReadMethod); static Class<?> determineGenericsType(Type type); static Method getNonStandardSetter(Class<?> clazz, String fieldName);  }
@Test(expected = MappingException.class) public void testGetDeepFieldHierarchy_NonDeepField() { ReflectionUtils.getDeepFieldHierarchy(SimpleObj.class, "test", null); }
@Test(expected = MappingException.class) public void testGetDeepFieldHierarchy_NotExists() { ReflectionUtils.getDeepFieldHierarchy(SimpleObj.class, String.valueOf(System.currentTimeMillis()) + "." + String.valueOf(System.currentTimeMillis()), null); }