use of org.springframework.extensions.webscripts.servlet.FormData in project alfresco-remote-api by Alfresco.
the class CustomModelUploadPost method executeImpl.
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) {
if (!customModelService.isModelAdmin(AuthenticationUtil.getFullyAuthenticatedUser())) {
throw new WebScriptException(Status.STATUS_FORBIDDEN, PermissionDeniedException.DEFAULT_MESSAGE_ID);
}
FormData formData = (FormData) req.parseContent();
if (formData == null || !formData.getIsMultiPart()) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "cmm.rest_api.model.import_not_multi_part_req");
}
ImportResult resultData = null;
boolean processed = false;
for (FormData.FormField field : formData.getFields()) {
if (field.getIsFile()) {
final String fileName = field.getFilename();
File tempFile = createTempFile(field.getInputStream());
try (ZipFile zipFile = new ZipFile(tempFile, StandardCharsets.UTF_8)) {
resultData = processUpload(zipFile, field.getFilename());
} catch (ZipException ze) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "cmm.rest_api.model.import_not_zip_format", new Object[] { fileName });
} catch (IOException io) {
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, "cmm.rest_api.model.import_process_zip_file_failure", io);
} finally {
// now the import is done, delete the temp file
tempFile.delete();
}
processed = true;
break;
}
}
if (!processed) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "cmm.rest_api.model.import_no_zip_file_uploaded");
}
// If we get here, then importing the custom model didn't throw any exceptions.
Map<String, Object> model = new HashMap<>(2);
model.put("importedModelName", resultData.getImportedModelName());
model.put("shareExtXMLFragment", resultData.getShareExtXMLFragment());
return model;
}
use of org.springframework.extensions.webscripts.servlet.FormData in project alfresco-remote-api by Alfresco.
the class NodesImpl method upload.
@Override
public Node upload(String parentFolderNodeId, FormData formData, Parameters parameters) {
if (formData == null || !formData.getIsMultiPart()) {
throw new InvalidArgumentException("The request content-type is not multipart: " + parentFolderNodeId);
}
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
if (!nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) {
throw new InvalidArgumentException("NodeId of folder is expected: " + parentNodeRef.getId());
}
String fileName = null;
Content content = null;
boolean autoRename = false;
QName nodeTypeQName = ContentModel.TYPE_CONTENT;
// If a fileName clashes for a versionable file
boolean overwrite = false;
Boolean versionMajor = null;
String versionComment = null;
String relativePath = null;
String renditionNames = null;
Map<String, Object> qnameStrProps = new HashMap<>();
Map<QName, Serializable> properties = null;
for (FormData.FormField field : formData.getFields()) {
switch(field.getName().toLowerCase()) {
case "name":
String str = getStringOrNull(field.getValue());
if ((str != null) && (!str.isEmpty())) {
fileName = str;
}
break;
case "filedata":
if (field.getIsFile()) {
fileName = (fileName != null ? fileName : field.getFilename());
content = field.getContent();
}
break;
case "autorename":
autoRename = Boolean.valueOf(field.getValue());
break;
case "nodetype":
nodeTypeQName = createQName(getStringOrNull(field.getValue()));
if (!isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT)) {
throw new InvalidArgumentException("Can only upload type of cm:content: " + nodeTypeQName);
}
break;
case "overwrite":
overwrite = Boolean.valueOf(field.getValue());
break;
case "majorversion":
versionMajor = Boolean.valueOf(field.getValue());
break;
case "comment":
versionComment = getStringOrNull(field.getValue());
break;
case "relativepath":
relativePath = getStringOrNull(field.getValue());
break;
case "renditions":
renditionNames = getStringOrNull(field.getValue());
break;
default:
{
final String propName = field.getName();
if (propName.indexOf(QName.NAMESPACE_PREFIX) > -1) {
qnameStrProps.put(propName, field.getValue());
}
}
}
}
// result in a success message, but the files do not appear.
if (formData.getFields().length == 0) {
throw new ConstraintViolatedException("No disk space available");
}
// destination, or site + container or updateNodeRef
if ((fileName == null) || fileName.isEmpty() || (content == null)) {
throw new InvalidArgumentException("Required parameters are missing");
}
if (autoRename && overwrite) {
throw new InvalidArgumentException("Both 'overwrite' and 'autoRename' should not be true when uploading a file");
}
// if requested, make (get or create) path
parentNodeRef = getOrCreatePath(parentNodeRef, relativePath);
final QName assocTypeQName = ContentModel.ASSOC_CONTAINS;
final Set<String> renditions = getRequestedRenditions(renditionNames);
try {
// Map the given properties, if any.
if (qnameStrProps.size() > 0) {
properties = mapToNodeProperties(qnameStrProps);
}
/*
* Existing file handling
*/
NodeRef existingFile = nodeService.getChildByName(parentNodeRef, assocTypeQName, fileName);
if (existingFile != null) {
// File already exists, decide what to do
if (autoRename) {
// attempt to find a unique name
fileName = findUniqueName(parentNodeRef, fileName);
// drop-through !
} else if (overwrite && nodeService.hasAspect(existingFile, ContentModel.ASPECT_VERSIONABLE)) {
// overwrite existing (versionable) file
BasicContentInfo contentInfo = new ContentInfoImpl(content.getMimetype(), content.getEncoding(), -1, null);
return updateExistingFile(parentNodeRef, existingFile, fileName, contentInfo, content.getInputStream(), parameters, versionMajor, versionComment);
} else {
// name clash (and no autoRename or overwrite)
throw new ConstraintViolatedException(fileName + " already exists.");
}
}
// Note: pending REPO-159, we currently auto-enable versioning on new upload (but not when creating empty file)
if (versionMajor == null) {
versionMajor = true;
}
// Create a new file.
NodeRef nodeRef = createNewFile(parentNodeRef, fileName, nodeTypeQName, content, properties, assocTypeQName, parameters, versionMajor, versionComment);
// Create the response
final Node fileNode = getFolderOrDocumentFullInfo(nodeRef, parentNodeRef, nodeTypeQName, parameters);
// RA-1052
try {
List<ThumbnailDefinition> thumbnailDefs = getThumbnailDefs(renditions);
requestRenditions(thumbnailDefs, fileNode);
} catch (Exception ex) {
// Note: The log level is not 'error' as it could easily fill out the log file, especially in the Cloud.
if (logger.isDebugEnabled()) {
// Don't throw the exception as we don't want the the upload to fail, just log it.
logger.debug("Asynchronous request to create a rendition upon upload failed: " + ex.getMessage());
}
}
return fileNode;
// Do not clean formData temp files to allow for retries.
// Temp files will be deleted later when GC call DiskFileItem#finalize() method or by temp file cleaner.
} catch (AccessDeniedException ade) {
throw new PermissionDeniedException(ade.getMessage());
}
/*
* NOTE: Do not clean formData temp files to allow for retries. It's
* possible for a temp file to remain if max retry attempts are
* made, but this is rare, so leave to usual temp file cleanup.
*/
}
use of org.springframework.extensions.webscripts.servlet.FormData in project alfresco-remote-api by Alfresco.
the class UserCSVUploadPost method executeImpl.
/**
* @see DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.Status)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status) {
final List<Map<QName, String>> users = new ArrayList<Map<QName, String>>();
final ResourceBundle rb = getResources();
// Try to load the user details from the upload
FormData form = (FormData) req.parseContent();
if (form == null || !form.getIsMultiPart()) {
throw new ResourceBundleWebScriptException(Status.STATUS_BAD_REQUEST, rb, ERROR_BAD_FORM);
}
boolean processed = false;
for (FormData.FormField field : form.getFields()) {
if (field.getIsFile()) {
processUpload(field.getInputStream(), field.getFilename(), users);
processed = true;
break;
}
}
if (!processed) {
throw new ResourceBundleWebScriptException(Status.STATUS_BAD_REQUEST, rb, ERROR_NO_FILE);
}
// Should we send emails?
boolean sendEmails = true;
if (req.getParameter("email") != null) {
sendEmails = Boolean.parseBoolean(req.getParameter("email"));
}
if (form.hasField("email")) {
sendEmails = Boolean.parseBoolean(form.getParameters().get("email")[0]);
}
// Now process the users
final MutableInt totalUsers = new MutableInt(0);
final MutableInt addedUsers = new MutableInt(0);
final Map<String, String> results = new HashMap<String, String>();
final boolean doSendEmails = sendEmails;
// Do the work in a new transaction, so that if we hit a problem
// during the commit stage (eg too many users) then we get to
// hear about it, and handle it ourselves.
// Otherwise, commit exceptions occur deep inside RepositoryContainer
// and we can't control the status code
RetryingTransactionCallback<Void> work = new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
try {
doAddUsers(totalUsers, addedUsers, results, users, rb, doSendEmails);
return null;
} catch (Throwable t) {
// Make sure we rollback from this
UserTransaction userTrx = RetryingTransactionHelper.getActiveUserTransaction();
if (userTrx != null && userTrx.getStatus() != javax.transaction.Status.STATUS_MARKED_ROLLBACK) {
try {
userTrx.setRollbackOnly();
} catch (Throwable t2) {
}
}
// Report the problem further down
throw t;
}
}
};
try {
retryingTransactionHelper.doInTransaction(work);
} catch (Throwable t) {
// Tell the client of the problem
if (t instanceof WebScriptException) {
// We've already wrapped it properly, all good
throw (WebScriptException) t;
} else {
// Return the details with a 200, so that Share does the right thing
throw new ResourceBundleWebScriptException(Status.STATUS_OK, rb, ERROR_GENERAL, t);
}
}
// If we get here, then adding the users didn't throw any exceptions,
// so tell the client which users went in and which didn't
Map<String, Object> model = new HashMap<String, Object>();
model.put("totalUsers", totalUsers);
model.put("addedUsers", addedUsers);
model.put("users", results);
return model;
}
use of org.springframework.extensions.webscripts.servlet.FormData in project alfresco-remote-api by Alfresco.
the class ParamsExtractorTests method testMultiPartPostExtractor.
@Test
public void testMultiPartPostExtractor() throws Exception {
ResourceWebScriptPost extractor = new ResourceWebScriptPost();
extractor.setAssistant(assistant);
Map<String, String> templateVars = new HashMap<String, String>();
WebScriptRequest request = mock(WebScriptRequest.class);
when(request.getServiceMatch()).thenReturn(new Match(null, templateVars, null));
File file = TempFileProvider.createTempFile("ParamsExtractorTests-", ".txt");
PrintWriter writer = new PrintWriter(file);
writer.println("Multipart Mock test.");
writer.close();
MultiPartRequest reqBody = MultiPartBuilder.create().setFileData(new FileData(file.getName(), file, MimetypeMap.MIMETYPE_TEXT_PLAIN)).build();
MockHttpServletRequest mockRequest = new MockHttpServletRequest("POST", "");
mockRequest.setContent(reqBody.getBody());
mockRequest.setContentType(reqBody.getContentType());
when(request.getContentType()).thenReturn("multipart/form-data");
when(request.parseContent()).thenReturn(new FormData(mockRequest));
Params params = extractor.extractParams(mockEntity(), request);
assertNotNull(params);
Object passed = params.getPassedIn();
assertNotNull(passed);
assertTrue(FormData.class.isAssignableFrom(passed.getClass()));
FormData formData = (FormData) passed;
assertTrue(formData.getIsMultiPart());
// No entity id for POST
templateVars.put(ResourceLocator.ENTITY_ID, "1234");
try {
params = extractor.extractParams(mockEntity(), request);
fail("Should not get here. No entity id for POST");
} catch (UnsupportedResourceOperationException uoe) {
assertNotNull(uoe);
}
params = extractor.extractParams(mockRelationship(), request);
assertNotNull(params);
assertEquals("1234", params.getEntityId());
passed = params.getPassedIn();
assertNotNull(passed);
assertTrue(FormData.class.isAssignableFrom(passed.getClass()));
formData = (FormData) passed;
assertTrue(formData.getIsMultiPart());
}
use of org.springframework.extensions.webscripts.servlet.FormData in project alfresco-remote-api by Alfresco.
the class SerializeTests method testInvokeMultiPartEntity.
@Test
public void testInvokeMultiPartEntity() throws IOException {
ResourceWithMetadata entityResource = locator.locateEntityResource(api, "multiparttest", HttpMethod.POST);
assertNotNull(entityResource);
MultiPartResourceAction.Create<?> resource = (MultiPartResourceAction.Create<?>) entityResource.getResource();
File file = TempFileProvider.createTempFile("ParamsExtractorTests-", ".txt");
PrintWriter writer = new PrintWriter(file);
writer.println("Multipart Mock test2.");
writer.close();
MultiPartRequest reqBody = MultiPartBuilder.create().setFileData(new FileData(file.getName(), file, MimetypeMap.MIMETYPE_TEXT_PLAIN)).build();
MockHttpServletRequest mockRequest = new MockHttpServletRequest("POST", "");
mockRequest.setContent(reqBody.getBody());
mockRequest.setContentType(reqBody.getContentType());
String out = writeResponse(helper.processAdditionsToTheResponse(mock(WebScriptResponse.class), api, null, NOT_USED, resource.create(new FormData(mockRequest), NOT_USED, callBack)));
assertTrue("There must be json output", StringUtils.startsWith(out, "{\"entry\":"));
}
Aggregations