private void writeCollection( final OutputStream outputStream, final Type collectionType, final Collection<?> collection, final QName outerTagName) { final Class<?> rawType; if (collectionType instanceof ParameterizedType) { final ParameterizedType returnType = (ParameterizedType) collectionType; rawType = (Class<?>) returnType.getRawType(); } else if (collectionType instanceof Class<?>) { rawType = (Class<?>) collectionType; } else if (collectionType instanceof WildcardType) { final Type[] UpperBounds = ((WildcardType) collectionType).getUpperBounds(); if (UpperBounds.length > 0) { rawType = (Class<?>) UpperBounds[0]; } else { rawType = Object.class; } } else if (collectionType instanceof TypeVariable) { final Type[] UpperBounds = ((TypeVariable<?>) collectionType).getBounds(); if (UpperBounds.length > 0) { rawType = (Class<?>) UpperBounds[0]; } else { rawType = Object.class; } } else { throw new IllegalArgumentException("Unsupported type variable"); } Class<?> elementType; if (Collection.class.isAssignableFrom(rawType)) { final Type[] paramTypes = Types.getTypeParametersFor(Collection.class, collectionType); elementType = Types.toRawType(paramTypes[0]); if (elementType.isInterface()) { // interfaces not supported by jaxb elementType = Types.commonAncestor(collection); } } else { elementType = Types.commonAncestor(collection); } try { // As long as JAXB is an option, we have to know that this is a StAXWriter as JAXB needs to // write to that. try (XmlWriter xmlWriter = XmlStreaming.newWriter(outputStream, "UTF-8")) { Marshaller marshaller = null; XmlWriterUtil.smartStartTag(xmlWriter, outerTagName); for (Object item : collection) { if (item != null) { if (item instanceof XmlSerializable) { ((XmlSerializable) item).serialize(xmlWriter); } else if (item instanceof Node) { XmlWriterUtil.serialize(xmlWriter, (Node) item); } else { if (marshaller == null) { JAXBContext jaxbcontext = null; if (elementType == null) { jaxbcontext = newJAXBContext(JAXBCollectionWrapper.class); } else { jaxbcontext = newJAXBContext(JAXBCollectionWrapper.class, elementType); } marshaller = jaxbcontext.createMarshaller(); } marshaller.marshal(item, (XMLStreamWriter) getDelegateMethod().invoke(xmlWriter)); } } } XmlWriterUtil.endTag(xmlWriter, outerTagName); } } catch (Throwable e) { throw new MessagingException(e); } }
private Object getParam( final Class<?> pClass, final String pName, final ParamType pType, final String pXpath, final HttpMessage pMessage) throws XmlException { Object result = null; switch (pType) { case GET: result = getParamGet(pName, pMessage); break; case POST: result = getParamPost(pName, pMessage); break; case QUERY: result = getParamGet(pName, pMessage); if (result == null) { result = getParamPost(pName, pMessage); } break; case VAR: result = mPathParams.get(pName); break; case XPATH: result = getParamXPath(pClass, pXpath, pMessage.getBody()); break; case BODY: result = getBody(pClass, pMessage); break; case ATTACHMENT: result = getAttachment(pClass, pName, pMessage); break; case PRINCIPAL: { final Principal principal = pMessage.getUserPrincipal(); if (pClass.isAssignableFrom(String.class)) { result = principal.getName(); } else { result = principal; } break; } } // XXX generizice this and share the same approach to unmarshalling in ALL code // TODO support collection/list parameters if ((result != null) && (!pClass.isInstance(result))) { if ((Types.isPrimitive(pClass) || (Types.isPrimitiveWrapper(pClass))) && (result instanceof String)) { try { result = Types.parsePrimitive(pClass, ((String) result)); } catch (NumberFormatException e) { throw new HttpResponseException( HttpServletResponse.SC_BAD_REQUEST, "The argument given is invalid", e); } } else if (Enum.class.isAssignableFrom(pClass)) { @SuppressWarnings({"rawtypes"}) final Class clazz = pClass; @SuppressWarnings("unchecked") final Enum<?> tmpResult = Enum.valueOf(clazz, result.toString()); result = tmpResult; } else if (result instanceof Node) { XmlDeserializer factory = pClass.getAnnotation(XmlDeserializer.class); if (factory != null) { try { result = factory .value() .newInstance() .deserialize(XmlStreaming.newReader(new DOMSource((Node) result))); } catch (IllegalAccessException | InstantiationException e) { throw new XmlException(e); } } else { result = JAXB.unmarshal(new DOMSource((Node) result), pClass); } } else { final String s = result.toString(); // Only wrap when we don't start with < final char[] requestBody = (s.startsWith("<") ? s : "<wrapper>" + s + "</wrapper>").toCharArray(); if (requestBody.length > 0) { result = JAXB.unmarshal(new CharArrayReader(requestBody), pClass); } else { result = null; } } } return result; }