blob: b022558019609776a3c22061d1e8c8dc21eda86c [file] [log] [blame]
/*******************************************************************************
*
* Copyright (c) 2002-2003 IBM Corporation, Beacon Information Technology Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* BeaconIT - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsi.internal.core.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.util.Vector;
import java.util.StringTokenizer;
import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.log.MimePart;
import org.eclipse.wst.wsi.internal.core.log.MimeParts;
import org.eclipse.wst.wsi.internal.core.log.impl.MimePartImpl;
import org.eclipse.wst.wsi.internal.core.log.impl.MimePartsImpl;
import org.eclipse.wst.wsi.internal.core.profile.ProfileAssertions;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
/**
* General set of utilities.
*/
public final class Utils
{
public static final byte CR = (byte) '\r';
public static final byte LF = (byte) '\n';
/**
* Common timestamp format.
*/
// public static final SimpleDateFormat timestampFormat = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
public static final SimpleDateFormat timestampFormat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
/**
* Basic date format.
*/
public static final SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd");
/**
* Wrapper method for error logging;
* for now it just goes to stderr.
* @param inError an error message.
*/
public final static void logError(String inError)
{
System.err.println("Error: " + inError);
}
/**
* Get exception information as a string.
* @param throwable a Throwable object.
* @return exception information as a string.
*/
public final static String getExceptionDetails(Throwable throwable)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println("Exception: ");
throwable.printStackTrace(pw);
return sw.toString();
}
/**
* Get current date and time as a timestamp.
* @return urrent date and time as a timestamp.
*/
public static String getTimestamp()
{
// Use GMT timezone
//timestampFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
timestampFormat.setTimeZone(TimeZone.getDefault());
// Return timestamp
return timestampFormat.format(new Date());
}
/**
* Get current date for default time zone.
* @return current date for default time zone.
*/
public static String getDate()
{
// Use GMT timezone
dateFormat.setTimeZone(TimeZone.getDefault());
// Return date
return dateFormat.format(new Date());
}
/**
* Get HTTP status code.
* @param httpHeaders HTTP headers.
* @return HTTP status code.
* @throws WSIException if the status code in http headers was not found.
*/
public static String getHTTPStatusCode(String httpHeaders)
throws WSIException
{
String statusCode = null;
if (httpHeaders.startsWith("HTTP"))
{
// Get location of status code
int index = httpHeaders.indexOf(" ");
int index2 = httpHeaders.indexOf(" ", index + 1);
if ((index == -1) || (index2 == -1))
{
throw new WSIException(
"Could not find status code in http headers: [" + httpHeaders + "].");
}
else
{
statusCode = httpHeaders.substring(index + 1, index2);
}
}
else
{
throw new WSIException(
"Could not find status code in http headers: [" + httpHeaders + "].");
}
// Return status code
return statusCode;
}
/**
* Get HTTP headers from a full message.
* @param fullMessage a message.
* @return HTTP headers from a full message.
*/
public static String getHTTPHeaders(String fullMessage)
{
//String httpHeaders = null;
// Try looking for the double newline
int index = fullMessage.indexOf("\r\n\r\n");
if (index != -1)
{
index += 4;
}
else
{
// check for case "\r\r...\r\n\r\r...\n"
// Note the index that is returned points to the first character
// immediatedly following the first occurence of the CRLFCRLF.
index = getFirstCRLFCRLF(fullMessage);
if (index == -1)
{
logError(
"Unable to parse HTTP message to find headers. Full message: "
+ fullMessage);
return "x-WSI-Test-Tool-Error: Couldn't find headers. Full message: ["
+ fullMessage
+ "].";
}
}
// Return HTTP headers
return fullMessage.substring(0, index);
}
/**
* Get SOAP message from a full message.
* @param fullMessage a message.
* @return SOAP message from a full message.
*/
public static String getContent(String fullMessage)
{
String message = "";
// Find start of message
int index = fullMessage.indexOf("\r\n\r\n");
if (index != -1)
{
index += 4;
}
else
{
// check for case "\r\r...\r\n\r\r...\n"
// Note the index that is returned points to the first character
// immediatedly following the first occurence of the CRLFCRLF.
index = getFirstCRLFCRLF(fullMessage);
}
if (index < 0)
{
// If we couldn't find the end of the HTTP headers or the start of the message, then show error
logError(
"Unable to parse message to get content. Full message: "
+ fullMessage);
message =
"x-WSI-Test-Tool-Error: Couldn't find message content. Full message: ["
+ fullMessage
+ "].";
}
// If the index is greater than the length, then there is no message content
else if (index >= fullMessage.length())
{
message = "";
}
// Else get the message content
else
{
message = fullMessage.substring(index);
}
// Return SOAP message
return message;
}
/**
* Get HTTP headers from a full message.
* @param fullMessage a message.
* @return HTTP headers from a full message.
*/
public static byte[] getHTTPHeaders(byte[] fullMessage)
{
//String httpHeaders = null;
int index = getFirstCRLFCRLF(fullMessage, 0);
if (index == -1)
{
logError(
"Unable to parse HTTP message to find headers. Full message: "
+ fullMessage);
return ("x-WSI-Test-Tool-Error: Couldn't find headers. Full message: ["
+ fullMessage + "].").getBytes();
}
// Return HTTP headers
byte[] b = new byte[index];
System.arraycopy(fullMessage, 0, b, 0, index);
return b;
}
/**
* Get HTTP headers from a full message.
* @param fullMessage a message.
* @return HTTP headers from a full message.
*/
public static String getHTTPHeadersAsString(byte[] fullMessage, String encoding)
{
//String httpHeaders = null;
int index = getFirstCRLFCRLF(fullMessage, 0);
if (index == -1)
{
logError(
"Unable to parse HTTP message to find headers. Full message: "
+ fullMessage);
return "x-WSI-Test-Tool-Error: Couldn't find headers. Full message: ["
+ fullMessage + "].";
}
// Return HTTP headers
try
{
return new String(fullMessage, 0, index, encoding);
}
catch (UnsupportedEncodingException e)
{
logError(
"Unsupported Encoding: " + encoding + ". Full message: "
+ fullMessage);
return "x-WSI-Test-Tool-Error: Unsupported Encoding \"" + encoding + "\". Full message: ["
+ fullMessage + "].";
}
}
/**
* Get SOAP message from a full message.
* @param fullMessage a message.
* @return SOAP message from a full message.
*/
public static String getContentAsString(byte[] message)
{
String content = "";
//String httpHeaders = null;
int index = getFirstCRLFCRLF(message, 0);
// If we couldn't find the end of the HTTP headers or the start of the message, then show error
if (index < 0)
{
logError(
"Unable to parse message to get content. Full message: "
+ message);
content =
"x-WSI-Test-Tool-Error: Couldn't find message content. Full message: ["
+ message.toString()
+ "].";
}
// Else get the message content
else if (index < message.length)
{
try
{
content = new String(message, index, message.length - index);
}
catch (Exception e)
{
logError(
"Unable to parse message to get content. Full message: "
+ message);
content =
"x-WSI-Test-Tool-Error: Couldn't find message content. Full message: ["
+ message.toString()
+ "].";
}
}
// Return SOAP message
return content;
}
/**
* Get SOAP message from a full message.
* @param fullMessage a message.
* @return SOAP message from a full message.
*/
public static byte[] getContent(byte[] message)
{
byte[] content = new byte [0];
//String httpHeaders = null;
int index = getFirstCRLFCRLF(message, 0);
// If we couldn't find the end of the HTTP headers or the start of the message, then show error
if (index < 0)
{
logError(
"Unable to parse message to get content. Full message: "
+ message);
message =
("x-WSI-Test-Tool-Error: Couldn't find message content. Full message: ["
+ message.toString()
+ "].").getBytes();
}
// If the index is greater than the length, then there is no message content
//else if (index >= fullMessage.length())
//{
// message = "";
//}
// Else get the message content
else if (index < message.length)
{
byte[] b = new byte[message.length - index];
System.arraycopy(message, index, b, 0, message.length - index);
content = b;
}
// Return SOAP message
return content;
}
/**
* Returns the first location of a CRLF.
*
* @return int
*/
public static int getFirstCRLF(byte[] buffer, int index)
{
int size = buffer.length;
int i = index;
while (i < size - 1) {
if (buffer[i] == CR && buffer[i+1] == LF)
return i;
i++;
}
return -1;
}
/**
* Returns the first location of a CRLF followed imediately by another CRLF.
*
* @return int
*/
public static int getFirstCRLFCRLF(byte[] buffer, int index)
{
int size = buffer.length;
int i = index;
while (i < size - 3)
{
if (buffer[i] == CR && buffer[i+1] == LF && buffer[i+2] == CR)
{
if (buffer[i+3] == LF)
{
return i+4;
}
else
{
int j = i + 3;
while (j < buffer.length && buffer[j] == CR)
{
j++;
}
if (j < buffer.length && buffer[j] == LF)
{
return j + 1;
}
}
}
i++;
}
return -1;
}
/**
* Returns the first location of a CRLF followed imediately by another CRLF.
*
* @return int
*/
public static int getFirstCRLFCRLF(String buffer)
{
int index = buffer.indexOf("\r\n\r");
if (index != -1)
{
int i = index +3;
while (i < buffer.length() && buffer.startsWith("\r", i))
i++;
if (i < buffer.length() && buffer.startsWith("\n", i))
return i+1;
else
return getFirstCRLFCRLF(buffer.substring(index + 3));
}
else
{
return -1;
}
}
/**
* Returns the list of indices which marks the separation of parts.
*/
public static int[] getBoundaryIndices(byte[] message, String boundaryStr)
{
int[] indices = new int[256];
int indicesIndex = 0;
try
{
byte[] boundary = ("\r\n--" + boundaryStr).getBytes("US-ASCII");
int index = 0;
int start = 0;
int end = message.length;
while (index != -1)
{
index = indexOf(message, boundary, start);
if (index != -1)
{
start = index + boundary.length;
indices[indicesIndex] = index;
indicesIndex++;
}
}
int[] b = new int[indicesIndex];
System.arraycopy(indices, 0, b, 0, indicesIndex);
indices = b;
}
catch (Exception e)
{}
return indices;
}
/**
* Returns the index of the first occurrence of key in the buffer.
*/
public static int indexOf(byte[] buffer, byte[] key, int start)
{
int bufferLen = buffer.length;
int keyLen = key.length;
int i,j,k = 0;
if (keyLen > bufferLen - start)
{
return -1;
}
for (k = start + keyLen - 1; k < bufferLen; k++)
{
for (j = keyLen - 1, i = k; (j >= 0) && (buffer[i] == key[j]); j--)
{
i--;
}
if (j == (-1)) {
return i + 1;
}
}
return -1;
}
/**
* Get contents of a resource and return as a input stream.
*
* @param resourceName the name of the resource to get and return as
* an input stream.
* @return contents of a resource as an input stream.
* @throws IOException if the resource could not be located.
*/
public static InputStream getInputStream(String resourceName)
throws IOException
{
InputStream is = null;
// If resource reference is a URL, then input stream from URL
try
{
// Try to create URL
URL urlResource = new URL(resourceName);
// If successful, then get URL input stream
is = getInputStream(urlResource);
}
// Else try to read resource directly
catch (MalformedURLException mue)
{
boolean bTryClassLoader = false;
try
{
// Open file input stream
is = new BufferedInputStream(new FileInputStream(resourceName));
}
catch (FileNotFoundException fnfe)
{
// Set try class loader flag
bTryClassLoader = true;
}
catch (SecurityException se)
{
// Set try class loader flag
bTryClassLoader = true;
}
catch (Exception e)
{
// DEBUG:
System.out.println("Exception in getInputStream :" + e.toString());
}
// If try class loader, then use it to get input stream
if (bTryClassLoader)
{
// Use class loader to load resource
is = ClassLoader.getSystemResourceAsStream(resourceName);
}
}
// If the input stream is null, then throw FileNotFoundException
if (is == null)
{
//try this
is =
Thread.currentThread().getContextClassLoader().getResourceAsStream(
resourceName);
}
// If the input stream is null, then throw FileNotFoundException
if (is == null)
{
//try this
URL aURL =
Thread.currentThread().getContextClassLoader().getResource(
resourceName);
if (aURL != null)
is = getInputStream(aURL);
}
if (is == null)
// Throw execption
throw new FileNotFoundException(
"Could not locate resource file: " + resourceName);
// Return input stream
return is;
}
/**
* Get the input stream from a URL.
* @param urlFile the URL to get the input stream from.
* @return the input stream corresponding to the given URL.
* @throws IOException if attempt to open the file denoted by URL has failed.
* @throws ConnectException if trouble connecting to URL.
*/
public static InputStream getInputStream(URL urlFile)
throws IOException, ConnectException
{
InputStream is = null;
// ADD: how are URLs that are password protected handled????
try
{
// Open file input stream
is = new BufferedInputStream(urlFile.openStream());
}
catch (ConnectException e)
{
// Re-throw this excpetion with additional information
throw new java.net.ConnectException(
"Could not connect to URL: " + urlFile.toExternalForm() + ".");
}
// Return input stream
return is;
}
/**
* Get contents of a resource and return as a input stream.
* @param fileLocation the location of the file.
* @return contents of a resource as a input stream.
*/
public static boolean fileExists(String fileLocation)
{
boolean fileExists = false;
// If resource reference is a URL, then input stream from URL
try
{
// Try to create URL
URL url = new URL(fileLocation);
// If successful, then try to open connection
InputStream is = url.openStream();
fileExists = true;
}
// Else try to read resource directly
catch (MalformedURLException mue)
{
try
{
File file = new File(fileLocation);
fileExists = file.exists();
}
catch (Exception e2)
{
fileExists = false;
}
}
catch (FileNotFoundException fnfe)
{
fileExists = false;
}
catch (Exception e)
{
fileExists = false;
}
// Return file exists indicator
return fileExists;
}
/**
* Get local host name.
* @return the local host name.
*/
public static String getLocalHostName()
{
String sLocalHostName;
try
{
// Get local host name
sLocalHostName = InetAddress.getLocalHost().getHostName();
}
catch (Exception e)
{
// Set default local host name
sLocalHostName = "127.0.0.1";
}
// Return local host name
return sLocalHostName;
}
/**
* Build a URL string from hostname, port and URN.
*
* @param hostname the hostname.
* @param port the port.
* @param urn the URN.
* @return formatted URL string.
*/
public static String formatURL(String hostname, String port, String urn)
{
// Build URN
String formatURN = urn;
// If URN doesn't start with "/", then add it
if (!(formatURN.startsWith("/")))
{
// Add "/" to beginning of the string
formatURN = "/" + urn;
}
// Return URL string
return "http://" + hostname + ":" + port + formatURN;
}
/**
* This method will replace all of the occurances of a string
* with a substitution string.
*
* @param sText String to udpate.
* @param sFind String to find.
* @param sReplace String to use for substitution.
* @return updated string.
*/
public static String replaceString(
String sText,
String sFind,
String sReplace)
{
int iPrevIndex = 0;
int iFindLen = sFind.length();
int iReplaceLen = sReplace.length();
String sUpdatedText = sText;
// Replace all occurances of the find string
for (int iIndex = sUpdatedText.indexOf(sFind);
iIndex < (sUpdatedText.length() - 1) && iIndex != -1;
iIndex = sUpdatedText.indexOf(sFind, iPrevIndex + iReplaceLen))
{
// Set updated text from the front portion + replacement text + back portion
sUpdatedText =
sUpdatedText.substring(0, iIndex)
+ sReplace
+ sUpdatedText.substring(iIndex + iFindLen);
// Set the previous index field
iPrevIndex = iIndex;
}
// Return updated text string
return sUpdatedText;
}
/**
* Convert string to hex string.
* @param data a String object.
* @return hex string.
*/
public static String toHexString(String data)
{
char[] HEX_CHARS =
{
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
// Get string as byte array
byte[] byteData = data.getBytes();
// Get length
int length = byteData.length;
// Create Char buffer
char[] charBuffer = new char[length * 2];
int next;
for (int byteCnt = 0, charCnt = 0; byteCnt < length;)
{
next = byteData[byteCnt++];
charBuffer[charCnt++] = HEX_CHARS[(next >>> 4) & 0x0F];
charBuffer[charCnt++] = HEX_CHARS[next & 0x0F];
}
return new String(charBuffer);
}
/**
* Convert byte buffer to hex string.
* @param data a byte array.
* @return hex string.
*/
public static String toHexString(byte[] byteData)
{
char[] HEX_CHARS =
{
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
// Get length
int length = byteData.length;
// Create Char buffer
char[] charBuffer = new char[length * 2];
int next;
for (int byteCnt = 0, charCnt = 0; byteCnt < length;)
{
next = byteData[byteCnt++];
charBuffer[charCnt++] = HEX_CHARS[(next >>> 4) & 0x0F];
charBuffer[charCnt++] = HEX_CHARS[next & 0x0F];
}
return new String(charBuffer);
}
// I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
/**
* Get MIME charset from a HTTP headers.
* @param httpHeaders String of HTTP header.
* @return the MIME charset string.
* @author K.Nakagome@BeaconIT Japan SIG
*/
public static String getHTTPCharset(String httpHeaders)
{
String mimeCharset = null;
mimeCharset = httpHeaders.toUpperCase();
int[] index = { -1, -1, -1 };
int indexS = mimeCharset.indexOf("CHARSET");
int indexE = Integer.MAX_VALUE;
if (indexS < 17)
{
return "";
}
indexS = mimeCharset.indexOf("=", indexS + 7);
if (indexS == -1)
{
return "";
}
indexS++;
index[0] = mimeCharset.indexOf("'", indexS);
index[1] = mimeCharset.indexOf("\r\n", indexS);
index[2] = mimeCharset.indexOf("\"", indexS);
for (int i = 0; i < 3; i++)
{
if (index[i] != -1 & indexE > index[i])
{
indexE = index[i];
}
}
if (indexE != Integer.MAX_VALUE)
{
mimeCharset = httpHeaders.substring(indexS, indexE);
mimeCharset.trim();
}
else
{
mimeCharset = "";
}
return mimeCharset;
}
/**
* Checks to see if the message is a simple SOAP message or whether it is a SOAP messagwe with attachments.
*/
public static boolean isMultipartRelatedMessage(String httpHeaders)
{
boolean result = false;
try
{
// check header for mime version and boundary
String contentType = HTTPUtils.getHttpHeaderAttribute(httpHeaders, HTTPConstants.HEADER_CONTENT_TYPE);
if (contentType == null)
{
// there is no contentType, check if there is a boundary attribute
String boundary = Utils.getHttpHeaderSubAttribute(httpHeaders, HTTPConstants.HEADER_CONTENT_TYPE, "boundary");
if ((boundary != null) && (!boundary.equals("")))
result = true;
}
else
{
result = contentType.equalsIgnoreCase("multipart/related");
}
}
catch (WSIException e)
{
result = false;
}
return result;
}
public static String getHttpHeaderAttribute(String httpHeaders, String attributeName)
{ String result = null;
try
{
result = HTTPUtils.getHttpHeaderAttribute(httpHeaders, attributeName);
}
catch (WSIException e)
{
result = null;
}
return result;
}
public static String getHttpHeaderSubAttribute(String httpHeaders, String attributeName, String subAttributeName)
{ String result = null;
try
{
result = HTTPUtils.getHttpHeaderSubAttribute(httpHeaders, attributeName, subAttributeName);
}
catch (WSIException e)
{
result = null;
}
return result;
}
public static String getMimeHeaderAttribute(String mimeHeaders, String attributeName)
{ String result = null;
try
{
result = MIMEUtils.getMimeHeaderAttribute(mimeHeaders, attributeName);
}
catch (WSIException e)
{
result = null;
}
return result;
}
public static String getMimeHeaderSubAttribute(String mimeHeaders, String attributeName, String subAttributeName)
{ String result = null;
try
{
result = MIMEUtils.getMimeHeaderSubAttribute(mimeHeaders, attributeName, subAttributeName);
}
catch (WSIException e)
{
result = null;
}
return result;
}
// I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
/**
* Get XML encoding from a SOAP Messages.
* @param message SOAP Message String.
* @return character encoding of XML.
* @author K.Nakagome@BeaconIT Japan SIG
*/
public static String getXMLEncoding(String message)
{
String xmlDef = null;
int indexS = message.indexOf("<?xml");
int indexE = -1;
if (indexS != -1)
{
indexE = message.indexOf("?>", indexS);
if (indexE > indexS)
{
xmlDef = message.substring(indexS, indexE);
}
}
if (xmlDef != null)
{
indexS = xmlDef.indexOf("encoding");
if (indexS == -1)
{
xmlDef = "";
}
else
{
xmlDef = xmlDef.substring(indexS + 8);
xmlDef = xmlDef.trim();
}
}
else
{
return "";
}
if (xmlDef.length() > 3)
{
indexS = xmlDef.indexOf("=");
if (indexS == 0)
{
xmlDef = xmlDef.substring(1);
}
else
{
return "";
}
}
if (xmlDef.length() > 3)
{
String end = "\"";
indexS = xmlDef.indexOf(end);
if (indexS != 0)
{
indexS = xmlDef.indexOf((end = "'"));
}
if (indexS == 0)
{
indexE = xmlDef.indexOf(end, 3);
if (indexE != -1)
{
xmlDef = xmlDef.substring(1, indexE);
}
else
{
xmlDef = "";
}
}
else
{
xmlDef = "";
}
}
return xmlDef;
}
// I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
private static ResourceBundle javaEncodingResource = null;
private static final String JAVA_ENCODING_RESOURCE =
"org.wsi.test.util.JavaEncoding";
private static final String JAVA_ENCODING_DEFAULT = "UTF-8";
// I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
/**
* Get Java VM supported character encoding.
*
* @param mimeEncoding string of MIME(IANA) character encoding.
* @return string of character encoding supported by Java VM.
* @author K.Nakagome@BeaconIT Japan SIG
*/
public static String getJavaEncoding(String mimeEncoding)
{
if (mimeEncoding == null || mimeEncoding.length() == 0)
{
return JAVA_ENCODING_DEFAULT;
}
try
{
if (javaEncodingResource == null)
{
javaEncodingResource = ResourceBundle.getBundle(JAVA_ENCODING_RESOURCE);
}
return javaEncodingResource.getString(mimeEncoding);
}
catch (Throwable t)
{
return mimeEncoding;
}
}
/**
* Convert an array to a Vector.
*
* @param array the array to be converted .
* @return converted Vector (null if array is null, empty if empty).
* @author Graham Turrell IBM
*/
public static Vector arrayToVector(Object[] array)
{
if (array == null)
return null;
Vector v = new Vector(array.length);
for (int i = 0; i < array.length; i++)
v.add(array[i]);
return v;
}
/**
* Checks to ensure that version of the profile test assertion
* document is supported in this version of the test tools.
* @param profileAssertions - a profile TAD.
* @return true if the version of the profile test assertion
* docuement is supported in this version of the test tools.
*/
public static boolean isValidProfileTADVersion(ProfileAssertions profileAssertions)
{
boolean result = false;
String name = profileAssertions.getTADName();
String version = profileAssertions.getTADVersion();
if (WSIConstants.BASIC_PROFILE_TAD_NAME.equals(name))
{
result =
checkVersionNumber(WSIConstants.BASIC_PROFILE_TAD_VERSION, version);
} else if (WSIConstants.BASIC_PROFILE_1_1_TAD_NAME.equals(name))
{
result =
checkVersionNumber(WSIConstants.BASIC_PROFILE_1_1_TAD_VERSION, version);
} else if (WSIConstants.SIMPLE_SOAP_BINDINGS_PROFILE_TAD_NAME.equals(name))
{
result =
checkVersionNumber(WSIConstants.SIMPLE_SOAP_BINDINGS_PROFILE_TAD_VERSION, version);
} else if (WSIConstants.ATTACHMENTS_PROFILE_TAD_NAME.equals(name))
{
result =
checkVersionNumber(WSIConstants.ATTACHMENTS_PROFILE_TAD_VERSION, version);
}
return result;
}
/**
* Checks to ensure that version number of the actual profile test assertion
* document is supported in this version of the test tools.
* @param supportedVersion - supported version number of profile TAD.
* @param actualVersion - actual version number of profile TAD.
* @return true if the version number of the actual profile test assertion
* document is supported in this version of the test tools.
*/
private static boolean checkVersionNumber(
String supportedVersion,
String actualVersion)
{
boolean validVersion = true;
try
{
StringTokenizer supportedVersionTokenizer =
new StringTokenizer(supportedVersion, ".");
StringTokenizer actualVersionTokenizer =
new StringTokenizer(actualVersion, ".");
while (supportedVersionTokenizer.hasMoreTokens() && validVersion)
{
int supportedVersionToken =
Integer.parseInt(supportedVersionTokenizer.nextToken());
if (actualVersionTokenizer.hasMoreTokens())
{
int actualVersionToken =
Integer.parseInt(actualVersionTokenizer.nextToken());
if (supportedVersionToken > actualVersionToken) break;
else validVersion = (supportedVersionToken >= actualVersionToken);
}
}
}
catch (Exception e)
{
validVersion = false;
}
return validVersion;
}
/**
* Identifies the root part in the list using the "start" attribute.
* If the "start" attribute does not exist then the first part is designated the root.
*/
public static MimePart findRootPart(String httpHeaders, Collection parts)
{
MimePart root = null;
String start = Utils.getHttpHeaderSubAttribute(httpHeaders, HTTPConstants.HEADER_CONTENT_TYPE, "start");
if (!parts.isEmpty())
{
// default to the first part in the collection
root = (MimePart)parts.iterator().next();
if ((start != null) && (!start.equals("")))
{
Iterator i = parts.iterator();
boolean rootNotFound = true;
while (i.hasNext() && rootNotFound)
{
MimePart part = (MimePart)i.next();
String headers = part.getHeaders();
if (headers != null)
{
String contentId = Utils.getMimeHeaderAttribute(headers, MIMEConstants.HEADER_CONTENT_ID);
if (start.equals(contentId))
{
root = part;
rootNotFound = false;
}
}
}
}
}
return root;
}
/**
* Decodes the given encoded string.
*/
public static byte[] decodeBase64(String str)
{
try
{
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
return decoder.decodeBuffer(str);
}
catch (Exception e)
{
return new byte[0];
}
}
/**
* Encodes the given byte array.
*/
public static String encodeBase64(byte[] buffer)
{
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
return encoder.encodeBuffer(buffer);
}
public static MimeParts parseMultipartRelatedMessage(String message, String httpHeaders, String encoding)
{
byte[] buffer = null;
try
{
buffer = message.getBytes(encoding);
}
catch (Exception e)
{
return null;
}
return parseMultipartRelatedMessage(buffer, httpHeaders, encoding);
}
public static MimeParts parseMultipartRelatedMessage(byte[] message, String httpHeaders, String encoding)
{
MimeParts mimeParts = new MimePartsImpl();
String boundary = Utils.getHttpHeaderSubAttribute(httpHeaders, HTTPConstants.HEADER_CONTENT_TYPE, "boundary");
ArrayList parts = new ArrayList();
if (boundary == null)
{
// assume it is a simple SOAP message
return null;
}
else
{
String start = Utils.getHttpHeaderSubAttribute(httpHeaders, HTTPConstants.HEADER_CONTENT_TYPE, "start");
int[] indices = Utils.getBoundaryIndices(message, boundary);
boolean rootNotFound = true;
for (int i= indices.length - 2; i>=0; i--)
{
try
{
MimePart part = new MimePartImpl();
int index = Utils.getFirstCRLFCRLF(message, indices[i]);
if ((index > indices[i]) && (index < indices[i+1]))
{
// the boundary string & mime headers (include the trailing CRLF CRLF)
String str = new String(message, indices[i], (index - indices[i]), "US-ASCII");
String delimiter = str.substring(0, str.indexOf("\r\n", 2) + 2);
if (i == indices.length -2)
{
String endDelimiter = new String(message, indices[i + 1], message.length - indices[i + 1], "US-ASCII");
int j = str.indexOf("\r\n", 2);
if (j != -1)
endDelimiter = str.substring(0, str.indexOf("\r\n", 2) + 2);
part.setBoundaryStrings(new String[]{delimiter, endDelimiter});
}
else
part.setBoundaryStrings(new String[]{delimiter});
// the headers
String headers = str.substring(delimiter.length());
if (headers.startsWith("\r\n"))
{
// no headers present
part.setHeaders("");
}
else
{
part.setHeaders(headers);
}
// the content
String contentId = Utils.getMimeHeaderAttribute(headers, MIMEConstants.HEADER_CONTENT_ID);
int size = indices[i+1] - (index);
byte[] content = new byte[size];
System.arraycopy(message, index, content, 0, size);
if ((rootNotFound && (i == 0)) ||
((start != null) && (!start.equals("")) && (start.equals(contentId))))
{
// root part -- do not encode
part.setContent(new String(content, encoding));
mimeParts.setRootPart(part);
}
else
{
String transferEncoding = Utils.getMimeHeaderAttribute(headers, MIMEConstants.HEADER_CONTENT_TRANSFER_ENCODING);
if ((transferEncoding != null) && transferEncoding.equalsIgnoreCase("base64"))
part.setContent(new String(content, encoding));
else
part.setContent(Utils.encodeBase64(content));
}
parts.add(part);
}
}
catch (Exception e)
{
return null;
}
}
int size = parts.size();
for (int i = size-1; i>=0; i--)
mimeParts.addPart((MimePart)parts.get(i));
}
return mimeParts;
}
public static String toXMLString(MimeParts mimeParts)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
// Add message content with attachments element
pw.print("<" + WSIConstants.ELEM_MESSAGE_CONTENT_WITH_ATTACHMENTS);
pw.print(">");
Collection partList = mimeParts.getParts();
if (!partList.isEmpty())
{
Iterator iMimeParts = partList.iterator();
while (iMimeParts.hasNext())
{
MimePart mimePart = (MimePart)iMimeParts.next();
pw.print(mimePart.toXMLString(""));
}
}
// Add end message element
pw.println("</" + WSIConstants.ELEM_MESSAGE_CONTENT_WITH_ATTACHMENTS + ">");
// Return string
return sw.toString();
}
public static void main (String[] args)
{
try
{
FileInputStream inputStream = new FileInputStream("d:\\b.xml");
int i = inputStream.available();
byte[] buffer = new byte[i];
inputStream.read(buffer);
String message = new String(buffer);
message = XMLUtils.xmlRemoveEscapedString(message);
String headers = Utils.getHTTPHeaders(message);
String content = Utils.getContent(message);
MimeParts parts = Utils.parseMultipartRelatedMessage(message, headers, Utils.JAVA_ENCODING_DEFAULT);
System.out.println(Utils.toXMLString(parts));
}
catch (Exception e){}
}
}