/*
* Copyright 2008 Fedora Commons, Inc.
*
* 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.mulgara.protocol.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.CharBuffer;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMultipart;
/**
* This class extends multipart MIME objects to lookup parameter values.
*
* @created Sep 17, 2008
* @author Paula Gearon
* @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
*/
public class MimeMultiNamedPart extends MimeMultipart {
/** The number of elements in internal data buffers. */
private static final int BUFFER_SIZE = 1024;
/**
* @param src The data source to retrieve the MIME data from
* @throws MessagingException If the source cannot be parsed as valid MIME data.
*/
public MimeMultiNamedPart(DataSource arg0) throws MessagingException {
super(arg0);
}
/**
* Goes through MIME data to look for a parameter.
* @param paramName The name of the parameter to retrieve
* @return The value for the parameter.
* @throws MessageException If the MIME data could not be parsed.
*/
public Object getParameter(String param) throws MessagingException, IOException {
BodyPart part = getNamedPart(param);
return part == null ? null : part.getContent();
}
/**
* Goes through MIME data to look for a string parameter.
* @param paramName The name of the parameter to retrieve
* @return The string value for the parameter, converting if needed.
* @throws MessageException If the MIME data could not be parsed.
*/
public String getParameterString(String param) throws MessagingException, IOException {
Object obj = getParameter(param);
if (obj == null) return null;
return toString(obj);
}
/**
* Finds a body part that has the requested name.
* @param paramName The name of the part to get.
* @return The body part with the requested name, or null if not found.
* @throws MessagingException If the MIME object could not be scanned.
*/
public BodyPart getNamedPart(String paramName) throws MessagingException {
for (int p = 0; p < getCount(); p++) {
BodyPart bpart = getBodyPart(p);
if (paramName.equalsIgnoreCase(getPartName(bpart))) return bpart;
}
return null;
}
/**
* Look up the name of a part by index.
* @param partNr The index of the part to look up.
* @return The name of the part, or null if not available.
* @throws MessagingException If the MIME object could not be scanned.
*/
public String getPartName(int partNr) throws MessagingException {
return getPartName(getBodyPart(partNr));
}
/**
* Gets the name of a body part.
* @param part The body part to get the name of.
* @return The name of this part, or <code>null</code> if no name can be found.
* @throws MessagingException The part could not be accessed.
*/
public static String getPartName(BodyPart part) throws MessagingException {
String[] cds = part.getHeader("Content-Disposition");
if (cds == null) return null;
// probably only has one Content-Disposition header, but check all anyway
for (String header: cds) {
for (String kv: header.split("; ")) {
int eq = kv.indexOf('=');
if (eq >= 0) {
// a key=value element
String key = kv.substring(0, eq);
if ("name".equalsIgnoreCase(key)) {
String value = kv.substring(eq + 1);
return stripQuotes(value);
}
}
}
}
return null;
}
/**
* Removes quote characters from around a string.
* @param str The string to remove quotes from.
* @return The part of str that was between quotes, or all of str if there were no quotes.
*/
private static String stripQuotes(String str) {
int l = str.length() - 1;
if (str.charAt(0) == '"' && str.charAt(l) == '"') str = str.substring(1, l);
return str;
}
/**
* Gets a string from an object. If the object is a stream, then it reads the stream
* otherwise it gets the string form of the object.
* @param o The object to convert to a string.
* @return The string form of the object, or <code>null</code> if the object could not be read.
*/
private static String toString(Object o) {
if (o instanceof InputStream) {
CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
StringBuilder sb = new StringBuilder();
InputStreamReader in = new InputStreamReader((InputStream)o);
try {
while (in.read(buffer) >= 0) {
buffer.flip();
sb.append(buffer);
}
o = sb;
} catch (IOException e) {
return null;
} finally {
try {
in.close();
} catch (IOException e) {
// got our data at this point, so ignore
}
}
}
return o.toString();
}
}