org.docx4j.utils.AbstractTraversalUtilVisitorCallback Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docx4j Show documentation
Show all versions of docx4j Show documentation
docx4j is a library which helps you to work with the Office Open
XML file format as used in docx
documents, pptx presentations, and xlsx spreadsheets.
package org.docx4j.utils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
/** @author alberto */
public abstract class AbstractTraversalUtilVisitorCallback extends TraversalUtil.CallbackImpl {
/**
* Get the actual type arguments a child class has used to extend a generic base class.
* based on http://www.artima.com/weblogs/viewpost.jsp?thread=208860
*/
protected Class findClassParameter(Class childClass) {
Map resolvedTypes = new HashMap();
Type type = childClass;
// start walking up the inheritance hierarchy until we hit baseClass
while (! getTypeClass(type).equals(TraversalUtilVisitor.class)) {
if (type instanceof Class) {
// there is no useful information for us in raw types, so just keep going.
type = ((Class) type).getGenericSuperclass();
}
else {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class> rawType = (Class)parameterizedType.getRawType();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
TypeVariable>[] typeParameters = rawType.getTypeParameters();
for (int i = 0; i < actualTypeArguments.length; i++) {
resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
}
if (!rawType.equals(TraversalUtilVisitor.class)) {
type = rawType.getGenericSuperclass();
}
}
}
// finally, for each actual type argument provided to baseClass, determine (if possible)
// the raw class for that type argument.
Type baseType =
(type instanceof Class ?
((Class)type).getTypeParameters()[0] :
((ParameterizedType)type).getActualTypeArguments()[0]);
// resolve types by chasing down type variables.
while (resolvedTypes.containsKey(baseType)) {
baseType = resolvedTypes.get(baseType);
}
return getTypeClass(baseType);
}
protected Class getTypeClass(Type type) {
return (type instanceof Class ?
(Class)type :
(type instanceof ParameterizedType ?
getTypeClass(((ParameterizedType) type).getRawType()) : null));
}
// Depth first
@Override
public void walkJAXBElements(Object parent) {
List children = getChildren(parent);
if (children != null) {
for (Object o : children) {
// if its wrapped in javax.xml.bind.JAXBElement, get its
// value; this is ok, provided the results of the Callback
// won't be marshalled
o = XmlUtils.unwrap(o);
this.apply(o, parent, children);
if (this.shouldTraverse(o)) {
walkJAXBElements(o);
}
}
}
}
@Override
public final List