/** * Call this method as the first action in your servlet, to ensure that the files are technically * handled, before your business logic takes places. This method should only be invoked for POST * calls. * * @param aRequestScope Current request scope * @throws FileUploadException */ public static void handleUpload(@Nonnull final IRequestWebScopeWithoutResponse aRequestScope) throws FileUploadException { s_aLogger.info("handleUpload"); // get the upload ID that was sent via a hidden field from the upload frame final String sUploadID = aRequestScope.getAttributeAsString(PARAM_UPLOAD_ID); if (StringHelper.hasNoText(sUploadID)) { FileUploadProgressListener.getInstance().reset(); throw new FileUploadException("Unable to retrieve upload ID for received request!"); } // Check if we have the matching upload context final UploadContext aContext = UploadContextRegistry.getInstance().getContext(sUploadID); if (aContext == null) { FileUploadProgressListener.getInstance().reset(); throw new FileUploadException( "Unable to retrieve upload context for received request with ID '" + sUploadID + "'!"); } // Ensure that the upload directory exists final File aUploadDir = aContext.getUploadDirectory(); if (!aUploadDir.exists()) { final FileIOError aErr = FileOperations.createDirRecursive(aUploadDir); if (aErr.isFailure()) { FileUploadProgressListener.getInstance().reset(); throw new FileUploadException( "Failed to create upload directory " + aUploadDir + ": " + aErr.toString()); // $NON-NLS-2$ } } for (final IFileItem aFileItem : aRequestScope.getAllUploadedFileItemValues()) { final File aUploadedFile = _handleUploadFileItem(aFileItem, aContext); if (aUploadedFile != null) { FileUploadProgressListener.getInstance() .setFileName(FilenameHelper.getRelativeToParentDirectory(aUploadedFile, aUploadDir)); } } FileUploadProgressListener.getInstance().setUploadFinished(); }
/** * Called after successful external validation * * @param aItem Uploaded file item * @param aContext The non-<code>null</code> Upload context * @return The file which has been written in on the server, or <code>null</code> in case of an * error * @throws FileUploadException */ @Nullable private static File _handleUploadFileItem( @Nonnull final IFileItem aItem, @Nonnull final UploadContext aContext) throws FileUploadException { final String sFieldName = aItem.getFieldName(); final String sSourceFileName = aItem.getName(); final String sContentType = aItem.getContentType(); final boolean bInMemory = aItem.isInMemory(); final long nSizeInBytes = aItem.getSize(); File aUploadedFile = null; s_aLogger.info( "Processing file item [field:" + sFieldName + ", file:" + sSourceFileName + ", contenttype:" + sContentType + ", inmemory:" + bInMemory + ", size:" + nSizeInBytes + (aContext.getPostProcessor() == null ? "" : ", post processor " + CGStringHelper.getClassLocalName(aContext.getPostProcessor())) + "]"); // Validate the original filename final IUploadFilenameFilter aFilter = aContext.getFilenameFilter(); if (aFilter != null && !aFilter.matchesFilter(sSourceFileName)) { FileUploadProgressListener.getInstance() .setFailed( aFilter.getErrorCode(), aFilter.getErrorMessage(), ArrayHelper.newArray(aFilter.getErrorArguments(), String.class)); final String sMsg = "Uploaded file '" + sSourceFileName + "' does not satisfy the active filename filter!"; //$NON-NLS-2$ s_aLogger.warn(sMsg); throw new FileUploadException(sMsg); } final IUploadFileSizeFilter aSizeFilter = aContext.getFileSizeFilter(); if (aSizeFilter != null && !aSizeFilter.matchesFilter(Long.valueOf(nSizeInBytes))) { FileUploadProgressListener.getInstance() .setFailed( EFileUploadText.ERROR_FILESIZE_EXCEEDED.getStringPropertyName(), EFileUploadText.ERROR_FILESIZE_EXCEEDED, sSourceFileName, SizeHelper.getSizeHelperOfLocale(Locale.US) .getAsMatching(aSizeFilter.getMaxBytes(), 2)); final String sMsg = "Uploaded file '" + sSourceFileName + "' does not satisfy the maximum file size filter!"; //$NON-NLS-2$ s_aLogger.warn(sMsg); throw new FileUploadException(sMsg); } // Size may be 0 if no file was selected if (nSizeInBytes > 0) { // Set the post processor only, if a file is present, to avoid endless // loops on "post processing file ..." final FileUploadProgressListener aProgListener = FileUploadProgressListener.getInstance(); final IUploadPostProcessor aPostProcessor = aContext.getPostProcessor(); if (aPostProcessor != null) { aProgListener.setPostProcessor(aPostProcessor); } // Ensure the file does not contain any harmful characters etc. final String sFileName = FileUploadHelper.getUnifiedFilename(aItem); String sTargetFileName = aContext.getTargetFileName(); if (StringHelper.hasNoText(sTargetFileName)) { sTargetFileName = sFileName; } final String sTargetDir = FilenameHelper.getAbsoluteWithEnsuredParentDirectory( aContext.getUploadDirectory(), FilenameHelper.getPath(sTargetFileName)); // This is the main copy action aUploadedFile = FileUploadHelper.saveUploadedFile( aItem, new File(sTargetDir), FilenameHelper.getBaseName(sTargetFileName), FilenameHelper.getExtension(sTargetFileName)); if (aUploadedFile == null) { // Something went wrong in copying s_aLogger.error("Upload failed."); } else { s_aLogger.info( "Upload completed successfully to destination " + aUploadedFile.getAbsolutePath()); if (aPostProcessor != null) { s_aLogger.info("Starting post processing..."); try { aProgListener.setPostProcessing(); final UploadPostProcessingResult aResult = aPostProcessor.performPostProcessing( aUploadedFile, sFileName, aContext.getProperties()); aProgListener.setPostProcessorResult(aResult); } catch (final RuntimeException ex) { // Catch any exception s_aLogger.error("Internal error in post processing", ex); aProgListener.setPostProcessorResult( new UploadPostProcessingResult( ESuccess.FAILURE, EFileUploadText.ERROR_POST_PROCESSING, EFileUploadText.ERROR_POST_PROCESSING.getStringPropertyName(), null)); } } } } else { FileUploadProgressListener.getInstance() .setFailed( EFileUploadText.ERROR_NO_FILE_OR_EMPTY.getStringPropertyName(), EFileUploadText.ERROR_NO_FILE_OR_EMPTY); final String sMsg = "No file or empty file selected: '" + sSourceFileName + "'!"; // $NON-NLS-2$ s_aLogger.warn(sMsg); throw new FileUploadException(sMsg); } return aUploadedFile; }