blob: f0d4152e905ccf4726adf8ca3c1524bdc04b8dfb [file] [log] [blame]
/*
* 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 org.apache.abdera2.protocol.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.apache.abdera2.model.Element.Helper;
import org.apache.abdera2.model.Entry;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.entity.mime.HttpMultipart;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.message.BasicHeader;
/**
* Implementation of the HttpEntity class for use with Multipart Atom Posts.
* The first part of the multipart related package is an Atom Entry document
* whose content element specifies a src="cid:..." attribute referencing the
* second part of the multipart package. This is used primarily as a means
* of simplifying posts to Atompub Media Collections.
*/
public class MultipartRelatedEntity
extends BasicHttpEntity
implements HttpEntity {
private final HttpMultipart multipart;
private final Header contentType;
private String boundary;
public MultipartRelatedEntity(
Entry entry,
ContentBody other) {
this(entry, other, null, null);
}
public MultipartRelatedEntity(
Entry entry,
ContentBody other,
String contentType) {
this(entry, other, contentType, null);
}
public MultipartRelatedEntity(
Entry entry,
ContentBody other,
String contentType,
String boundary) {
if (entry == null ||
other == null)
throw new IllegalArgumentException();
this.boundary = boundary != null ? boundary : String.valueOf(System.currentTimeMillis());
this.contentType =
new BasicHeader(
"Content-Type",String.format("Multipart/Related; boundary=\"%s\";type=\"%s\"",this.boundary,Helper.getMimeType(entry)));
String cs = entry.getDocument().getCharset();
Charset charset = cs != null ? Charset.forName(cs) : Charset.defaultCharset();
multipart = new HttpMultipart("related", charset, this.boundary, HttpMultipartMode.STRICT);
multipart.addBodyPart(new FormBodyPart("entry",new AbderaBody(entry)));
String contentId = entry.getContentSrc().toString();
if (!contentId.matches("cid\\:.+")) {
throw new IllegalArgumentException("entry content source is not a correct content-ID");
}
FormBodyPart other_part = new FormBodyPart("other",other);
other_part.addField("Content-ID", String.format("<%s>",contentId.substring(4)));
other_part.addField("Content-Type", other.getMimeType());
multipart.addBodyPart(other_part);
}
public void consumeContent()
throws IOException, UnsupportedOperationException{
if (isStreaming()) {
throw new UnsupportedOperationException(
"Streaming entity does not implement #consumeContent()");
}
}
public InputStream getContent() {
throw new UnsupportedOperationException();
}
public void writeTo(OutputStream out) throws IOException {
multipart.writeTo(out);
}
public long getContentLength() {
return -1;
}
public Header getContentType() {
return contentType;
}
public boolean isRepeatable() {
for (FormBodyPart part: this.multipart.getBodyParts()) {
ContentBody body = part.getBody();
if (body.getContentLength() < 0) {
return false;
}
}
return true;
}
public boolean isChunked() {
return !isRepeatable();
}
public boolean isStreaming() {
return !isRepeatable();
}
}