/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.rest.internal.resources.attachments;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import javax.inject.Named;
import javax.mail.BodyPart;
import javax.mail.Header;
import javax.mail.Multipart;
import javax.ws.rs.Encoded;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.xwiki.component.annotation.Component;
import org.xwiki.rest.XWikiRestException;
import org.xwiki.rest.internal.Utils;
import org.xwiki.rest.internal.resources.BaseAttachmentsResource;
import org.xwiki.rest.model.jaxb.Attachments;
import org.xwiki.rest.resources.attachments.AttachmentResource;
import org.xwiki.rest.resources.attachments.AttachmentsResource;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.api.Document;
/**
* @version $Id: be175e79df336cede7efb42a0d06260f76c3919a $
*/
@Component
@Named("org.xwiki.rest.internal.resources.attachments.AttachmentsResourceImpl")
public class AttachmentsResourceImpl extends BaseAttachmentsResource implements AttachmentsResource
{
private static String FORM_FILENAME_FIELD = "filename";
@Override
public Attachments getAttachments(String wikiName, String spaceName, String pageName, Integer start, Integer number,
Boolean withPrettyNames) throws XWikiRestException
{
try {
DocumentInfo documentInfo = getDocumentInfo(wikiName, spaceName, pageName, null, null, true, false);
Document doc = documentInfo.getDocument();
return getAttachmentsForDocument(doc, start, number, withPrettyNames);
} catch (XWikiException e) {
throw new XWikiRestException(e);
}
}
@Override
public Response addAttachment(String wikiName, String spaceName, String pageName, Multipart multipart)
throws XWikiRestException
{
try {
List<String> spaces = parseSpaceSegments(spaceName);
DocumentInfo documentInfo = getDocumentInfo(wikiName, spaces, pageName, null, null, true, true);
Document doc = documentInfo.getDocument();
if (!doc.hasAccessLevel("edit", Utils.getXWikiUser(componentManager))) {
throw new WebApplicationException(Status.UNAUTHORIZED);
}
/* The name to be used */
String attachmentName = null;
/* The actual filename of the sent file */
String actualFileName = null;
/* The specified file name using a form field */
String overriddenFileName = null;
String contentType = null;
InputStream inputStream = null;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
/* Get the content disposition headers */
Enumeration e = bodyPart.getMatchingHeaders(new String[]{ "Content-disposition" });
while (e.hasMoreElements()) {
Header h = (Header) e.nextElement();
/* Parse header data. Normally headers are in the form form-data; key="value"; ... */
if (h.getValue().startsWith("form-data")) {
String[] fieldData = h.getValue().split(";");
for (String s : fieldData) {
String[] pair = s.split("=");
if (pair.length == 2) {
String key = pair[0].trim();
String value = pair[1].replace("\"", "").trim();
if ("name".equals(key)) {
if (FORM_FILENAME_FIELD.equals(value)) {
overriddenFileName = bodyPart.getContent().toString();
}
} else if ("filename".equals(key)) {
actualFileName = value;
contentType = bodyPart.getContentType();
inputStream = bodyPart.getInputStream();
}
}
}
}
}
}
if (overriddenFileName != null) {
attachmentName = overriddenFileName;
} else {
attachmentName = actualFileName;
}
if (attachmentName == null) {
throw new WebApplicationException(Status.BAD_REQUEST);
}
byte[] buffer = new byte[4096];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (true) {
int read = inputStream.read(buffer);
if (read != 4096) {
if (read != -1) {
baos.write(buffer, 0, read);
}
break;
} else {
baos.write(buffer);
}
}
baos.flush();
/* Attach the file */
AttachmentInfo attachmentInfo = storeAttachment(doc, attachmentName, baos.toByteArray());
if (attachmentInfo.isAlreadyExisting()) {
return Response.status(Status.ACCEPTED).entity(attachmentInfo.getAttachment()).build();
} else {
return Response.created(Utils.createURI(uriInfo.getBaseUri(), AttachmentResource.class, wikiName,
spaces, pageName, attachmentName)).entity(attachmentInfo.getAttachment()).build();
}
} catch (Exception e) {
throw new XWikiRestException(e);
}
}
}