private void serializeValue(final HttpServletResponse pResponse, Object value) throws TransformerException, IOException, FactoryConfigurationError { if (value instanceof Source) { setContentType(pResponse, "application/binary"); // Unknown content type Sources.writeToStream((Source) value, pResponse.getOutputStream()); } else if (value instanceof Node) { pResponse.setContentType("text/xml"); Sources.writeToStream(new DOMSource((Node) value), pResponse.getOutputStream()); } else if (value instanceof XmlSerializable) { pResponse.setContentType("text/xml"); XMLOutputFactory factory = XMLOutputFactory.newInstance(); factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); try { XmlWriter out = XmlStreaming.newWriter( pResponse.getOutputStream(), pResponse.getCharacterEncoding(), true); try { out.startDocument(null, null, null); ((XmlSerializable) value).serialize(out); out.endDocument(); } finally { out.close(); } } catch (XmlException e) { throw new TransformerException(e); } } else if (value instanceof Collection) { final XmlElementWrapper annotation = getElementWrapper(); if (annotation != null) { setContentType(pResponse, "text/xml"); try (OutputStream outStream = pResponse.getOutputStream()) { writeCollection( outStream, getGenericReturnType(), (Collection<?>) value, getQName(annotation)); } } } else if (value instanceof CharSequence) { setContentType(pResponse, "text/plain"); pResponse.getWriter().append((CharSequence) value); } else { if (value != null) { try { final JAXBContext jaxbContext = JAXBContext.newInstance(getReturnType()); setContentType(pResponse, "text/xml"); final JAXBSource jaxbSource = new JAXBSource(jaxbContext, value); Sources.writeToStream(jaxbSource, pResponse.getOutputStream()); } catch (final JAXBException e) { throw new MessagingException(e); } } } }
@NotNull @Override public SimpleAdapter marshal(@NotNull final XmlSerializable v) throws Exception { final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); final Document document = dbf.newDocumentBuilder().newDocument(); final DocumentFragment content = document.createDocumentFragment(); final XMLOutputFactory xof = XMLOutputFactory.newFactory(); final XMLStreamWriter out = xof.createXMLStreamWriter(new DOMResult(content)); v.serialize(XmlStreaming.newWriter(new DOMResult(content))); final int childCount = content.getChildNodes().getLength(); if (childCount == 0) { return new SimpleAdapter(); } else if (childCount == 1) { final SimpleAdapter result = new SimpleAdapter(); final Node child = content.getFirstChild(); if (child instanceof Element) { result.setAttributes(child.getAttributes()); for (Node child2 = child.getFirstChild(); child2 != null; child2 = child2.getNextSibling()) { result.children.add(child2); } } else { result.children.add(child); } return result; } else { // More than one child final SimpleAdapter result = new SimpleAdapter(); for (Node child = content.getFirstChild(); child != null; child = child.getNextSibling()) { result.children.add(child); } return result; } }
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); } }