| /* |
| * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0, which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package com.sun.enterprise.v3.common; |
| |
| import java.io.OutputStream; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.jvnet.hk2.annotations.Service; |
| |
| import org.glassfish.hk2.api.PerLookup; |
| |
| /** |
| * Represents the action report as XML like this: |
| * <br> |
| * <!-- |
| * Apologies for the formatting - it's necessary for the JavaDoc to be readable |
| * If you are using NetBeans, for example, click anywhere in this comment area to see |
| * the document example clearly in the JavaDoc preview |
| * --> |
| * <code> |
| * <br><action-report description="xxx" exit-code="xxx" [failure-cause="xxx"]> |
| * <br> <message-part message="xxx"> |
| * <br> <property name="xxx" value="xxx"/> |
| * <br> ... |
| * <br> <message-part message="xxx" type="xxx"> |
| * <br> ... |
| * <br> </message-part> |
| * <br> </message-part> |
| * <br> <action-report ...> [for subactions] |
| * <br> ... |
| * <br> </action-report> |
| * <br></action-report> |
| * </code> |
| * |
| * @author tjquinn |
| */ |
| @Service(name="xml") |
| @PerLookup |
| public class XMLActionReporter extends ActionReporter { |
| |
| @Override |
| public void writeReport(OutputStream os) { |
| try { |
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder db = dbf.newDocumentBuilder(); |
| Document d = db.newDocument(); |
| |
| d.appendChild(writeActionReport(d, this)); |
| writeXML(d, os); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| |
| } |
| |
| /** |
| * Creates a new Element representing the XML content describing an |
| * action report. Invokes itself recursively to capture information |
| * about any subactions. |
| * @param owningDocument Document which will own all generated XML content |
| * @param report the ActionReporter to convert to XML content |
| * @return Element for the specified ActionReporter (and any sub-reports) |
| */ |
| private Element writeActionReport(Document owningDocument, ActionReporter report) { |
| Element result = owningDocument.createElement("action-report"); |
| result.setAttribute("description", report.actionDescription); |
| result.setAttribute("exit-code", report.getActionExitCode().name()); |
| if (exception != null) { |
| result.setAttribute("failure-cause", exception.getLocalizedMessage()); |
| } |
| |
| writePart(result, report.getTopMessagePart(), null); |
| for (ActionReporter subReport : report.subActions) { |
| result.appendChild(writeActionReport(owningDocument, subReport)); |
| } |
| return result; |
| } |
| |
| @Override |
| public String getContentType() { |
| return "text/xml"; |
| } |
| |
| private void writePart(Element actionReport, MessagePart part, String childType) { |
| Document d = actionReport.getOwnerDocument(); |
| Element messagePart = d.createElement("message-part"); |
| actionReport.appendChild(messagePart); |
| if (childType != null) { |
| messagePart.setAttribute("type", childType); |
| } |
| |
| for (Map.Entry prop : part.getProps().entrySet()) { |
| Element p = d.createElement("property"); |
| messagePart.appendChild(p); |
| p.setAttribute("name", prop.getKey().toString()); |
| Object value = prop.getValue(); |
| if (value instanceof List) { |
| addListElement(p, (List)value); |
| } else if (value instanceof Map) { |
| addMapElement(p, (Map)value); |
| } else { |
| p.setAttribute("value", prop.getValue().toString()); |
| } |
| } |
| messagePart.setAttribute("message", part.getMessage()); |
| for (MessagePart subPart : part.getChildren()) { |
| writePart(messagePart, subPart, subPart.getChildrenType()); |
| } |
| } |
| |
| private void addListElement(Element parent, List list) { |
| Document d = parent.getOwnerDocument(); |
| Element listElement = d.createElement("list"); |
| parent.appendChild(listElement); |
| |
| for (Object entry : list) { |
| Element entryElement = d.createElement("entry"); |
| listElement.appendChild(entryElement); |
| if (entry instanceof List) { |
| addListElement(entryElement, (List) entry); |
| } else if (entry instanceof Map) { |
| addMapElement(entryElement, (Map) entry); |
| } else { |
| entryElement.setAttribute("value", entry.toString()); |
| } |
| } |
| } |
| |
| private void addMapElement(Element parent, Map map) { |
| Document d = parent.getOwnerDocument(); |
| Element mapElement = d.createElement("map"); |
| parent.appendChild(mapElement); |
| |
| for (Map.Entry entry : (Set<Map.Entry>)map.entrySet()) { |
| Element entryElement = d.createElement("entry"); |
| String key = entry.getKey().toString(); |
| Object value = entry.getValue(); |
| mapElement.appendChild(entryElement); |
| entryElement.setAttribute("key", key); |
| |
| if (value instanceof List) { |
| addListElement(entryElement, (List) value); |
| } else if (value instanceof Map) { |
| addMapElement(entryElement, (Map) value); |
| } else { |
| entryElement.setAttribute("value", value.toString()); |
| } |
| } |
| } |
| |
| private void writeXML(Document doc, OutputStream os) throws TransformerConfigurationException, TransformerException { |
| Source source = new DOMSource(doc); |
| |
| Result result = new StreamResult(os); |
| |
| Transformer xformer = TransformerFactory.newInstance().newTransformer(); |
| xformer.transform(source, result); |
| } |
| } |