/******************************************************************************* * 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.ext; import org.apache.commons.fileupload.FileItem; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import static javax.ws.rs.core.MediaType.TEXT_PLAIN; /** * Implementation of {@link FileItem} which allow store data in memory only * without access to file system. If size of item exceeds limit (initial * allocated buffer size) then {@link WebApplicationException} will be thrown. * * @author andrew00x */ class InMemoryFileItem implements FileItem { private static final byte[] EMPTY_DATA = new byte[0]; private final String fileName; private final int maxSize; private ByteArrayOutputStream byteArrayOutputStream; private FilterOutputStream countingOutputStream; private String contentType; private String fieldName; private boolean isFormField; InMemoryFileItem(String contentType, String fieldName, boolean isFormField, String fileName, int maxSize) { this.contentType = contentType; this.fieldName = fieldName; this.isFormField = isFormField; this.fileName = fileName; this.maxSize = maxSize; } @Override public void delete() { byteArrayOutputStream = null; countingOutputStream = null; } @Override public byte[] get() { if (byteArrayOutputStream == null) { return EMPTY_DATA; } return byteArrayOutputStream.toByteArray(); } @Override public String getContentType() { return contentType; } @Override public String getFieldName() { return fieldName; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(get()); } @Override public String getName() { return fileName; } @Override public OutputStream getOutputStream() { if (byteArrayOutputStream == null) { byteArrayOutputStream = new ByteArrayOutputStream(maxSize); countingOutputStream = new FilterOutputStream(byteArrayOutputStream) { private int bytesCounter = 0; @Override public void write(byte[] b, int off, int len) throws IOException { ensureDoNotExceedMaxSize(len); super.write(b, off, len); bytesCounter += len; } @Override public void write(int b) throws IOException { ensureDoNotExceedMaxSize(1); super.write(b); bytesCounter++; } private void ensureDoNotExceedMaxSize(int numBytesToWrite) { int newSize = bytesCounter + numBytesToWrite; if (newSize > maxSize) { throw new WebApplicationException(Response.status(413) .entity(String.format("Item size is too large. Must not be over %d", maxSize)) .type(TEXT_PLAIN).build()); } } }; } return countingOutputStream; } @Override public long getSize() { return get().length; } @Override public String getString() { return new String(get()); } @Override public String getString(String encoding) throws UnsupportedEncodingException { return new String(get(), encoding); } @Override public boolean isFormField() { return isFormField; } @Override public boolean isInMemory() { return true; } @Override public void setFieldName(String name) { this.fieldName = name; } @Override public void setFormField(boolean state) { isFormField = state; } @Override public void write(File file) throws Exception { throw new UnsupportedOperationException(); } }