/* | |
* Copyright 2004,2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.apache.ws.commons.om.impl.llom; | |
import org.apache.ws.commons.om.OMAttribute; | |
import org.apache.ws.commons.om.OMConstants; | |
import org.apache.ws.commons.om.OMElement; | |
import org.apache.ws.commons.om.OMException; | |
import org.apache.ws.commons.om.OMNamespace; | |
import org.apache.ws.commons.om.OMText; | |
import org.apache.ws.commons.om.OMXMLParserWrapper; | |
import org.apache.ws.commons.om.util.Base64; | |
import org.apache.ws.commons.om.util.UUIDGenerator; | |
import org.apache.ws.commons.om.impl.OMOutputImpl; | |
import org.apache.ws.commons.om.impl.llom.mtom.MTOMStAXSOAPModelBuilder; | |
import javax.xml.stream.XMLStreamException; | |
import javax.xml.stream.XMLStreamWriter; | |
import java.io.IOException; | |
import java.io.InputStream; | |
public class OMTextImpl extends OMNodeImpl implements OMText, OMConstants { | |
protected String value = null; | |
protected String mimeType; | |
protected boolean optimize = false; | |
protected boolean isBinary = false; | |
/** | |
* Field contentID for the mime part used when serializing Binary stuff as | |
* MTOM optimized. | |
*/ | |
private String contentID = null; | |
/** | |
* Field dataHandler contains the DataHandler | |
* Declaring as Object to remove the dependency on | |
* Javax.activation.DataHandler | |
*/ | |
private Object dataHandlerObject = null; | |
/** | |
* Field nameSpace used when serializing Binary stuff as MTOM optimized. | |
*/ | |
protected OMNamespace ns = new OMNamespaceImpl( | |
"http://www.w3.org/2004/08/xop/include", "xop"); | |
/** | |
* Field localName used when serializing Binary stuff as MTOM optimized. | |
*/ | |
protected String localName = "Include"; | |
/** | |
* Field attributes used when serializing Binary stuff as MTOM optimized. | |
*/ | |
protected OMAttribute attribute; | |
/** | |
* Constructor OMTextImpl. | |
* | |
* @param s | |
*/ | |
public OMTextImpl(String s) { | |
this.value = s; | |
this.nodeType = TEXT_NODE; | |
} | |
/** | |
* @param s | |
* @param nodeType - OMText can handle CHARACTERS, SPACES, CDATA and ENTITY REFERENCES. | |
* Constants for this can be found in OMNode. | |
*/ | |
public OMTextImpl(String s, int nodeType) { | |
this.value = s; | |
this.nodeType = nodeType; | |
} | |
/** | |
* Constructor OMTextImpl. | |
* | |
* @param parent | |
* @param text | |
*/ | |
public OMTextImpl(OMElement parent, String text) { | |
super(parent); | |
this.value = text; | |
done = true; | |
this.nodeType = TEXT_NODE; | |
} | |
public OMTextImpl(OMElement parent, String text, int nodeType) { | |
super(parent); | |
this.value = text; | |
done = true; | |
this.nodeType = nodeType; | |
} | |
/** | |
* @param s - base64 encoded String representation of Binary | |
* @param mimeType of the Binary | |
*/ | |
public OMTextImpl(String s, String mimeType, boolean optimize) { | |
this(null, s, mimeType, optimize); | |
} | |
/** | |
* @param parent | |
* @param s - | |
* base64 encoded String representation of Binary | |
* @param mimeType of the Binary | |
*/ | |
public OMTextImpl(OMElement parent, String s, String mimeType, | |
boolean optimize) { | |
this(parent, s); | |
this.mimeType = mimeType; | |
this.optimize = optimize; | |
this.isBinary = true; | |
done = true; | |
this.nodeType = TEXT_NODE; | |
} | |
/** | |
* @param dataHandler To send binary optimised content Created programatically. | |
*/ | |
public OMTextImpl(Object dataHandler) { | |
this(dataHandler, true); | |
} | |
/** | |
* @param dataHandler | |
* @param optimize To send binary content. Created progrmatically. | |
*/ | |
public OMTextImpl(Object dataHandler, boolean optimize) { | |
this.dataHandlerObject = dataHandler; | |
this.isBinary = true; | |
this.optimize = optimize; | |
done = true; | |
this.nodeType = TEXT_NODE; | |
} | |
/** | |
* @param contentID | |
* @param parent | |
* @param builder Used when the builder is encountered with a XOP:Include tag | |
* Stores a reference to the builder and the content-id. Supports | |
* deferred parsing of MIME messages. | |
*/ | |
public OMTextImpl(String contentID, OMElement parent, | |
OMXMLParserWrapper builder) { | |
super(parent); | |
this.contentID = contentID; | |
this.optimize = true; | |
this.isBinary = true; | |
this.builder = builder; | |
this.nodeType = TEXT_NODE; | |
} | |
/** | |
* @param omOutput | |
* @throws XMLStreamException | |
*/ | |
public void serialize(OMOutputImpl omOutput) throws XMLStreamException { | |
serializeLocal(omOutput); | |
} | |
/** | |
* Writes the relevant output. | |
* | |
* @param omOutput | |
* @throws XMLStreamException | |
*/ | |
private void writeOutput(OMOutputImpl omOutput) throws XMLStreamException { | |
XMLStreamWriter writer = omOutput.getXmlStreamWriter(); | |
int type = getType(); | |
if (type == TEXT_NODE || type == SPACE_NODE) { | |
writer.writeCharacters(this.getText()); | |
} else if (type == CDATA_SECTION_NODE) { | |
writer.writeCData(this.getText()); | |
} else if (type == ENTITY_REFERENCE_NODE) { | |
writer.writeEntityRef(this.getText()); | |
} | |
} | |
/** | |
* Returns the value. | |
*/ | |
public String getText() throws OMException { | |
if (this.value != null) { | |
return this.value; | |
} else { | |
try { | |
InputStream inStream; | |
inStream = this.getInputStream(); | |
byte[] data; | |
StringBuffer text = new StringBuffer(); | |
do { | |
data = new byte[1024]; | |
int len; | |
while((len = inStream.read(data)) > 0) { | |
byte[] temp = new byte[len]; | |
System.arraycopy(data,0,temp,0,len); | |
text.append(Base64.encode(temp)); | |
} | |
} while (inStream.available() > 0); | |
return text.toString(); | |
} catch (Exception e) { | |
throw new OMException(e); | |
} | |
} | |
} | |
public boolean isOptimized() { | |
return optimize; | |
} | |
public void setOptimize(boolean value) { | |
this.optimize = value; | |
if (value) | |
{ | |
isBinary = true; | |
} | |
} | |
/** | |
* Gets the datahandler. | |
* @return Returns javax.activation.DataHandler | |
*/ | |
public Object getDataHandler() { | |
/* | |
* this should return a DataHandler containing the binary data | |
* reperesented by the Base64 strings stored in OMText | |
*/ | |
if (value != null & isBinary) { | |
return org.apache.ws.commons.attachments.DataHandlerUtils.getDataHandlerFromText(value,mimeType); | |
} else { | |
if (dataHandlerObject == null) { | |
if (contentID == null) { | |
throw new RuntimeException("ContentID is null"); | |
} | |
dataHandlerObject = ((MTOMStAXSOAPModelBuilder) builder) | |
.getDataHandler(contentID); | |
} | |
return dataHandlerObject; | |
} | |
} | |
public String getLocalName() { | |
return localName; | |
} | |
public java.io.InputStream getInputStream() throws OMException { | |
if (isBinary) { | |
if (dataHandlerObject == null) { | |
getDataHandler(); | |
} | |
InputStream inStream; | |
javax.activation.DataHandler dataHandler = (javax.activation.DataHandler)dataHandlerObject; | |
try { | |
inStream = dataHandler.getDataSource().getInputStream(); | |
} catch (IOException e) { | |
throw new OMException( | |
"Cannot get InputStream from DataHandler." + e); | |
} | |
return inStream; | |
} else { | |
throw new OMException("Unsupported Operation"); | |
} | |
} | |
public String getContentID() { | |
if (contentID == null) { | |
contentID = UUIDGenerator.getUUID() | |
+ "@apache.org"; | |
} | |
return this.contentID; | |
} | |
public boolean isComplete() { | |
return done; | |
} | |
public void serializeAndConsume(OMOutputImpl omOutput) | |
throws XMLStreamException { | |
serializeLocal(omOutput); | |
} | |
private void serializeLocal(OMOutputImpl omOutput) throws XMLStreamException { | |
if (!this.isBinary) { | |
writeOutput(omOutput); | |
} else { | |
if (omOutput.isOptimized()) { | |
if (contentID == null) { | |
contentID = omOutput.getNextContentId(); | |
} | |
// send binary as MTOM optimised | |
this.attribute = new OMAttributeImpl("href", | |
new OMNamespaceImpl("", ""), "cid:" + getContentID()); | |
this.serializeStartpart(omOutput); | |
omOutput.writeOptimized(this); | |
omOutput.getXmlStreamWriter().writeEndElement(); | |
} else { | |
omOutput.getXmlStreamWriter().writeCharacters(this.getText()); | |
} | |
} | |
} | |
/* | |
* Methods to copy from OMSerialize utils | |
*/ | |
private void serializeStartpart(OMOutputImpl omOutput) | |
throws XMLStreamException { | |
String nameSpaceName; | |
String writer_prefix; | |
String prefix; | |
XMLStreamWriter writer = omOutput.getXmlStreamWriter(); | |
if (this.ns != null) { | |
nameSpaceName = this.ns.getName(); | |
writer_prefix = writer.getPrefix(nameSpaceName); | |
prefix = this.ns.getPrefix(); | |
if (nameSpaceName != null) { | |
if (writer_prefix != null) { | |
writer | |
.writeStartElement(nameSpaceName, this | |
.getLocalName()); | |
} else { | |
if (prefix != null) { | |
writer.writeStartElement(prefix, this.getLocalName(), | |
nameSpaceName); | |
//TODO FIX ME | |
//writer.writeNamespace(prefix, nameSpaceName); | |
writer.setPrefix(prefix, nameSpaceName); | |
} else { | |
writer.writeStartElement(nameSpaceName, this | |
.getLocalName()); | |
writer.writeDefaultNamespace(nameSpaceName); | |
writer.setDefaultNamespace(nameSpaceName); | |
} | |
} | |
} else { | |
writer.writeStartElement(this.getLocalName()); | |
} | |
} else { | |
writer.writeStartElement(this.getLocalName()); | |
} | |
// add the elements attribute "href" | |
serializeAttribute(this.attribute, omOutput); | |
// add the namespace | |
serializeNamespace(this.ns, omOutput); | |
} | |
/** | |
* Method serializeAttribute. | |
* | |
* @param attr | |
* @param omOutput | |
* @throws XMLStreamException | |
*/ | |
static void serializeAttribute(OMAttribute attr, OMOutputImpl omOutput) | |
throws XMLStreamException { | |
XMLStreamWriter writer = omOutput.getXmlStreamWriter(); | |
// first check whether the attribute is associated with a namespace | |
OMNamespace ns = attr.getNamespace(); | |
String prefix; | |
String namespaceName; | |
if (ns != null) { | |
// add the prefix if it's availble | |
prefix = ns.getPrefix(); | |
namespaceName = ns.getName(); | |
if (prefix != null) { | |
writer.writeAttribute(prefix, namespaceName, attr | |
.getLocalName(), attr.getAttributeValue()); | |
} else { | |
writer.writeAttribute(namespaceName, attr.getLocalName(), attr | |
.getAttributeValue()); | |
} | |
} else { | |
writer.writeAttribute(attr.getLocalName(), attr.getAttributeValue()); | |
} | |
} | |
/** | |
* Method serializeNamespace. | |
* | |
* @param namespace | |
* @param omOutput | |
* @throws XMLStreamException | |
*/ | |
static void serializeNamespace(OMNamespace namespace, OMOutputImpl omOutput) | |
throws XMLStreamException { | |
XMLStreamWriter writer = omOutput.getXmlStreamWriter(); | |
if (namespace != null) { | |
String uri = namespace.getName(); | |
String ns_prefix = namespace.getPrefix(); | |
writer.writeNamespace(ns_prefix, namespace.getName()); | |
writer.setPrefix(ns_prefix, uri); | |
} | |
} | |
/** | |
* A slightly different implementation of the discard method. | |
* | |
* @throws OMException | |
*/ | |
public void discard() throws OMException { | |
if (done) { | |
this.detach(); | |
} else { | |
builder.discard((OMElement) this.parent); | |
} | |
} | |
} |