/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.everrest.core.impl.provider.multipart;
import org.everrest.core.impl.MultivaluedMapImpl;
import org.everrest.core.impl.header.HeaderHelper;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author andrew00x
*/
public class MultipartFormDataWriter {
private static final Annotation[] EMPTY = new Annotation[0];
private static final byte[] NEW_LINE = "\r\n".getBytes();
private static final byte[] HEADER_LINE_DELIM = ": ".getBytes();
private static final byte[] HYPHENS = "--".getBytes();
private Providers providers;
public MultipartFormDataWriter(Providers providers) {
this.providers = providers;
}
public void writeItems(Collection<OutputItem> items, OutputStream output, byte[] boundary) throws IOException {
for (OutputItem item : items) {
writeItem(item, output, boundary);
}
output.write(HYPHENS);
output.write(boundary);
output.write(HYPHENS);
output.write(NEW_LINE);
}
@SuppressWarnings("unchecked")
protected void writeItem(OutputItem item, OutputStream output, byte[] boundary) throws IOException {
output.write(HYPHENS);
output.write(boundary);
output.write(NEW_LINE);
final MediaType mediaType = item.getMediaType();
final Class<?> type = item.getType();
final Type genericType = item.getGenericType();
final MessageBodyWriter writer = providers.getMessageBodyWriter(type, genericType, EMPTY, mediaType);
if (writer == null) {
throw new RuntimeException(
String.format("Unable to find a MessageBodyWriter for media type '%s' and class '%s'", mediaType, type.getName()));
}
final MultivaluedMap<String, String> myHeaders = new MultivaluedMapImpl();
String contentDispositionHeader = "form-data; name=\"" + item.getName() + '"';
final String filename = item.getFilename();
if (filename != null) {
contentDispositionHeader += ("; filename=\"" + item.getFilename() + "\"");
}
myHeaders.putSingle("Content-Disposition", contentDispositionHeader);
if (mediaType != null) {
myHeaders.putSingle("Content-Type", mediaType.toString());
}
myHeaders.putAll(item.getHeaders());
writeHeaders(myHeaders, output);
writer.writeTo(item.getEntity(), type, genericType, EMPTY, mediaType, myHeaders, output);
output.write(NEW_LINE);
}
private void writeHeaders(MultivaluedMap<String, String> headers, OutputStream output) throws IOException {
for (Map.Entry<String, List<String>> e : headers.entrySet()) {
String name = e.getKey();
for (Object o : e.getValue()) {
String value;
if (o != null && (value = HeaderHelper.getHeaderAsString(o)) != null) {
output.write(name.getBytes());
output.write(HEADER_LINE_DELIM);
output.write(value.getBytes());
output.write(NEW_LINE);
}
}
}
output.write(NEW_LINE);
}
}