/*******************************************************************************
* 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 javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import static com.google.common.collect.Maps.newHashMap;
/**
* @author andrew00x
*/
@Provider
@Produces({"multipart/*"})
public class CollectionMultipartFormDataMessageBodyWriter implements MessageBodyWriter<Collection<OutputItem>> {
private final MultipartFormDataWriter multipartFormDataWriter;
public CollectionMultipartFormDataMessageBodyWriter(@Context Providers providers) {
this(new MultipartFormDataWriter(providers));
}
CollectionMultipartFormDataMessageBodyWriter(MultipartFormDataWriter multipartFormDataWriter) {
this.multipartFormDataWriter = multipartFormDataWriter;
}
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
if (Collection.class.isAssignableFrom(type) && genericType instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType)genericType;
Type[] ta = t.getActualTypeArguments();
return ta.length == 1 && ta[0] instanceof Class && OutputItem.class.isAssignableFrom((Class<?>)ta[0]);
}
return false;
}
@Override
public long getSize(Collection<OutputItem> items, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
@Override
public void writeTo(Collection<OutputItem> items, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
String boundary = mediaType.getParameters().get("boundary");
if (boundary == null) {
boundary = Long.toString(System.currentTimeMillis());
}
httpHeaders.putSingle("Content-type", createMediaTypeWithBoundary(mediaType, boundary));
final byte[] boundaryBytes = boundary.getBytes();
multipartFormDataWriter.writeItems(items, entityStream, boundaryBytes);
}
private MediaType createMediaTypeWithBoundary(MediaType mediaType, String boundary) {
Map<String, String> parameters = newHashMap(mediaType.getParameters());
parameters.put("boundary", boundary);
return new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters);
}
}