/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you 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.axiom.om; | |
import java.util.HashMap; | |
import org.apache.axiom.om.impl.MTOMConstants; | |
import org.apache.axiom.om.util.UUIDGenerator; | |
import org.apache.axiom.soap.SOAP11Constants; | |
import org.apache.axiom.soap.SOAP12Constants; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
/** | |
* Formats options for OM Output. | |
* <p/> | |
* Setting of all the properties in a OMOutputFormat should be done before calling the | |
* getContentType() method. It is advised to set all the properties at the creation time of the | |
* OMOutputFormat and not to change them later. | |
*/ | |
public class OMOutputFormat { | |
private static Log log = LogFactory.getLog(OMOutputFormat.class); | |
private String mimeBoundary = null; | |
private String rootContentId = null; | |
private int nextid = 0; | |
private boolean doOptimize = false; | |
private boolean doingSWA = false; | |
private boolean isSoap11 = true; | |
private int optimizedThreshold = 0; | |
/** Field DEFAULT_CHAR_SET_ENCODING. Specifies the default character encoding scheme to be used. */ | |
public static final String DEFAULT_CHAR_SET_ENCODING = "utf-8"; | |
private String charSetEncoding; | |
private String xmlVersion; | |
private String contentType; | |
private boolean ignoreXMLDeclaration = false; | |
private boolean autoCloseWriter = false; | |
public static final String ACTION_PROPERTY = "action"; | |
HashMap map = null; // Map of generic properties | |
public OMOutputFormat() { | |
} | |
/** | |
* @param key String | |
* @return property or null | |
*/ | |
public Object getProperty(String key) { | |
if (map == null) { | |
return null; | |
} | |
return map.get(key); | |
} | |
/** | |
* @param key String | |
* @param value Object | |
* @return old value or null | |
*/ | |
public Object setProperty(String key, Object value) { | |
if (map == null) { | |
map = new HashMap(); | |
} | |
return map.put(key, value); | |
} | |
/** | |
* @param key | |
* @return true if known key | |
*/ | |
public boolean containsKey(String key) { | |
if (map == null) { | |
return false; | |
} | |
return map.containsKey(key); | |
} | |
public boolean isOptimized() { | |
return doOptimize && !doingSWA; // optimize is disabled if SWA | |
} | |
/** | |
* Return the content-type value that should be written with the message. | |
* (i.e. if optimized, then a multipart/related content-type is returned). | |
* @return content-type value | |
*/ | |
public String getContentType() { | |
String ct = null; | |
if (log.isDebugEnabled()) { | |
log.debug("Start getContentType: " + toString()); | |
} | |
if (contentType == null) { | |
if (isSoap11) { | |
contentType = SOAP11Constants.SOAP_11_CONTENT_TYPE; | |
} else { | |
contentType = SOAP12Constants.SOAP_12_CONTENT_TYPE; | |
} | |
} | |
// If MTOM or SWA, the returned content-type is an | |
// appropriate multipart/related content type. | |
if (isOptimized()) { | |
if (isDoingSWA()) { | |
// If both optimized and SWA, then prefer SWA | |
// for the content type | |
ct = this.getContentTypeForSwA(contentType); | |
} else { | |
// Optimized without SWA is MTOM | |
ct = this.getContentTypeForMTOM(contentType); | |
} | |
} else if (isDoingSWA()) { | |
ct = this.getContentTypeForSwA(contentType); | |
} else { | |
ct = contentType; | |
} | |
if (log.isDebugEnabled()) { | |
log.debug("getContentType= {" + ct + "} " + toString()); | |
} | |
return ct; | |
} | |
/** | |
* Set a raw content-type | |
* (i.e. "text/xml" (SOAP 1.1) or "application/xml" (REST)) | |
* If this method is not invoked, OMOutputFormat will choose | |
* a content-type value consistent with the soap version. | |
* @param c | |
*/ | |
public void setContentType(String c) { | |
contentType = c; | |
} | |
public String getMimeBoundary() { | |
if (mimeBoundary == null) { | |
mimeBoundary = | |
"MIMEBoundary" | |
+ UUIDGenerator.getUUID().replace(':', '_'); | |
} | |
return mimeBoundary; | |
} | |
public String getRootContentId() { | |
if (rootContentId == null) { | |
rootContentId = | |
"0." | |
+ UUIDGenerator.getUUID() | |
+ "@apache.org"; | |
} | |
return rootContentId; | |
} | |
public String getNextContentId() { | |
nextid++; | |
return nextid | |
+ "." | |
+ UUIDGenerator.getUUID() | |
+ "@apache.org"; | |
} | |
/** | |
* Returns the character set encoding scheme. If the value of the charSetEncoding is not set | |
* then the default will be returned. | |
* | |
* @return Returns encoding string. | |
*/ | |
public String getCharSetEncoding() { | |
return this.charSetEncoding; | |
} | |
public void setCharSetEncoding(String charSetEncoding) { | |
this.charSetEncoding = charSetEncoding; | |
} | |
public String getXmlVersion() { | |
return xmlVersion; | |
} | |
public void setXmlVersion(String xmlVersion) { | |
this.xmlVersion = xmlVersion; | |
} | |
public void setSOAP11(boolean b) { | |
isSoap11 = b; | |
} | |
public boolean isSOAP11() { | |
return isSoap11; | |
} | |
public boolean isIgnoreXMLDeclaration() { | |
return ignoreXMLDeclaration; | |
} | |
public void setIgnoreXMLDeclaration(boolean ignoreXMLDeclaration) { | |
this.ignoreXMLDeclaration = ignoreXMLDeclaration; | |
} | |
public void setDoOptimize(boolean b) { | |
doOptimize = b; | |
} | |
public boolean isDoingSWA() { | |
return doingSWA; | |
} | |
public void setDoingSWA(boolean doingSWA) { | |
this.doingSWA = doingSWA; | |
} | |
/** | |
* Generates a Content-Type value for MTOM messages. This is a MIME Multipart/Related | |
* Content-Type value as defined by RFC 2387 and the XOP specification. The generated | |
* header will look like the following: | |
* | |
* Content-Type: multipart/related; boundary=[MIME BOUNDARY VALUE]; | |
* type="application/xop+xml"; | |
* start="[MESSAGE CONTENT ID]"; | |
* start-info="[MESSAGE CONTENT TYPE]"; | |
* | |
* @param SOAPContentType | |
* @return | |
*/ | |
public String getContentTypeForMTOM(String SOAPContentType) { | |
// If an action was set, we need to include it within the value | |
// for the start-info attribute. | |
if (containsKey(ACTION_PROPERTY)) { | |
String action = (String) getProperty(ACTION_PROPERTY); | |
if (action != null && action.length() > 0) { | |
SOAPContentType = SOAPContentType + "; action=\\\"" + action + "\\\""; | |
} | |
} | |
StringBuffer sb = new StringBuffer(); | |
sb.append("multipart/related"); | |
sb.append("; "); | |
sb.append("boundary="); | |
sb.append(getMimeBoundary()); | |
sb.append("; "); | |
sb.append("type=\"" + MTOMConstants.MTOM_TYPE + "\""); | |
sb.append("; "); | |
sb.append("start=\"<").append(getRootContentId()).append(">\""); | |
sb.append("; "); | |
sb.append("start-info=\"").append(SOAPContentType).append("\""); | |
return sb.toString(); | |
} | |
public String getContentTypeForSwA(String SOAPContentType) { | |
StringBuffer sb = new StringBuffer(); | |
sb.append("multipart/related"); | |
sb.append("; "); | |
sb.append("boundary="); | |
sb.append(getMimeBoundary()); | |
sb.append("; "); | |
sb.append("type=\"").append(SOAPContentType).append("\""); | |
sb.append("; "); | |
sb.append("start=\"<").append(getRootContentId()).append(">\""); | |
return sb.toString(); | |
} | |
public boolean isAutoCloseWriter() { | |
return autoCloseWriter; | |
} | |
public void setAutoCloseWriter(boolean autoCloseWriter) { | |
this.autoCloseWriter = autoCloseWriter; | |
} | |
public void setMimeBoundary(String mimeBoundary) { | |
this.mimeBoundary = mimeBoundary; | |
} | |
public void setRootContentId(String rootContentId) { | |
this.rootContentId = rootContentId; | |
} | |
/** | |
* Use toString for logging state of the OMOutputFormat | |
*/ | |
public String toString() { | |
StringBuffer sb = new StringBuffer(); | |
sb.append("OMOutputFormat ["); | |
sb.append(" mimeBoundary ="); | |
sb.append(mimeBoundary); | |
sb.append(" rootContentId="); | |
sb.append(rootContentId); | |
sb.append(" doOptimize="); | |
sb.append(doOptimize); | |
sb.append(" doingSWA="); | |
sb.append(doingSWA); | |
sb.append(" isSOAP11="); | |
sb.append(isSoap11); | |
sb.append(" charSetEncoding="); | |
sb.append(charSetEncoding); | |
sb.append(" xmlVersion="); | |
sb.append(xmlVersion); | |
sb.append(" contentType="); | |
sb.append(contentType); | |
sb.append(" ignoreXmlDeclaration="); | |
sb.append(ignoreXMLDeclaration); | |
sb.append(" autoCloseWriter="); | |
sb.append(autoCloseWriter); | |
// TODO Print all properties | |
sb.append(" actionProperty="); | |
sb.append(getProperty(ACTION_PROPERTY)); | |
sb.append(" optimizedThreshold="); | |
sb.append(optimizedThreshold); | |
sb.append("]"); | |
return sb.toString(); | |
} | |
public void setOptimizedThreshold(int optimizedThreshold) { | |
this.optimizedThreshold = optimizedThreshold; | |
} | |
public int getOptimizedThreshold() { | |
return optimizedThreshold; | |
} | |
} |