001: /*
002: * ChainBuilder ESB
003: * Visual Enterprise Integration
004: *
005: * Copyright (C) 2007 Bostech Corporation
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the
009: * Free Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
014: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
015: * for more details.
016: *
017: * You should have received a copy of the GNU General Public License along with
018: * this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: *
022: * $Id: DOMAxiomBuilder.java 10952 2007-12-13 21:22:19Z mpreston $
023: */
024: package com.bostechcorp.cbesb.runtime.component.http.marshallers.axiom;
025:
026: import java.util.HashMap;
027:
028: import javax.activation.DataHandler;
029: import javax.jbi.messaging.MessagingException;
030: import javax.xml.transform.Source;
031: import javax.xml.transform.Transformer;
032: import javax.xml.transform.TransformerConfigurationException;
033: import javax.xml.transform.TransformerException;
034: import javax.xml.transform.TransformerFactory;
035: import javax.xml.transform.dom.DOMResult;
036: import javax.xml.transform.dom.DOMSource;
037:
038: import org.apache.axiom.om.OMAbstractFactory;
039: import org.apache.axiom.om.OMElement;
040: import org.apache.axiom.om.OMFactory;
041: import org.apache.axiom.om.OMNamespace;
042: import org.apache.axiom.om.OMNode;
043: import org.apache.axiom.om.OMText;
044: import org.apache.axiom.om.impl.OMNodeEx;
045: import org.apache.commons.logging.Log;
046: import org.apache.commons.logging.LogFactory;
047: import org.w3c.dom.Attr;
048: import org.w3c.dom.Document;
049: import org.w3c.dom.Element;
050: import org.w3c.dom.NamedNodeMap;
051: import org.w3c.dom.Node;
052: import org.w3c.dom.Text;
053:
054: /**
055: * A specialized IAxiomBuilder to be used when the Source is a DOMSource.
056: * This should provide better performance than using the more general case
057: * SAXAxiomBuilder that would require serializing the DOMSource and re-parsing.
058: */
059: public class DOMAxiomBuilder implements IAxiomBuilder {
060:
061: protected final transient Log logger = LogFactory
062: .getLog(getClass());
063:
064: private boolean useMTOM = false;
065: private boolean useSwA = false;
066:
067: // private OMFactory factory = DOOMAbstractFactory.getOMFactory();
068: private OMFactory factory = OMAbstractFactory.getOMFactory();
069:
070: private HashMap<String, DataHandler> inputAttachments;
071: private HashMap<String, DataHandler> outputAttachments;
072:
073: private HashMap<String, OMNamespace> omNamespaceMap;
074:
075: /* (non-Javadoc)
076: * @see com.bostechcorp.cbesb.runtime.component.http.marshallers.axiom.IAxiomBuilder#getOMTree(javax.xml.transform.Source, java.util.HashMap, boolean, boolean)
077: */
078: public OMElement getOMTree(Source source,
079: HashMap<String, DataHandler> attachments, boolean useMTOM,
080: boolean useSwA) throws MessagingException {
081: this .inputAttachments = attachments;
082: this .outputAttachments = new HashMap<String, DataHandler>();
083: this .useMTOM = useMTOM;
084: this .useSwA = useSwA;
085:
086: DOMSource domSrc = sourceToDOMSource(source);
087:
088: Node node = (domSrc).getNode();
089: Element rootElement;
090: if (node instanceof Document) {
091: rootElement = ((Document) node).getDocumentElement();
092: } else {
093: rootElement = (Element) node;
094: }
095:
096: omNamespaceMap = new HashMap<String, OMNamespace>();
097: OMElement omRoot = DomElementToOMElement(rootElement);
098: ((OMNodeEx) omRoot).setComplete(true);
099: return omRoot;
100: }
101:
102: /* (non-Javadoc)
103: * @see com.bostechcorp.cbesb.runtime.component.http.marshallers.axiom.IAxiomBuilder#getOutputAttachments()
104: */
105: public HashMap<String, DataHandler> getOutputAttachments() {
106:
107: return outputAttachments;
108: }
109:
110: private OMElement DomElementToOMElement(Element domElement) {
111: String namespaceURI = domElement.getNamespaceURI();
112: String prefix = domElement.getPrefix();
113: String localName = domElement.getLocalName();
114: // logger.debug("Namespace: '" + namespaceURI + "' prefix: '" + prefix + "' localName: '" + localName + "'");
115:
116: OMNamespace omNamespace = null;
117: if (namespaceURI != null) {
118: if (omNamespaceMap.containsKey(namespaceURI)) {
119: omNamespace = omNamespaceMap.get(namespaceURI);
120: } else {
121: omNamespace = factory.createOMNamespace(namespaceURI,
122: prefix);
123: omNamespaceMap.put(namespaceURI, omNamespace);
124: }
125: }
126:
127: OMElement omElement = factory.createOMElement(localName,
128: omNamespace);
129:
130: NamedNodeMap attributes = domElement.getAttributes();
131: for (int i = 0; i < attributes.getLength(); i++) {
132: Attr attribute = (Attr) attributes.item(i);
133: String attrLocalName = attribute.getLocalName();
134: String attrNamespace = attribute.getNamespaceURI();
135: if (attrLocalName == null) {
136: attrLocalName = attribute.getNodeName();
137: }
138: String attrValue = attribute.getValue();
139: if (attrLocalName != null) {
140: omElement.addAttribute(attrLocalName, attrValue,
141: omElement.findNamespace(attrNamespace, null));
142: }
143: if (useSwA) {
144: DataHandler dh = getAttachment(attrValue);
145: if (dh != null) {
146: outputAttachments.put(attrValue, dh);
147: }
148: }
149: }
150:
151: Node domChild = domElement.getFirstChild();
152: OMNode previousChild = null;
153: while (domChild != null) {
154: if (domChild instanceof Element) {
155: OMElement currentChild = DomElementToOMElement((Element) domChild);
156: if (previousChild != null) {
157: ((OMNodeEx) previousChild)
158: .setNextOMSibling(currentChild);
159: ((OMNodeEx) currentChild)
160: .setPreviousOMSibling(previousChild);
161: }
162: omElement.addChild(currentChild);
163: ((OMNodeEx) currentChild).setParent(omElement);
164: ((OMNodeEx) omElement).setComplete(true);
165: previousChild = currentChild;
166: } else if (domChild instanceof Text) {
167: String text = ((Text) domChild).getData();
168: OMText node;
169: DataHandler dh = null;
170: if (useMTOM || useSwA) {
171: dh = getAttachment(text);
172: if (dh != null) {
173: outputAttachments.put(text, dh);
174: }
175: }
176: if (useMTOM && dh != null) {
177: node = factory.createOMText(dh, true);
178: } else {
179: node = factory.createOMText(text);
180: }
181: omElement.addChild(node);
182: }
183:
184: domChild = domChild.getNextSibling();
185: }
186:
187: return omElement;
188: }
189:
190: private DataHandler getAttachment(String contentId) {
191: if (inputAttachments.containsKey(contentId)) {
192: return inputAttachments.get(contentId);
193: } else if (contentId.startsWith("cid:")
194: && inputAttachments.containsKey(contentId.substring(4))) {
195: return inputAttachments.get(contentId.substring(4));
196: }
197: return null;
198: }
199:
200: private DOMSource sourceToDOMSource(Source src) {
201: if (src instanceof DOMSource) {
202: return (DOMSource) src;
203: } else {
204: try {
205: TransformerFactory tf = TransformerFactory
206: .newInstance();
207: Transformer t = tf.newTransformer();
208: DOMResult dr = new DOMResult();
209: t.transform(src, dr);
210: return new DOMSource(dr.getNode());
211: } catch (TransformerConfigurationException e) {
212: logger
213: .error("Caught exception creating DOMSource: ",
214: e);
215: } catch (TransformerException e) {
216: logger
217: .error("Caught exception creating DOMSource: ",
218: e);
219: }
220: }
221: return null;
222: }
223: }
|