/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package com.trsst.client;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.abdera.model.Base;
import org.apache.abdera.util.MimeTypeHelper;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.methods.RequestEntity;
/**
* A RequestEntity that handles an Entry or a Feed and supports multiple
* attachments. Per convention, each content id should match an id referenced in
* an entry with a corresponding digest or the server must reject.
*
* @author mpowers
*/
public class MultiPartRequestEntity implements RequestEntity {
private final Base base;
private final byte[][] content;
private final String[] contentId;
private final String[] contentType;
private long contentLength;
private String boundary;
public MultiPartRequestEntity(Base base, byte[][] content,
String[] contentId, String[] contentType) {
this.base = base;
this.content = content;
this.contentId = contentId;
this.contentType = contentType;
this.boundary = boundary != null ? boundary : String.valueOf(System
.currentTimeMillis());
try {
// dummy output stream to count the content length
contentLength = 0;
writeRequest(new OutputStream() {
@Override
public void write(int b) {
contentLength++;
}
@Override
public void write(byte[] b, int off, int len) {
contentLength += len;
}
});
} catch (IOException e) {
this.contentLength = -1;
log.error("Unexpected error while determining content length");
}
log.debug("MultiPartRequestEntity: contentLength: " + contentLength);
}
public void writeRequest(OutputStream arg0) throws IOException {
DataOutputStream out = new DataOutputStream(arg0);
out.writeBytes("--" + boundary + "\r\n");
writeEntry(base, out);
out.writeBytes("--" + boundary + "\r\n");
if (content != null) {
for (int i = 0; i < content.length; i++) {
writeContent(content[i], contentId[i], contentType[i], out);
out.writeBytes("\r\n" + "--" + boundary + "--");
}
}
out.flush();
}
private static void writeEntry(Base base, DataOutputStream out)
throws IOException {
out.writeBytes("content-type: " + MimeTypeHelper.getMimeType(base)
+ "\r\n\r\n");
base.writeTo(out);
}
private static void writeContent(byte[] content, String contentId,
String contentType, DataOutputStream out) throws IOException {
if (contentType == null) {
throw new NullPointerException("media content type can't be null");
}
out.writeBytes("content-type: " + contentType + "\r\n");
out.writeBytes("content-id: <cid:" + contentId + ">\r\n\r\n");
out.write(new Base64().encode(content));
}
public long getContentLength() {
return contentLength;
}
public String getContentType() {
return "Multipart/Related; boundary=\"" + boundary + "\";type=\""
+ MimeTypeHelper.getMimeType(base) + "\"";
}
public boolean isRepeatable() {
return true;
}
private final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(this
.getClass());
}