
org.craftercms.cstudio.publishing.servlet.FileUploadServlet Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2007-2013 Crafter Software Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.craftercms.cstudio.publishing.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.craftercms.cstudio.publishing.PublishedChangeSet;
import org.craftercms.cstudio.publishing.exception.PublishingException;
import org.craftercms.cstudio.publishing.processor.PublishingProcessor;
import org.craftercms.cstudio.publishing.target.PublishingTarget;
import org.craftercms.cstudio.publishing.target.TargetManager;
import org.springframework.util.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
/**
* @author Dejan Brkic
*/
public class FileUploadServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 3281574055609732424L;
private static Log LOGGER = LogFactory.getLog(FileUploadServlet.class);
public static final String PARAM_PASSWORD = "password";
public static String PARAM_SITE = "siteId";
public static String PARAM_TARGET = "target";
public static String PARAM_DELETED_FILES = "deletedFiles";
public static String CONFIG_ROOT = "root";
public static String CONFIG_CONTENT_FOLDER = "contentFolder";
public static String CONFIG_METADATA_FOLDER = "metadataFolder";
public static String CONFIG_METADATA_FILENAME_SUFFIX = ".meta.xml";
public static String CONFIG_MULTI_TENANCY_VARIABLE = "\\{siteId\\}";
public static String FILES_SEPARATOR = ",";
protected TargetManager targetManager;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
if (ServletFileUpload.isMultipartContent(request)) {
ServletFileUpload servletFileUpload = createServletFileUpload();
List fileItemsList = null;
Map parameters = new HashMap(11);
Map files = new HashMap(11);
try {
fileItemsList = servletFileUpload.parseRequest(request);
for (FileItem fileItem : fileItemsList) {
if (fileItem.isFormField()) {
parameters.put(fileItem.getFieldName(), fileItem.getString());
} else {
files.put(fileItem.getFieldName(), fileItem.getInputStream());
}
}
if (LOGGER.isDebugEnabled()) {
StringBuilder parametersLog = new StringBuilder("Request Parameters : ");
for(Entry entry : parameters.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if(key.equals(PARAM_PASSWORD)){
value = "********";
}
parametersLog.append(" " + key + " = " + value );
}
LOGGER.debug(parametersLog.toString());
}
String password = parameters.get(PARAM_PASSWORD);
if (password != null && password.equalsIgnoreCase(this.password)) {
deployFiles(parameters, files);
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Illegal publish request received.");
}
}
} catch (Exception e) {
handleErrorCase(files, response, e);
}
}
}
/**
* handle error case
*
* @param files
* @param response
* @param exception
*/
private void handleErrorCase(Map files, HttpServletResponse response, Exception exception) {
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Failed to upload files.", exception);
}
closeAll(files);
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, exception.getMessage());
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Failed to upload files.", e);
}
}
}
/**
* close all inputstream
*
* @param files
*/
private void closeAll(Map files) {
if (files != null) {
for (String file : files.keySet()) {
InputStream steam = files.get(file);
IOUtils.closeQuietly(steam);
}
}
}
/*
* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
/**
* create servlet file upload
*
* @return
*/
protected ServletFileUpload createServletFileUpload() {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
String tempPath = System.getProperty("java.io.tmpdir");
if (tempPath == null) {
tempPath = "temp";
}
File repoPath = new File(tempPath + File.separator + "crafter");
if (!repoPath.exists()) {
repoPath.mkdirs();
}
diskFileItemFactory.setRepository(repoPath);
ServletFileUpload toRet = new ServletFileUpload(diskFileItemFactory);
return toRet;
}
/**
* write files to targets
*
* @param parameters
* @param files
* @throws IOException
*/
protected void deployFiles(Map parameters, Map files) throws IOException {
String paramTarget = parameters.get(PARAM_TARGET);
PublishingTarget target = this.targetManager.getTarget(paramTarget);
if (target != null) {
PublishedChangeSet changeSet = new PublishedChangeSet();
// TODO: support pre-processors in future
writeToTarget(parameters, files, target, changeSet);
deleteFromTarget(parameters, target, changeSet);
// run through post processors
if (target.isDefaultProcessingEnabled()) {
try {
target.getDefaultPostProcessor().doProcess(changeSet, parameters, target);
} catch (PublishingException e) {
LOGGER.error("Error while running a default post processor", e);
}
}
doPostProcessing(changeSet, parameters, target);
} else {
throw new IOException("No configuration exists for " + paramTarget);
}
}
/**
* create or update files to target
*
* @param parameters
* @param files
* @param target
* @param changeSet
* @throws IOException
*/
protected void writeToTarget(Map parameters, Map files,
PublishingTarget target, PublishedChangeSet changeSet) throws IOException {
List createdFiles = new ArrayList(files.size());
List updatedFiles = new ArrayList(files.size());
String site = parameters.get(PARAM_SITE);
// write files to the target path
for (Map.Entry entry : files.entrySet()) {
String locationParamName = entry.getKey().replace("File", "Location").replace("metadata", "content");
boolean isMetadata = entry.getKey().startsWith("metadata");
String contentLocation = parameters.get(locationParamName);
StringBuilder sbFullPath = new StringBuilder(target.getParameter(CONFIG_ROOT));
sbFullPath.append(File.separator);
if (isMetadata)
sbFullPath.append(target.getParameter(CONFIG_METADATA_FOLDER));
else
sbFullPath.append(target.getParameter(CONFIG_CONTENT_FOLDER));
sbFullPath.append(contentLocation);
if (isMetadata) {
sbFullPath.append(CONFIG_METADATA_FILENAME_SUFFIX);
}
//String fullPath = target.getParameter(CONFIG_ROOT) + "/" + contentLocation;
if (LOGGER.isInfoEnabled()) {
LOGGER.info("writing " + sbFullPath.toString());
}
String fullPath = sbFullPath.toString();
if (StringUtils.hasText(site)) {
fullPath = fullPath.replaceAll(CONFIG_MULTI_TENANCY_VARIABLE, site);
}
File file = new File(fullPath);
OutputStream outputStream = null;
try {
// create new file if doesn't exist
boolean created = false;
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
created = true;
}
outputStream = new FileOutputStream(file);
IOUtils.copy(entry.getValue(), outputStream);
if (!isMetadata) {
if (created) {
createdFiles.add(contentLocation);
} else {
updatedFiles.add(contentLocation);
}
}
} catch (FileNotFoundException e) {
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Error: not able to open output stream for file " + contentLocation + " for " + target.getName());
}
throw e;
} catch (IOException e) {
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Error: not able to write file " + contentLocation + " for " + target.getName());
}
throw e;
} finally {
IOUtils.closeQuietly(entry.getValue());
IOUtils.closeQuietly(outputStream);
}
}
changeSet.setCreatedFiles(createdFiles);
changeSet.setUpdatedFiles(updatedFiles);
}
/**
* delete files form target
* @param parameters
* @param target
* @param changeSet
*/
protected void deleteFromTarget(Map parameters, PublishingTarget target, PublishedChangeSet changeSet) {
String deletedList = parameters.get(PARAM_DELETED_FILES);
String site = parameters.get(PARAM_SITE);
if (deletedList != null) {
StringTokenizer tokens = new StringTokenizer(deletedList, FILES_SEPARATOR);
List deletedFiles = new ArrayList(tokens.countTokens());
while (tokens.hasMoreElements()) {
String contentLocation = tokens.nextToken();
contentLocation = StringUtils.trimWhitespace(contentLocation);
String root = target.getParameter(CONFIG_ROOT);
String fullPath = root + File.separator + target.getParameter(CONFIG_CONTENT_FOLDER) + contentLocation;
if (LOGGER.isInfoEnabled()) {
LOGGER.info("deleting " + fullPath);
}
if (StringUtils.hasText(site)) {
fullPath = fullPath.replaceAll(CONFIG_MULTI_TENANCY_VARIABLE, site);
}
File file = new File(fullPath);
if (file.exists()) {
if (file.isFile()) {
file.delete();
deletedFiles.add(contentLocation);
} else {
deleteChildren(file.list(), fullPath, contentLocation, deletedFiles);
file.delete();
}
} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(fullPath + " is not deleted since it does not exsit.");
}
}
fullPath = root + '/' + target.getParameter(CONFIG_METADATA_FOLDER) +
contentLocation + CONFIG_METADATA_FILENAME_SUFFIX;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("deleting " + fullPath);
}
if (StringUtils.hasText(site)) {
fullPath = fullPath.replaceAll(CONFIG_MULTI_TENANCY_VARIABLE, site);
}
file = new File(fullPath);
if (file.exists()) {
file.delete();
}
else if (LOGGER.isDebugEnabled()) {
LOGGER.debug(fullPath + " is not deleted since it does not exsit.");
}
}
changeSet.setDeletedFiles(deletedFiles);
}
}
/**
* delete child items
*
* @param children
* @param parentPath
* @param deletedFiles
*/
private void deleteChildren(String[] children, String parentFullPath, String parentPath, List deletedFiles) {
if (children != null) {
for (String child : children) {
String childFullPath = parentFullPath + File.separator + child;
String childPath = parentPath + File.separator + child;
File file = new File(childFullPath);
if (file.isFile()) {
file.delete();
deletedFiles.add(childPath);
} else {
deleteChildren(file.list(), childFullPath, childPath, deletedFiles);
file.delete();
}
}
}
}
/**
* run published files through the post processors
*
* @param changeSet
* @param parameters
* @param target
*/
protected void doPostProcessing(PublishedChangeSet changeSet, Map parameters, PublishingTarget target) {
List postProcessors = target.getPostProcessors();
if (postProcessors != null) {
try {
for (PublishingProcessor processor : postProcessors) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Running files through " + processor.getName());
}
processor.doProcess(changeSet, parameters, target);
}
} catch (Exception e) {
LOGGER.error("Error while running a post processor", e);
}
}
}
/**
* @return the targetManager
*/
public TargetManager getTargetManager() {
return targetManager;
}
/**
* @param targetManager the targetManager to set
*/
public void setTargetManager(TargetManager targetManager) {
this.targetManager = targetManager;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy