VIVO-848 Move the FileStorage system behind an interface
Add it to the Application framework, and do some cleanup.
This commit is contained in:
parent
c751ecdc6d
commit
6e5bbaeef8
24 changed files with 232 additions and 260 deletions
|
@ -6,12 +6,16 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageImplWrapper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.imageprocessor.jai.JaiImageProcessor;
|
import edu.cornell.mannlib.vitro.webapp.imageprocessor.jai.JaiImageProcessor;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||||
import edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineWrapper;
|
import edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineWrapper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine;
|
import edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl;
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +29,7 @@ public class ApplicationImpl implements Application {
|
||||||
private final ServletContext ctx;
|
private final ServletContext ctx;
|
||||||
private SearchEngine searchEngine;
|
private SearchEngine searchEngine;
|
||||||
private ImageProcessor imageProcessor;
|
private ImageProcessor imageProcessor;
|
||||||
|
private FileStorage fileStorage;
|
||||||
|
|
||||||
public ApplicationImpl(ServletContext ctx) {
|
public ApplicationImpl(ServletContext ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
@ -44,6 +49,7 @@ public class ApplicationImpl implements Application {
|
||||||
this.searchEngine = searchEngine;
|
this.searchEngine = searchEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ImageProcessor getImageProcessor() {
|
public ImageProcessor getImageProcessor() {
|
||||||
return imageProcessor;
|
return imageProcessor;
|
||||||
}
|
}
|
||||||
|
@ -52,11 +58,21 @@ public class ApplicationImpl implements Application {
|
||||||
this.imageProcessor = imageProcessor;
|
this.imageProcessor = imageProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileStorage getFileStorage() {
|
||||||
|
return fileStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileStorage(FileStorage fileStorage) {
|
||||||
|
this.fileStorage = fileStorage;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// The Setup class.
|
// The Setup class.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
public static class Setup implements ServletContextListener {
|
public static class Setup implements ServletContextListener {
|
||||||
|
private ApplicationImpl application;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
@ -64,14 +80,26 @@ public class ApplicationImpl implements Application {
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ApplicationImpl application = new ApplicationImpl(ctx);
|
application = new ApplicationImpl(ctx);
|
||||||
|
|
||||||
|
ComponentStartupStatus css = new ComponentStartupStatusImpl(
|
||||||
|
this, ss);
|
||||||
|
|
||||||
SearchEngine searchEngine = new SearchEngineWrapper(
|
SearchEngine searchEngine = new SearchEngineWrapper(
|
||||||
new SolrSearchEngine());
|
new SolrSearchEngine());
|
||||||
|
searchEngine.startup(application, css);
|
||||||
application.setSearchEngine(searchEngine);
|
application.setSearchEngine(searchEngine);
|
||||||
|
ss.info(this, "Started the searchEngine: " + searchEngine);
|
||||||
|
|
||||||
ImageProcessor imageProcessor = new JaiImageProcessor();
|
ImageProcessor imageProcessor = new JaiImageProcessor();
|
||||||
|
imageProcessor.startup(application, css);
|
||||||
application.setImageProcessor(imageProcessor);
|
application.setImageProcessor(imageProcessor);
|
||||||
|
ss.info(this, "Started the ImageProcessor: " + searchEngine);
|
||||||
|
|
||||||
|
FileStorage fileStorage = new FileStorageImplWrapper();
|
||||||
|
fileStorage.startup(application, css);
|
||||||
|
application.setFileStorage(fileStorage);
|
||||||
|
ss.info(this, "Started the FileStorage system: " + searchEngine);
|
||||||
|
|
||||||
ApplicationUtils.setInstance(application);
|
ApplicationUtils.setInstance(application);
|
||||||
ss.info(this, "Appliation is configured.");
|
ss.info(this, "Appliation is configured.");
|
||||||
|
@ -82,7 +110,9 @@ public class ApplicationImpl implements Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
// Nothing to tear down.
|
application.getFileStorage().shutdown(application);
|
||||||
|
application.getImageProcessor().shutdown(application);
|
||||||
|
application.getSearchEngine().shutdown(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.UNAUTHORIZED;
|
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.UNAUTHORIZED;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.UnavailableException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.commons.fileupload.FileItem;
|
import org.apache.commons.fileupload.FileItem;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
|
||||||
|
@ -27,11 +27,10 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.For
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.CropRectangle;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.CropRectangle;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.Dimensions;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.Dimensions;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
@ -115,23 +114,7 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
@Override
|
@Override
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
super.init();
|
super.init();
|
||||||
Object o = getServletContext().getAttribute(
|
fileStorage = ApplicationUtils.instance().getFileStorage();
|
||||||
FileStorageSetup.ATTRIBUTE_NAME);
|
|
||||||
if (o instanceof FileStorage) {
|
|
||||||
fileStorage = (FileStorage) o;
|
|
||||||
} else if (o == null) {
|
|
||||||
throw new UnavailableException(this.getClass().getSimpleName()
|
|
||||||
+ " could not initialize. Attribute '"
|
|
||||||
+ FileStorageSetup.ATTRIBUTE_NAME
|
|
||||||
+ "' was not set in the servlet context.");
|
|
||||||
} else {
|
|
||||||
throw new UnavailableException(this.getClass().getSimpleName()
|
|
||||||
+ " could not initialize. Attribute '"
|
|
||||||
+ FileStorageSetup.ATTRIBUTE_NAME
|
|
||||||
+ "' in the servlet context contained an instance of '"
|
|
||||||
+ o.getClass().getName() + "' instead of '"
|
|
||||||
+ FileStorage.class.getName() + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,9 +28,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadControl
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.TempFileHolder;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.TempFileHolder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.CropRectangle;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.CropRectangle;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.Dimensions;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.Dimensions;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.ImageProcessorException;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.ImageProcessorException;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static methods to help when serving uploaded files.
|
* Static methods to help when serving uploaded files.
|
||||||
|
@ -19,6 +18,8 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
||||||
public class FileServingHelper {
|
public class FileServingHelper {
|
||||||
private static final Log log = LogFactory.getLog(FileServingHelper.class);
|
private static final Log log = LogFactory.getLog(FileServingHelper.class);
|
||||||
|
|
||||||
|
public static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace";
|
||||||
|
|
||||||
private static final String DEFAULT_PATH = "/individual/";
|
private static final String DEFAULT_PATH = "/individual/";
|
||||||
private static final String FILE_PATH = "/file/";
|
private static final String FILE_PATH = "/file/";
|
||||||
private static boolean warned; // Only issue the warning once.
|
private static boolean warned; // Only issue the warning once.
|
||||||
|
@ -29,11 +30,11 @@ public class FileServingHelper {
|
||||||
*/
|
*/
|
||||||
private static String getDefaultNamespace(ServletContext ctx) {
|
private static String getDefaultNamespace(ServletContext ctx) {
|
||||||
String defaultNamespace = ConfigurationProperties.getBean(ctx)
|
String defaultNamespace = ConfigurationProperties.getBean(ctx)
|
||||||
.getProperty(FileStorageSetup.PROPERTY_DEFAULT_NAMESPACE);
|
.getProperty(PROPERTY_DEFAULT_NAMESPACE);
|
||||||
if (defaultNamespace == null) {
|
if (defaultNamespace == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Configuration properties must contain a value for '"
|
"Configuration properties must contain a value for '"
|
||||||
+ FileStorageSetup.PROPERTY_DEFAULT_NAMESPACE + "'");
|
+ PROPERTY_DEFAULT_NAMESPACE + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defaultNamespace.endsWith(DEFAULT_PATH)) {
|
if (!defaultNamespace.endsWith(DEFAULT_PATH)) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.filestorage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import javax.servlet.http.HttpSessionBindingEvent;
|
import javax.servlet.http.HttpSessionBindingEvent;
|
||||||
import javax.servlet.http.HttpSessionBindingListener;
|
import javax.servlet.http.HttpSessionBindingListener;
|
||||||
|
@ -12,9 +11,9 @@ import javax.servlet.http.HttpSessionBindingListener;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches an uploaded file to the session with a listener, so the file will be
|
* Attaches an uploaded file to the session with a listener, so the file will be
|
||||||
|
@ -109,6 +108,7 @@ public class TempFileHolder implements HttpSessionBindingListener {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void valueBound(HttpSessionBindingEvent event) {
|
public void valueBound(HttpSessionBindingEvent event) {
|
||||||
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,17 +130,7 @@ public class TempFileHolder implements HttpSessionBindingListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpSession session = event.getSession();
|
FileStorage fs = ApplicationUtils.instance().getFileStorage();
|
||||||
ServletContext servletContext = session.getServletContext();
|
|
||||||
|
|
||||||
FileStorage fs = (FileStorage) servletContext
|
|
||||||
.getAttribute(FileStorageSetup.ATTRIBUTE_NAME);
|
|
||||||
if (fs == null) {
|
|
||||||
log.error("Servlet context does not contain file storage at '"
|
|
||||||
+ FileStorageSetup.ATTRIBUTE_NAME + "'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.deleteFile(fileInfo.getBytestreamUri());
|
fs.deleteFile(fileInfo.getBytestreamUri());
|
||||||
log.debug("Deleted file " + fileInfo);
|
log.debug("Deleted file " + fileInfo);
|
||||||
|
|
|
@ -22,10 +22,10 @@ import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper object to handle the mundane details of dealing with uploaded files
|
* A helper object to handle the mundane details of dealing with uploaded files
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
import javax.servlet.ServletContextListener;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the file storage system, and stores a reference in the servlet
|
|
||||||
* context.
|
|
||||||
*/
|
|
||||||
public class FileStorageSetup implements ServletContextListener {
|
|
||||||
private static final Log log = LogFactory.getLog(FileStorageSetup.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The implementation of the {@link FileStorage} system will be stored in
|
|
||||||
* the {@link ServletContext} as an attribute with this name.
|
|
||||||
*/
|
|
||||||
public static final String ATTRIBUTE_NAME = FileStorage.class.getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default implementation will use this key to ask
|
|
||||||
* {@link ConfigurationProperties} for the vivo home directory. The file
|
|
||||||
* storage base directory is in a subdirectory below this one.
|
|
||||||
*/
|
|
||||||
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
|
|
||||||
public static final String FILE_STORAGE_SUBDIRECTORY = "uploads";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default implementation will use this key to ask
|
|
||||||
* {@link ConfigurationProperties} for the default URI namespace.
|
|
||||||
*/
|
|
||||||
public static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an implementation of {@link FileStorage} and store it in the
|
|
||||||
* {@link ServletContext}, as an attribute named according to
|
|
||||||
* {@link #ATTRIBUTE_NAME}.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
|
||||||
ServletContext ctx = sce.getServletContext();
|
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
|
||||||
|
|
||||||
try {
|
|
||||||
File baseDirectory = figureBaseDir(sce);
|
|
||||||
Collection<String> fileNamespace = confirmDefaultNamespace(sce);
|
|
||||||
FileStorage fs = new FileStorageImpl(baseDirectory, fileNamespace);
|
|
||||||
|
|
||||||
ctx.setAttribute(ATTRIBUTE_NAME, fs);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.fatal("Failed to initialize the file system.", e);
|
|
||||||
ss.fatal(this, "Failed to initialize the file system.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration property for the file storage base directory, and
|
|
||||||
* check that it points to an existing, writeable directory.
|
|
||||||
*
|
|
||||||
* For use by the constructor in implementations of {@link FileStorage}.
|
|
||||||
*/
|
|
||||||
private File figureBaseDir(ServletContextEvent sce) throws IOException {
|
|
||||||
String homeDirPath = ConfigurationProperties.getBean(sce).getProperty(
|
|
||||||
PROPERTY_VITRO_HOME_DIR);
|
|
||||||
if (homeDirPath == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Configuration properties must contain a value for '"
|
|
||||||
+ PROPERTY_VITRO_HOME_DIR + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
File homeDir = new File(homeDirPath);
|
|
||||||
if (!homeDir.exists()) {
|
|
||||||
throw new IllegalStateException("Vitro home directory '"
|
|
||||||
+ homeDir.getAbsolutePath() + "' does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
File baseDir = new File(homeDir, FILE_STORAGE_SUBDIRECTORY);
|
|
||||||
if (!baseDir.exists()) {
|
|
||||||
boolean created = baseDir.mkdir();
|
|
||||||
if (!created) {
|
|
||||||
throw new IOException("Unable to create uploads directory at '"
|
|
||||||
+ baseDir + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return baseDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration property for the default namespace. For use by the
|
|
||||||
* constructor in implementations of {@link FileStorage}.
|
|
||||||
*
|
|
||||||
* @returns a collection containing the default namespace.
|
|
||||||
*/
|
|
||||||
private Collection<String> confirmDefaultNamespace(ServletContextEvent sce) {
|
|
||||||
String defaultNamespace = ConfigurationProperties.getBean(sce)
|
|
||||||
.getProperty(PROPERTY_DEFAULT_NAMESPACE);
|
|
||||||
if (defaultNamespace == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Configuration properties must contain a value for '"
|
|
||||||
+ PROPERTY_DEFAULT_NAMESPACE + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.singleton(defaultNamespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
|
||||||
// Nothing to do here.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage.SHORTY_LENGTH;
|
import static edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageImpl.SHORTY_LENGTH;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
|
@ -24,10 +24,29 @@ import java.util.Properties;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default implementation of {@link FileStorage}.
|
* The default implementation of {@link FileStorage}.
|
||||||
*/
|
*/
|
||||||
public class FileStorageImpl implements FileStorage {
|
public class FileStorageImpl {
|
||||||
|
/**
|
||||||
|
* The name of the root directory, within the base directory.
|
||||||
|
*/
|
||||||
|
public static final String FILE_STORAGE_ROOT = "file_storage_root";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the file in the base directory that holds the namespace map.
|
||||||
|
*/
|
||||||
|
public static final String FILE_STORAGE_NAMESPACES_PROPERTIES = "file_storage_namespaces.properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How often to we insert path separator characters?
|
||||||
|
*/
|
||||||
|
public static final int SHORTY_LENGTH = 3;
|
||||||
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(FileStorageImpl.class);
|
private static final Log log = LogFactory.getLog(FileStorageImpl.class);
|
||||||
|
|
||||||
private final File baseDir;
|
private final File baseDir;
|
||||||
|
@ -240,7 +259,6 @@ public class FileStorageImpl implements FileStorage {
|
||||||
* directories to put it in.
|
* directories to put it in.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void createFile(String id, String filename, InputStream bytes)
|
public void createFile(String id, String filename, InputStream bytes)
|
||||||
throws FileAlreadyExistsException, IOException {
|
throws FileAlreadyExistsException, IOException {
|
||||||
String existingFilename = getFilename(id);
|
String existingFilename = getFilename(id);
|
||||||
|
@ -291,7 +309,6 @@ public class FileStorageImpl implements FileStorage {
|
||||||
* will be deleted. This repeats, up to (but not including) the root
|
* will be deleted. This repeats, up to (but not including) the root
|
||||||
* directory.
|
* directory.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean deleteFile(String id) throws IOException {
|
public boolean deleteFile(String id) throws IOException {
|
||||||
String existingFilename = getFilename(id);
|
String existingFilename = getFilename(id);
|
||||||
if (existingFilename == null) {
|
if (existingFilename == null) {
|
||||||
|
@ -356,14 +373,12 @@ public class FileStorageImpl implements FileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
|
||||||
* <p>
|
* <p>
|
||||||
* For a non-null result, a directory must exist for the ID, and it must
|
* For a non-null result, a directory must exist for the ID, and it must
|
||||||
* contain a file (it may or may not contain other directories).
|
* contain a file (it may or may not contain other directories).
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override
|
public String getFilename(String id) {
|
||||||
public String getFilename(String id) throws IOException {
|
|
||||||
File dir = FileStorageHelper.getPathToIdDirectory(id,
|
File dir = FileStorageHelper.getPathToIdDirectory(id,
|
||||||
this.namespacesMap, this.rootDir);
|
this.namespacesMap, this.rootDir);
|
||||||
log.debug("ID '" + id + "' translates to this directory path: '" + dir
|
log.debug("ID '" + id + "' translates to this directory path: '" + dir
|
||||||
|
@ -374,6 +389,7 @@ public class FileStorageImpl implements FileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
File[] files = dir.listFiles(new FileFilter() {
|
File[] files = dir.listFiles(new FileFilter() {
|
||||||
|
@Override
|
||||||
public boolean accept(File pathname) {
|
public boolean accept(File pathname) {
|
||||||
return pathname.isFile();
|
return pathname.isFile();
|
||||||
}
|
}
|
||||||
|
@ -395,7 +411,6 @@ public class FileStorageImpl implements FileStorage {
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public InputStream getInputStream(String id, String filename)
|
public InputStream getInputStream(String id, String filename)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A thin wrapper around the existing FileStorageImpl. Handles the setup.
|
||||||
|
*/
|
||||||
|
public class FileStorageImplWrapper implements FileStorage {
|
||||||
|
public static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace";
|
||||||
|
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
|
||||||
|
public static final String FILE_STORAGE_SUBDIRECTORY = "uploads";
|
||||||
|
|
||||||
|
private FileStorageImpl fs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of FileStorageImpl, based on the values in runtime.properties.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startup(Application application, ComponentStartupStatus ss) {
|
||||||
|
ServletContext ctx = application.getServletContext();
|
||||||
|
|
||||||
|
try {
|
||||||
|
File baseDirectory = figureBaseDir(ctx);
|
||||||
|
Collection<String> fileNamespace = confirmDefaultNamespace(ctx);
|
||||||
|
fs = new FileStorageImpl(baseDirectory, fileNamespace);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ss.fatal("Failed to initialize the file system.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration property for the file storage base directory, and
|
||||||
|
* check that it points to an existing, writeable directory.
|
||||||
|
*/
|
||||||
|
private File figureBaseDir(ServletContext ctx) throws IOException {
|
||||||
|
String homeDirPath = ConfigurationProperties.getBean(ctx).getProperty(
|
||||||
|
PROPERTY_VITRO_HOME_DIR);
|
||||||
|
if (homeDirPath == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Configuration properties must contain a value for '"
|
||||||
|
+ PROPERTY_VITRO_HOME_DIR + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
File homeDir = new File(homeDirPath);
|
||||||
|
if (!homeDir.exists()) {
|
||||||
|
throw new IllegalStateException("Vitro home directory '"
|
||||||
|
+ homeDir.getAbsolutePath() + "' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
File baseDir = new File(homeDir, FILE_STORAGE_SUBDIRECTORY);
|
||||||
|
if (!baseDir.exists()) {
|
||||||
|
boolean created = baseDir.mkdir();
|
||||||
|
if (!created) {
|
||||||
|
throw new IOException("Unable to create uploads directory at '"
|
||||||
|
+ baseDir + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration property for the default namespace.
|
||||||
|
*/
|
||||||
|
private Collection<String> confirmDefaultNamespace(ServletContext ctx) {
|
||||||
|
String defaultNamespace = ConfigurationProperties.getBean(ctx)
|
||||||
|
.getProperty(PROPERTY_DEFAULT_NAMESPACE);
|
||||||
|
if (defaultNamespace == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Configuration properties must contain a value for '"
|
||||||
|
+ PROPERTY_DEFAULT_NAMESPACE + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.singleton(defaultNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown(Application application) {
|
||||||
|
// Nothing to shut down.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Delegated methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createFile(String id, String filename, InputStream bytes)
|
||||||
|
throws FileAlreadyExistsException, IOException {
|
||||||
|
fs.createFile(id, filename, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilename(String id) throws IOException {
|
||||||
|
return fs.getFilename(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream(String id, String filename)
|
||||||
|
throws FileNotFoundException, IOException {
|
||||||
|
return fs.getInputStream(id, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteFile(String id) throws IOException {
|
||||||
|
return fs.deleteFile(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that an object ID contains an invalid character.
|
* Indicates that an object ID contains an invalid character.
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a PairTree path ("ppath" or "relative path") that is not correctly
|
* Indicates a PairTree path ("ppath" or "relative path") that is not correctly
|
|
@ -273,10 +273,10 @@ but is different in several respects:
|
||||||
<p>
|
<p>
|
||||||
By the way, almost all of this is implemented in
|
By the way, almost all of this is implemented in
|
||||||
<pre>
|
<pre>
|
||||||
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageHelper
|
edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageHelper
|
||||||
</pre>
|
</pre>
|
||||||
and illustrated in
|
and illustrated in
|
||||||
<pre>
|
<pre>
|
||||||
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageHelperTest
|
edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageHelperTest
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
|
@ -12,19 +12,18 @@ import java.net.URLDecoder;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.UnavailableException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -59,16 +58,8 @@ public class FileServingServlet extends VitroHttpServlet {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
Object o = getServletContext().getAttribute(
|
super.init();
|
||||||
FileStorageSetup.ATTRIBUTE_NAME);
|
fileStorage = ApplicationUtils.instance().getFileStorage();
|
||||||
if (o instanceof FileStorage) {
|
|
||||||
fileStorage = (FileStorage) o;
|
|
||||||
} else {
|
|
||||||
throw new UnavailableException(
|
|
||||||
"The ServletContext did not hold a FileStorage object at '"
|
|
||||||
+ FileStorageSetup.ATTRIBUTE_NAME
|
|
||||||
+ "'; found this instead: " + o);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -220,10 +211,6 @@ public class FileServingServlet extends VitroHttpServlet {
|
||||||
public FileServingException(String message) {
|
public FileServingException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileServingException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.modules;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||||
|
|
||||||
|
@ -17,6 +18,8 @@ public interface Application {
|
||||||
|
|
||||||
ImageProcessor getImageProcessor();
|
ImageProcessor getImageProcessor();
|
||||||
|
|
||||||
|
FileStorage getFileStorage();
|
||||||
|
|
||||||
public interface Component {
|
public interface Component {
|
||||||
enum LifecycleState {
|
enum LifecycleState {
|
||||||
NEW, ACTIVE, STOPPED
|
NEW, ACTIVE, STOPPED
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.modules.fileStorage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -1,30 +1,17 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.modules.fileStorage;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for the File Storage system.
|
* The interface for the File Storage system.
|
||||||
*/
|
*/
|
||||||
public interface FileStorage {
|
public interface FileStorage extends Application.Module {
|
||||||
/**
|
|
||||||
* The name of the root directory, within the base directory.
|
|
||||||
*/
|
|
||||||
public static final String FILE_STORAGE_ROOT = "file_storage_root";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the file in the base directory that holds the namespace map.
|
|
||||||
*/
|
|
||||||
public static final String FILE_STORAGE_NAMESPACES_PROPERTIES = "file_storage_namespaces.properties";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How often to we insert path separator characters?
|
|
||||||
*/
|
|
||||||
int SHORTY_LENGTH = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the bytes from this stream as a file with the specified ID and
|
* Store the bytes from this stream as a file with the specified ID and
|
||||||
* filename. If the file already exists, it is over-written.
|
* filename. If the file already exists, it is over-written.
|
|
@ -1,32 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.searchengine;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
import javax.servlet.ServletContextListener;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whatever search engine we have, start it up and shut it down.
|
|
||||||
*/
|
|
||||||
public class SearchEngineSetup implements ServletContextListener {
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
|
||||||
Application application = ApplicationUtils.instance();
|
|
||||||
StartupStatus ss = StartupStatus.getBean(sce.getServletContext());
|
|
||||||
ComponentStartupStatus css = new ComponentStartupStatusImpl(this, ss);
|
|
||||||
application.getSearchEngine().startup(application, css);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
|
||||||
Application application = ApplicationUtils.instance();
|
|
||||||
application.getSearchEngine().shutdown(application);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -96,7 +96,7 @@ public class SearchEngineWrapper implements SearchEngine {
|
||||||
try {
|
try {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("startup called when state was " + lifecycleState, e);
|
log.warn("shutdown called when state was " + lifecycleState, e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub
|
||||||
import stubs.javax.servlet.ServletContextStub;
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +34,7 @@ public class FileServingHelperTest extends AbstractTestClass {
|
||||||
ctx = new ServletContextStub();
|
ctx = new ServletContextStub();
|
||||||
|
|
||||||
ConfigurationPropertiesStub props = new ConfigurationPropertiesStub();
|
ConfigurationPropertiesStub props = new ConfigurationPropertiesStub();
|
||||||
props.setProperty(FileStorageSetup.PROPERTY_DEFAULT_NAMESPACE,
|
props.setProperty(FileServingHelper.PROPERTY_DEFAULT_NAMESPACE,
|
||||||
DEFAULT_NAMESPACE);
|
DEFAULT_NAMESPACE);
|
||||||
props.setBean(ctx);
|
props.setBean(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.backend;
|
package edu.cornell.mannlib.vitro.webapp.filestorage.impl;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageImpl.FILE_STORAGE_NAMESPACES_PROPERTIES;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageImpl.FILE_STORAGE_ROOT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -26,6 +28,7 @@ import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the FileStorage methods. The zero-argument constructor was tested in
|
* Test the FileStorage methods. The zero-argument constructor was tested in
|
||||||
|
@ -55,26 +58,29 @@ public class FileStorageImplTest extends AbstractTestClass {
|
||||||
// tests
|
// tests
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void baseDirDoesntExist() throws IOException {
|
public void baseDirDoesntExist() throws IOException {
|
||||||
File baseDir = new File(tempDir, "doesntExist");
|
File baseDir = new File(tempDir, "doesntExist");
|
||||||
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
public void partialInitializationRoot() throws IOException {
|
public void partialInitializationRoot() throws IOException {
|
||||||
File baseDir = new File(tempDir, "partialWithRoot");
|
File baseDir = new File(tempDir, "partialWithRoot");
|
||||||
baseDir.mkdir();
|
baseDir.mkdir();
|
||||||
new File(baseDir, FileStorage.FILE_STORAGE_ROOT).mkdir();
|
new File(baseDir, FILE_STORAGE_ROOT).mkdir();
|
||||||
|
|
||||||
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
public void partialInitializationNamespaces() throws IOException {
|
public void partialInitializationNamespaces() throws IOException {
|
||||||
File baseDir = new File(tempDir, "partialWithNamespaces");
|
File baseDir = new File(tempDir, "partialWithNamespaces");
|
||||||
baseDir.mkdir();
|
baseDir.mkdir();
|
||||||
new File(baseDir, FileStorage.FILE_STORAGE_NAMESPACES_PROPERTIES)
|
new File(baseDir, FILE_STORAGE_NAMESPACES_PROPERTIES)
|
||||||
.createNewFile();
|
.createNewFile();
|
||||||
|
|
||||||
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
new FileStorageImpl(baseDir, EMPTY_NAMESPACES);
|
||||||
|
@ -276,7 +282,7 @@ public class FileStorageImplTest extends AbstractTestClass {
|
||||||
*/
|
*/
|
||||||
private void assertFileContents(FileStorageImpl fs, String id,
|
private void assertFileContents(FileStorageImpl fs, String id,
|
||||||
String filename, String expectedContents) throws IOException {
|
String filename, String expectedContents) throws IOException {
|
||||||
File rootDir = new File(fs.getBaseDir(), FileStorage.FILE_STORAGE_ROOT);
|
File rootDir = new File(fs.getBaseDir(), FILE_STORAGE_ROOT);
|
||||||
File path = FileStorageHelper.getFullPath(rootDir, id, filename,
|
File path = FileStorageHelper.getFullPath(rootDir, id, filename,
|
||||||
fs.getNamespaces());
|
fs.getNamespaces());
|
||||||
|
|
|
@ -8,6 +8,7 @@ import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||||
|
|
||||||
|
@ -66,4 +67,11 @@ public class ApplicationStub implements Application {
|
||||||
"ApplicationStub.getImageProcessor() not implemented.");
|
"ApplicationStub.getImageProcessor() not implemented.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileStorage getFileStorage() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"ApplicationStub.getFileStorage() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.RDFSetup
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.ConfigurationModelsSetup
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ConfigurationModelsSetup
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
|
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
|
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
|
||||||
|
|
||||||
# Some permissions were removed in release 1.7
|
# Some permissions were removed in release 1.7
|
||||||
|
@ -65,7 +63,6 @@ edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup
|
||||||
|
|
||||||
# The search indexer uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
# The search indexer uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
||||||
# and the PermissionRegistry must already be set up.
|
# and the PermissionRegistry must already be set up.
|
||||||
edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineSetup
|
|
||||||
edu.cornell.mannlib.vitro.webapp.searchindex.SearchIndexerSetup
|
edu.cornell.mannlib.vitro.webapp.searchindex.SearchIndexerSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
|
edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
|
||||||
|
|
Loading…
Add table
Reference in a new issue