/**
*
*/
package com.grendelscan.commons.http.dataHandling.containers;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.lang.NotImplementedException;
import org.apache.http.entity.mime.MIME;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.grendelscan.commons.CharsetUtils;
import com.grendelscan.commons.StringUtils;
import com.grendelscan.commons.formatting.DataEncodingStream;
import com.grendelscan.commons.formatting.DataFormat;
import com.grendelscan.commons.formatting.DataFormatType;
import com.grendelscan.commons.http.dataHandling.data.AbstractData;
import com.grendelscan.commons.http.dataHandling.data.Data;
import com.grendelscan.commons.http.dataHandling.references.DataReference;
import com.grendelscan.commons.http.dataHandling.references.FileUploadReference;
/**
* @author dbyrne
*
*/
public class FileUploadContainer extends AbstractData implements DataContainer<FileUploadReference>
{
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadContainer.class);
private Data fileContent;
private Data fileName;
private Data fieldName;
private Data mimeType;
/**
* @param parent
* @param transactionId
*/
public FileUploadContainer(final DataContainer<?> parent, final int transactionId)
{
super(parent, transactionId);
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#childrenDebugString()
*/
@Override
public String childrenDebugString()
{
StringBuilder sb = new StringBuilder();
sb.append("FieldName:\n");
sb.append(StringUtils.indentLines(fieldName.debugString(), 1));
sb.append("FileName:\n");
sb.append(StringUtils.indentLines(fileName.debugString(), 1));
sb.append("MimeType:\n");
sb.append(StringUtils.indentLines(mimeType.debugString(), 1));
sb.append("File content (URL encoded):\n");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataFormat format = new DataFormat();
format.formatType = DataFormatType.URL_BASIC_ENCODED;
DataEncodingStream des = new DataEncodingStream(baos, format);
fileContent.writeBytes(des);
sb.append(StringUtils.indentLines(new String(baos.toByteArray()), 1));
return sb.toString();
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.data.Data#debugString()
*/
@Override
public String debugString()
{
StringBuilder sb = new StringBuilder();
sb.append("FileUploadContainer -\n");
sb.append(StringUtils.indentLines(abstractDataDebugString(), 1));
sb.append("\n");
sb.append(StringUtils.indentLines(childrenDebugString(), 1));
return sb.toString();
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getChild(com.grendelscan.commons.http.dataHandling.references.DataReference)
*/
@Override
public Data getChild(final FileUploadReference reference)
{
switch (reference.getPart())
{
case fieldname:
return fieldName;
case filecontent:
return fileContent;
case filename:
return fileName;
case mime:
return mimeType;
}
throw new IllegalStateException("This should be unreachable");
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getChildsReference(com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public FileUploadReference getChildsReference(final Data child)
{
if (child == fieldName)
{
return FileUploadReference.FIELD_NAME;
}
if (child == fileName)
{
return FileUploadReference.FILENAME;
}
if (child == mimeType)
{
return FileUploadReference.MIME_TYPE;
}
if (child == fileContent)
{
return FileUploadReference.FILE_CONTENT;
}
throw new IllegalArgumentException("The passed data object is not a child of this container");
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getChildUnsafeType(com.grendelscan.commons.http.dataHandling.references.DataReference)
*/
@Override
public Data getChildUnsafeType(final DataReference reference)
{
return getChild((FileUploadReference) reference);
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getDataChildren()
*/
@Override
public Data[] getDataChildren()
{
return new Data[] { fieldName, fileName, mimeType, fileContent };
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#removeChild(com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void removeChild(final Data child)
{
throw new NotImplementedException("Remove child makes no sense on a file upload parameter");
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#replaceChild(com.grendelscan.commons.http.dataHandling.references.DataReference,
* com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void replaceChild(final FileUploadReference reference, final Data child)
{
switch (reference.getPart())
{
case fieldname:
fieldName = child;
break;
case filecontent:
fileContent = child;
break;
case filename:
fileName = child;
break;
case mime:
mimeType = child;
break;
}
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.data.Data#writeBytes(java.io.OutputStream)
*/
@Override
public void writeBytes(final OutputStream out)
{
try
{
out.write(CharsetUtils.encode(MIME.DEFAULT_CHARSET, MIME.CONTENT_DISPOSITION + ": form-data; name=\""));
fieldName.writeBytes(out);
out.write(CharsetUtils.encode(MIME.DEFAULT_CHARSET, "\"; filename=\""));
fileName.writeBytes(out);
out.write(CharsetUtils.encode(MIME.DEFAULT_CHARSET, "\"\r\n" + MIME.CONTENT_TYPE + ": "));
mimeType.writeBytes(out);
out.write(CharsetUtils.encode(MIME.DEFAULT_CHARSET, "\"\r\n\r\n"));
fileContent.writeBytes(out);
out.write(CharsetUtils.encode(MIME.DEFAULT_CHARSET, "\r\n"));
}
catch (IOException e)
{
LOGGER.error("Very odd problem writing data: " + e.toString(), e);
}
}
}