private void addType(Type cls, boolean allowArray) { if (cls instanceof Class) { if (globalAdapters.contains(cls)) { return; } if (((Class<?>) cls).isArray() && !allowArray) { addClass(((Class<?>) cls).getComponentType()); } else { addClass((Class<?>) cls); } } else if (cls instanceof ParameterizedType) { final ParameterizedType parameterizedType = (ParameterizedType) cls; addType(parameterizedType.getRawType()); if (!parameterizedType.getRawType().equals(Enum.class)) { for (Type t2 : parameterizedType.getActualTypeArguments()) { if (shouldTypeBeAdded(t2, parameterizedType)) { addType(t2); } } } } else if (cls instanceof GenericArrayType) { Class<?> ct; GenericArrayType gt = (GenericArrayType) cls; Type componentType = gt.getGenericComponentType(); if (componentType instanceof Class) { ct = (Class<?>) componentType; } else { TypeVariable<?> tv = (TypeVariable<?>) componentType; Type[] bounds = tv.getBounds(); if (bounds != null && bounds.length == 1) { if (bounds[0] instanceof Class) { ct = (Class<?>) bounds[0]; } else { throw new IllegalArgumentException("Unable to determine type for: " + tv); } } else { throw new IllegalArgumentException("Unable to determine type for: " + tv); } } ct = Array.newInstance(ct, 0).getClass(); addClass(ct); } else if (cls instanceof WildcardType) { for (Type t : ((WildcardType) cls).getUpperBounds()) { addType(t); } for (Type t : ((WildcardType) cls).getLowerBounds()) { addType(t); } } else if (cls instanceof TypeVariable) { for (Type t : ((TypeVariable<?>) cls).getBounds()) { addType(t); } } }
private void addClass(Class<?> cls) { if (Throwable.class.isAssignableFrom(cls)) { if (!Throwable.class.equals(cls) && !Exception.class.equals(cls)) { walkReferences(cls); } addClass(String.class); } else { cls = JAXBUtils.getValidClass(cls); if (null != cls) { if (classes.contains(cls)) { return; } if (!cls.isInterface()) { classes.add(cls); } XmlSeeAlso xsa = cls.getAnnotation(XmlSeeAlso.class); if (xsa != null) { for (Class<?> c : xsa.value()) { addClass(c); } } XmlJavaTypeAdapter xjta = cls.getAnnotation(XmlJavaTypeAdapter.class); if (xjta != null) { // has an adapter. We need to inspect the adapter and then // return as the adapter will handle the superclass // and interfaces and such Type t = getTypeFromXmlAdapter(xjta); if (t != null) { addType(t); } return; } if (cls.getSuperclass() != null) { // JAXB should do this, but it doesn't always. // in particular, older versions of jaxb don't addClass(cls.getSuperclass()); } if (!cls.isInterface()) { walkReferences(cls); } } } }
@Override public void begin(MessagePartInfo part) { Class<?> clazz = part.getTypeClass(); if (clazz == null) { return; } if (Exception.class.isAssignableFrom(clazz)) { // exceptions are handled special, make sure we mark it part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION", Boolean.TRUE); } boolean isFromWrapper = part.getMessageInfo().getOperation().isUnwrapped(); if (isFromWrapper && !Boolean.TRUE.equals(part.getProperty("messagepart.isheader"))) { UnwrappedOperationInfo uop = (UnwrappedOperationInfo) part.getMessageInfo().getOperation(); OperationInfo op = uop.getWrappedOperation(); MessageInfo inf = null; if (uop.getInput() == part.getMessageInfo()) { inf = op.getInput(); } else if (uop.getOutput() == part.getMessageInfo()) { inf = op.getOutput(); } if (inf != null && inf.getMessagePart(0).getTypeClass() != null) { // if the wrapper has a type class, we don't need to do anything // as everything would have been discovered when walking the // wrapper type (unless it's a header which wouldn't be in the wrapper) return; } } if (isFromWrapper && clazz.isArray() && !Byte.TYPE.equals(clazz.getComponentType())) { clazz = clazz.getComponentType(); } Annotation[] a = (Annotation[]) part.getProperty("parameter.annotations"); checkForAdapter(clazz, a); Type genericType = (Type) part.getProperty("generic.type"); if (genericType != null) { boolean isList = Collection.class.isAssignableFrom(clazz); if (isFromWrapper) { if (genericType instanceof Class && ((Class<?>) genericType).isArray()) { Class<?> cl2 = (Class<?>) genericType; if (cl2.isArray() && !Byte.TYPE.equals(cl2.getComponentType())) { genericType = cl2.getComponentType(); } addType(genericType); } else if (!isList) { addType(genericType); } } else { addType(genericType, true); } if (isList && genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; if (pt.getActualTypeArguments().length > 0 && pt.getActualTypeArguments()[0] instanceof Class) { Class<? extends Object> arrayCls = Array.newInstance((Class<?>) pt.getActualTypeArguments()[0], 0).getClass(); clazz = arrayCls; part.setTypeClass(clazz); if (isFromWrapper) { addType(clazz.getComponentType(), true); } } else if (pt.getActualTypeArguments().length > 0 && pt.getActualTypeArguments()[0] instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) pt.getActualTypeArguments()[0]; gat.getGenericComponentType(); Class<? extends Object> arrayCls = Array.newInstance((Class<?>) gat.getGenericComponentType(), 0).getClass(); clazz = Array.newInstance(arrayCls, 0).getClass(); part.setTypeClass(clazz); if (isFromWrapper) { addType(clazz.getComponentType(), true); } } } if (isFromWrapper && isList) { clazz = null; } } if (clazz != null) { if (!isFromWrapper && clazz.getAnnotation(XmlRootElement.class) == null && clazz.getAnnotation(XmlType.class) != null && StringUtils.isEmpty(clazz.getAnnotation(XmlType.class).name())) { Object ref = JAXBClassLoaderUtils.createTypeReference(part.getName(), clazz); if (ref != null) { typeReferences.add(ref); } } addClass(clazz); } }
void addClass(Class<?> claz) { if (Throwable.class.isAssignableFrom(claz)) { if (!Throwable.class.equals(claz) && !Exception.class.equals(claz)) { walkReferences(claz); } addClass(String.class); } else if (claz.getName().startsWith("java.") || claz.getName().startsWith("javax.")) { return; } else { Class<?> cls = JAXBUtils.getValidClass(claz); if (cls == null && ReflectionUtil.getDeclaredConstructors(claz).length > 0 && !Modifier.isAbstract(claz.getModifiers())) { if (LOG.isLoggable(Level.INFO)) { LOG.info( "Class " + claz.getName() + " does not have a default constructor which JAXB requires."); } // there is no init(), but other constructors Object factory = createFactory(claz, ReflectionUtil.getDeclaredConstructors(claz)[0]); unmarshallerProperties.put("com.sun.xml.bind.ObjectFactory", factory); cls = claz; } if (null != cls) { if (classes.contains(cls)) { return; } if (!cls.isInterface()) { classes.add(cls); } XmlSeeAlso xsa = cls.getAnnotation(XmlSeeAlso.class); if (xsa != null) { for (Class<?> c : xsa.value()) { addClass(c); } } XmlJavaTypeAdapter xjta = cls.getAnnotation(XmlJavaTypeAdapter.class); if (xjta != null) { // has an adapter. We need to inspect the adapter and then // return as the adapter will handle the superclass // and interfaces and such Type t = Utils.getTypeFromXmlAdapter(xjta); if (t != null) { addType(t); } return; } if (cls.getSuperclass() != null) { // JAXB should do this, but it doesn't always. // in particular, older versions of jaxb don't addClass(cls.getSuperclass()); } if (!cls.isInterface()) { walkReferences(cls); } } } }