/**
* Copyright (C) 2012 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library 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
* version 2.1 of the License.
* This library 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
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.bonitasoft.forms.server;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.bonitasoft.console.common.server.utils.BonitaHomeFolderAccessor;
import org.bonitasoft.console.common.server.utils.FormsResourcesUtils;
import org.bonitasoft.console.common.server.utils.UnauthorizedFolderException;
import org.bonitasoft.engine.api.ProcessAPI;
import org.bonitasoft.engine.bpm.document.ArchivedDocument;
import org.bonitasoft.engine.bpm.document.Document;
import org.bonitasoft.engine.bpm.document.DocumentNotFoundException;
import org.bonitasoft.engine.session.APISession;
import org.bonitasoft.forms.server.api.FormAPIFactory;
import org.bonitasoft.forms.server.api.IFormWorkflowAPI;
/**
* Servlet allowing to view process instances attachments as images
*
* TODO refactor to remove duplicate code with {@link DocumentDownloadServlet}
*
* @author Anthony Birembaut
*/
public class DocumentImageServlet extends DocumentDownloadServlet {
/**
* UID
*/
private static final long serialVersionUID = -2397573068771431608L;
/**
* Logger
*/
private static final Logger LOGGER = Logger.getLogger(DocumentImageServlet.class.getName());
/**
* {@inheritDoc}
*/
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
final String filePath = request.getParameter(FILE_PATH_PARAM);
String fileName = request.getParameter(FILE_NAME_PARAM);
final String resourcePath = request.getParameter(RESOURCE_FILE_NAME_PARAM);
final String documentId = request.getParameter(DOCUMENT_ID_PARAM);
final APISession apiSession = (APISession) request.getSession().getAttribute(API_SESSION_PARAM_KEY);
byte[] fileContent = null;
String contentType = null;
if (filePath != null) {
final BonitaHomeFolderAccessor tempFolderAccessor = new BonitaHomeFolderAccessor();
try {
final File file = tempFolderAccessor.getTempFile(filePath, apiSession.getTenantId());
if (fileName == null) {
fileName = file.getName();
}
final FileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
contentType = mimetypesFileTypeMap.getContentType(file);
fileContent = getFileContent(file, filePath);
} catch (final UnauthorizedFolderException e) {
throw new ServletException(e.getMessage());
} catch (final IOException e) {
throw new ServletException(e);
}
} else if (documentId != null) {
try {
final ProcessAPI processAPI = bpmEngineAPIUtil.getProcessAPI(apiSession);
String contentStorageId;
try {
final Document document = processAPI.getDocument(Long.valueOf(documentId));
fileName = document.getContentFileName();
contentStorageId = document.getContentStorageId();
} catch (final DocumentNotFoundException dnfe) {
final ArchivedDocument archivedDocument = processAPI.getArchivedVersionOfProcessDocument(Long.valueOf(documentId));
fileName = archivedDocument.getDocumentContentFileName();
contentStorageId = archivedDocument.getContentStorageId();
}
if (contentStorageId != null && !contentStorageId.isEmpty()) {
fileContent = processAPI.getDocumentContent(contentStorageId);
}
} catch (final Exception e) {
final String errorMessage = "Error while retrieving the document with ID " + documentId + " from the engine.";
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, errorMessage, e);
}
throw new ServletException(errorMessage, e);
}
} else if (resourcePath != null) {
final String processIDStr = request.getParameter(PROCESS_ID_PARAM);
final String instanceIDStr = request.getParameter(INSTANCE_ID_PARAM);
final String taskIdStr = request.getParameter(TASK_ID_PARAM);
final IFormWorkflowAPI workflowAPI = FormAPIFactory.getFormWorkflowAPI();
long processDefinitionID = -1;
try {
if (processIDStr != null) {
processDefinitionID = Long.parseLong(processIDStr);
} else if (taskIdStr != null) {
processDefinitionID = workflowAPI.getProcessDefinitionIDFromActivityInstanceID(apiSession, Long.parseLong(taskIdStr));
} else if (instanceIDStr != null) {
processDefinitionID = workflowAPI.getProcessDefinitionIDFromProcessInstanceID(apiSession, Long.parseLong(instanceIDStr));
} else {
final String errorMessage = "Error while retrieving the resource " + resourcePath
+ " : Either a process, instance or task is required in the URL";
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, errorMessage);
}
throw new ServletException(errorMessage);
}
Date processDeployementDate = workflowAPI.getMigrationDate(apiSession, processDefinitionID);
if (processDeployementDate == null) {
processDeployementDate = workflowAPI.getProcessDefinitionDate(apiSession, processDefinitionID);
}
final File processDir = FormsResourcesUtils.getApplicationResourceDir(apiSession, processDefinitionID, processDeployementDate);
final File resource = new File(processDir, BUSINESS_ARCHIVE_RESOURCES_DIRECTORY + File.separator + resourcePath);
if (resource.exists()) {
fileName = resource.getName();
fileContent = getFileContent(resource, filePath);
} else {
final String errorMessage = "The target resource does not exist " + resource.getAbsolutePath();
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, errorMessage);
}
throw new IOException(errorMessage);
}
} catch (final Exception e) {
final String errorMessage = "Error while retrieving the resource " + resourcePath;
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, errorMessage, e);
}
throw new ServletException(errorMessage, e);
}
} else {
final String errorMessage = "Error while getting the file. either a document, a filePath or a resourcePath parameter is required.";
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, errorMessage);
}
throw new ServletException(errorMessage);
}
if (contentType != null) {
response.setContentType(contentType);
}
response.setCharacterEncoding("UTF-8");
if (fileName != null) {
try {
final String encodedfileName = URLEncoder.encode(fileName, "UTF-8");
final String userAgent = request.getHeader("User-Agent");
if (userAgent != null && userAgent.contains("Firefox")) {
response.setHeader("Content-Disposition", "inline; filename*=UTF-8''" + encodedfileName);
} else {
response.setHeader("Content-Disposition", "inline; filename=\"" + encodedfileName.replaceAll("\\+", " ") + "\"; filename*=UTF-8''"
+ encodedfileName);
}
if (fileContent != null) {
response.setContentLength(fileContent.length);
OutputStream out = null;
try {
out = response.getOutputStream();
out.write(fileContent);
} finally {
if (out != null) {
out.close();
}
}
}
} catch (final IOException e) {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, "Error while generating the response.", e);
}
throw new ServletException(e.getMessage(), e);
}
}
}
}