VIVO-906 Assemble application at runtime.

Create an object to represent VitroHomeDirectory
Instantiate TripleSources, FileStorage, etc, based on the config file.
This commit is contained in:
Jim Blake 2014-11-13 17:11:11 -05:00
parent e3dca6a699
commit ebb31eb081
22 changed files with 665 additions and 440 deletions

View file

@ -269,6 +269,12 @@
<include name="example.developer.properties" /> <include name="example.developer.properties" />
</fileset> </fileset>
</copy> </copy>
<mkdir dir="${vitrohome.image.dir}/config" />
<copy todir="${vitrohome.image.dir}/config" >
<fileset dir="${appbase.dir}/config" >
<include name="applicationSetup.n3" />
</fileset>
</copy>
<copy todir="${vitrohome.image.dir}" > <copy todir="${vitrohome.image.dir}" >
<fileset dir="${appbase.dir}" > <fileset dir="${appbase.dir}" >
<include name="rdf/**/*" /> <include name="rdf/**/*" />

View file

@ -2,21 +2,28 @@
package edu.cornell.mannlib.vitro.webapp.application; package edu.cornell.mannlib.vitro.webapp.application;
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION;
import javax.servlet.ServletContext; 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 com.hp.hpl.jena.ontology.OntDocumentManager;
import edu.cornell.mannlib.vitro.webapp.imageprocessor.jai.JaiImageProcessor;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
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.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage; 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.InstrumentedSearchEngineWrapper; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource;
import edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.triplesource.impl.BasicCombinedTripleSource;
import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl; import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation;
/** /**
* The basic implementation of the Application interface. * The basic implementation of the Application interface.
@ -26,12 +33,16 @@ public class ApplicationImpl implements Application {
// The instance // The instance
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private final ServletContext ctx; private ServletContext ctx;
private VitroHomeDirectory homeDirectory;
private SearchEngine searchEngine; private SearchEngine searchEngine;
private ImageProcessor imageProcessor; private ImageProcessor imageProcessor;
private FileStorage fileStorage; private FileStorage fileStorage;
private ContentTripleSource contentTripleSource;
private ConfigurationTripleSource configurationTripleSource;
public ApplicationImpl(ServletContext ctx) { public void setServletContext(ServletContext ctx) {
this.ctx = ctx; this.ctx = ctx;
} }
@ -40,13 +51,29 @@ public class ApplicationImpl implements Application {
return ctx; return ctx;
} }
@Override
public VitroHomeDirectory getHomeDirectory() {
return homeDirectory;
}
public void setHomeDirectory(VitroHomeDirectory homeDirectory) {
this.homeDirectory = homeDirectory;
}
@Override @Override
public SearchEngine getSearchEngine() { public SearchEngine getSearchEngine() {
return searchEngine; return searchEngine;
} }
public void setSearchEngine(SearchEngine searchEngine) { @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasSearchEngine")
this.searchEngine = searchEngine; public void setSearchEngine(SearchEngine se) {
if (searchEngine == null) {
searchEngine = se;
} else {
throw new IllegalStateException(
"Configuration includes multiple SearchEngine instancess: "
+ searchEngine + ", and " + se);
}
} }
@Override @Override
@ -54,8 +81,15 @@ public class ApplicationImpl implements Application {
return imageProcessor; return imageProcessor;
} }
public void setImageProcessor(ImageProcessor imageProcessor) { @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasImageProcessor")
this.imageProcessor = imageProcessor; public void setImageProcessor(ImageProcessor ip) {
if (imageProcessor == null) {
imageProcessor = ip;
} else {
throw new IllegalStateException(
"Configuration includes multiple ImageProcessor instancess: "
+ imageProcessor + ", and " + ip);
}
} }
@Override @Override
@ -63,57 +97,151 @@ public class ApplicationImpl implements Application {
return fileStorage; return fileStorage;
} }
public void setFileStorage(FileStorage fileStorage) { @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasFileStorage")
this.fileStorage = fileStorage; public void setFileStorage(FileStorage fs) {
if (fileStorage == null) {
fileStorage = fs;
} else {
throw new IllegalStateException(
"Configuration includes multiple FileStorage intances: "
+ fileStorage + ", and " + fs);
}
}
@Override
public ContentTripleSource getContentTripleSource() {
return contentTripleSource;
}
@Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasContentTripleSource")
public void setContentTripleSource(ContentTripleSource source) {
if (contentTripleSource == null) {
contentTripleSource = source;
} else {
throw new IllegalStateException(
"Configuration includes multiple intances of ContentTripleSource: "
+ contentTripleSource + ", and " + source);
}
}
@Override
public ConfigurationTripleSource getConfigurationTripleSource() {
return configurationTripleSource;
}
@Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasConfigurationTripleSource")
public void setConfigurationTripleSource(ConfigurationTripleSource source) {
if (configurationTripleSource == null) {
configurationTripleSource = source;
} else {
throw new IllegalStateException(
"Configuration includes multiple intances of ConfigurationTripleSource: "
+ configurationTripleSource + ", and " + source);
}
}
@Validation
public void validate() throws Exception {
if (searchEngine == null) {
throw new IllegalStateException(
"Configuration did not include a SearchEngine.");
}
if (imageProcessor == null) {
throw new IllegalStateException(
"Configuration did not include an ImageProcessor.");
}
if (fileStorage == null) {
throw new IllegalStateException(
"Configuration did not include a FileStorage.");
}
if (contentTripleSource == null) {
throw new IllegalStateException(
"Configuration did not include a ContentTripleSource.");
}
if (configurationTripleSource == null) {
throw new IllegalStateException(
"Configuration did not include a ConfigurationTripleSource.");
}
}
@Override
public void shutdown() {
getFileStorage().shutdown(this);
getImageProcessor().shutdown(this);
getSearchEngine().shutdown(this);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// The Setup class. // Setup the major components.
//
// This must happen after the ConfigurationProperties and some other stuff.
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
public static class Setup implements ServletContextListener { public static class ComponentsSetup implements ServletContextListener {
private ApplicationImpl application;
@Override @Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext(); ServletContext ctx = sce.getServletContext();
Application app = ApplicationUtils.instance();
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
ComponentStartupStatus css = new ComponentStartupStatusImpl(this,
ss);
try { SearchEngine searchEngine = app.getSearchEngine();
application = new ApplicationImpl(ctx); searchEngine.startup(app, css);
ss.info(this, "Started the SearchEngine: " + searchEngine);
ComponentStartupStatus css = new ComponentStartupStatusImpl( ImageProcessor imageProcessor = app.getImageProcessor();
this, ss); imageProcessor.startup(app, css);
ss.info(this, "Started the ImageProcessor: " + imageProcessor);
SearchEngine searchEngine = new InstrumentedSearchEngineWrapper( FileStorage fileStorage = app.getFileStorage();
new SolrSearchEngine()); fileStorage.startup(app, css);
searchEngine.startup(application, css); ss.info(this, "Started the FileStorage system: " + fileStorage);
application.setSearchEngine(searchEngine);
ss.info(this, "Started the searchEngine: " + searchEngine);
ImageProcessor imageProcessor = new JaiImageProcessor(); ContentTripleSource contentTripleSource = app
imageProcessor.startup(application, css); .getContentTripleSource();
application.setImageProcessor(imageProcessor); contentTripleSource.startup(app, css);
ss.info(this, "Started the ImageProcessor: " + searchEngine); ss.info(this, "Started the ContentTripleSource: "
+ contentTripleSource);
FileStorage fileStorage = new FileStorageImplWrapper(); ConfigurationTripleSource configurationTripleSource = app
fileStorage.startup(application, css); .getConfigurationTripleSource();
application.setFileStorage(fileStorage); configurationTripleSource.startup(app, css);
ss.info(this, "Started the FileStorage system: " + searchEngine); ss.info(this, "Started the ConfigurationTripleSource: "
+ configurationTripleSource);
ApplicationUtils.setInstance(application); configureJena();
ss.info(this, "Appliation is configured."); prepareCombinedTripleSource(app, ctx);
} catch (Exception e) { }
ss.fatal(this, "Failed to initialize the Application.", e);
} private void configureJena() {
// we do not want to fetch imports when we wrap Models in OntModels
OntDocumentManager.getInstance().setProcessImports(false);
}
private void prepareCombinedTripleSource(Application app,
ServletContext ctx) {
ContentTripleSource contentSource = app.getContentTripleSource();
ConfigurationTripleSource configurationSource = app
.getConfigurationTripleSource();
BasicCombinedTripleSource source = new BasicCombinedTripleSource(
contentSource, configurationSource);
RDFServiceUtils.setRDFServiceFactory(ctx,
contentSource.getRDFServiceFactory());
RDFServiceUtils.setRDFServiceFactory(ctx,
configurationSource.getRDFServiceFactory(), CONFIGURATION);
ModelAccess.setCombinedTripleSource(source);
} }
@Override @Override
public void contextDestroyed(ServletContextEvent sce) { public void contextDestroyed(ServletContextEvent sce) {
application.getFileStorage().shutdown(application); Application app = ApplicationUtils.instance();
application.getImageProcessor().shutdown(application); app.getSearchEngine().shutdown(app);
application.getSearchEngine().shutdown(application); app.getImageProcessor().shutdown(app);
app.getFileStorage().shutdown(app);
} }
} }
} }

View file

@ -0,0 +1,115 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.application;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoaderException;
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel;
/**
* Read the application setup file and create the components it describes.
*/
public class ApplicationSetup implements ServletContextListener {
private static final String APPLICATION_SETUP_PATH = "config/applicationSetup.n3";
private ServletContext ctx;
private StartupStatus ss;
private ApplicationImpl app;
private VitroHomeDirectory vitroHomeDir;
private Path configFile;
private LockableModel configModel;
private ConfigurationBeanLoader loader;
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
this.ctx = sce.getServletContext();
this.ss = StartupStatus.getBean(ctx);
this.vitroHomeDir = VitroHomeDirectory.find(ctx);
ss.info(this, vitroHomeDir.getDiscoveryMessage());
locateApplicationConfigFile();
loadApplicationConfigFile();
createConfigurationBeanLoader();
instantiateTheApplication();
app.setServletContext(this.ctx);
app.setHomeDirectory(this.vitroHomeDir);
ApplicationUtils.setInstance(app);
ss.info(this, "Application is configured.");
} catch (Exception e) {
ss.fatal(this, "Failed to initialize the Application.", e);
}
}
private void locateApplicationConfigFile() {
Path path = this.vitroHomeDir.getPath().resolve(APPLICATION_SETUP_PATH);
if (!Files.exists(path)) {
throw new IllegalStateException("'" + path + "' does not exist.");
}
if (!Files.isReadable(path)) {
throw new IllegalStateException("Can't read '" + path + "'");
}
this.configFile = path;
}
private void loadApplicationConfigFile() {
try (InputStream in = Files.newInputStream(this.configFile)) {
Model m = ModelFactory.createDefaultModel();
m.read(in, null, "N3");
this.configModel = new LockableModel(m);
} catch (Exception e) {
throw new RuntimeException("Failed to read '" + this.configFile
+ "'", e);
}
}
private void createConfigurationBeanLoader() {
this.loader = new ConfigurationBeanLoader(configModel);
}
private void instantiateTheApplication() {
try {
Set<ApplicationImpl> apps = loader.loadAll(ApplicationImpl.class);
if (apps.isEmpty()) {
throw new IllegalStateException("'" + this.configFile
+ "' does not define an instance of "
+ ApplicationImpl.class.getName());
} else if (apps.size() > 1) {
throw new IllegalStateException("'" + this.configFile
+ "' defines " + apps.size() + " instances of "
+ ApplicationImpl.class.getName());
} else {
this.app = apps.iterator().next();
}
} catch (ConfigurationBeanLoaderException e) {
throw new IllegalStateException("Failed to setup the application",
e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (app != null) {
app.shutdown();
}
}
}

View file

@ -29,5 +29,4 @@ public class ApplicationUtils {
static void setInstance(Application application) { static void setInstance(Application application) {
instance = application; instance = application;
} }
} }

View file

@ -0,0 +1,54 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.application;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Obtains and provides the contents of the build.properties file.
*/
public class BuildProperties {
private static final Log log = LogFactory.getLog(BuildProperties.class);
/** Path to the file of build properties baked into the webapp. */
public static final String WEBAPP_PATH_BUILD_PROPERTIES = "/WEB-INF/resources/build.properties";
private final Map<String, String> propertyMap;
public BuildProperties(ServletContext ctx) {
Map<String, String> map = new HashMap<>();
try (InputStream stream = ctx
.getResourceAsStream(WEBAPP_PATH_BUILD_PROPERTIES)) {
if (stream == null) {
log.debug("Didn't find a resource at '"
+ WEBAPP_PATH_BUILD_PROPERTIES + "'.");
} else {
Properties props = new Properties();
props.load(stream);
for (String key : props.stringPropertyNames()) {
map.put(key, props.getProperty(key));
}
}
} catch (IOException e) {
throw new RuntimeException("Failed to load from '"
+ WEBAPP_PATH_BUILD_PROPERTIES + "'.", e);
}
propertyMap = Collections.unmodifiableMap(map);
}
public Map<String, String> getMap() {
return this.propertyMap;
}
}

View file

@ -0,0 +1,213 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.application;
import static edu.cornell.mannlib.vitro.webapp.application.BuildProperties.WEBAPP_PATH_BUILD_PROPERTIES;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Encapsulates some of the info relating to the Vitro home directory.
*/
public class VitroHomeDirectory {
private static final Log log = LogFactory.getLog(VitroHomeDirectory.class);
public static VitroHomeDirectory find(ServletContext ctx) {
HomeDirectoryFinder finder = new HomeDirectoryFinder(ctx);
return new VitroHomeDirectory(ctx, finder.getPath(),
finder.getMessage());
}
private final ServletContext ctx;
private final Path path;
private final String discoveryMessage;
public VitroHomeDirectory(ServletContext ctx, Path path,
String discoveryMessage) {
this.ctx = ctx;
this.path = path;
this.discoveryMessage = discoveryMessage;
}
public ServletContext getCtx() {
return ctx;
}
public Path getPath() {
return path;
}
public String getDiscoveryMessage() {
return discoveryMessage;
}
/**
* Find something that specifies the location of the Vitro home directory.
* Look in the JDNI environment, the system properties, and the
* build.properties file.
*
* If we don't find it, fail. If we find it more than once, use the first
* one (with a warning). If it is not an existing, readable directory, fail.
*/
private static class HomeDirectoryFinder {
/** JNDI path that defines the Vitro home directory */
private static final String VHD_JNDI_PATH = "java:comp/env/vitro/home";
/** System property that defines the Vitro home directory */
private static final String VHD_SYSTEM_PROPERTY = "vitro.home";
/** build.properties property that defines the Vitro home directory */
private static final String VHD_BUILD_PROPERTY = "vitro.home";
private final ServletContext ctx;
private final List<Found> foundLocations = new ArrayList<>();
public HomeDirectoryFinder(ServletContext ctx) {
this.ctx = ctx;
getVhdFromJndi();
getVhdFromSystemProperties();
getVhdFromBuildProperties();
confirmExactlyOneResult();
confirmValidDirectory();
}
public String getMessage() {
return foundLocations.get(0).getMessage();
}
public Path getPath() {
return foundLocations.get(0).getPath();
}
public void getVhdFromJndi() {
try {
String vhdPath = (String) new InitialContext()
.lookup(VHD_JNDI_PATH);
if (vhdPath == null) {
log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH
+ "'.");
} else {
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: "
+ vhdPath);
String message = String.format(
"JNDI environment '%s' was set to '%s'",
VHD_JNDI_PATH, vhdPath);
foundLocations.add(new Found(Paths.get(vhdPath), message));
}
} catch (Exception e) {
log.debug("JNDI lookup failed. " + e);
}
}
private void getVhdFromSystemProperties() {
String vhdPath = System.getProperty(VHD_SYSTEM_PROPERTY);
if (vhdPath == null) {
log.debug("Didn't find a system property value at '"
+ VHD_SYSTEM_PROPERTY + "'.");
} else {
log.debug("'" + VHD_SYSTEM_PROPERTY
+ "' as specified by system property: " + vhdPath);
String message = String.format(
"System property '%s' was set to '%s'",
VHD_SYSTEM_PROPERTY, vhdPath);
foundLocations.add(new Found(Paths.get(vhdPath), message));
}
}
private void getVhdFromBuildProperties() {
try {
Map<String, String> buildProps = new BuildProperties(ctx)
.getMap();
String vhdPath = buildProps.get(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("build properties doesn't contain a value for '"
+ VHD_BUILD_PROPERTY + "'.");
} else {
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.",
WEBAPP_PATH_BUILD_PROPERTIES, VHD_BUILD_PROPERTY,
vhdPath);
foundLocations.add(new Found(Paths.get(vhdPath), message));
}
} catch (Exception e) {
log.warn("Reading build properties failed. " + e);
}
}
private void confirmExactlyOneResult() {
if (foundLocations.isEmpty()) {
String message = String.format("Can't find a value "
+ "for the Vitro home directory. "
+ "Looked in JNDI environment at '%s'. "
+ "Looked for a system property named '%s'. "
+ "Looked in 'WEB-INF/resources/build.properties' "
+ "for '%s'.", VHD_JNDI_PATH, VHD_SYSTEM_PROPERTY,
VHD_BUILD_PROPERTY);
throw new IllegalStateException(message);
} else if (foundLocations.size() > 1) {
String message = String.format("Found multiple values for the "
+ "Vitro home directory: " + foundLocations);
log.warn(message);
}
}
private void confirmValidDirectory() {
Path vhd = getPath();
if (!Files.exists(vhd)) {
throw new IllegalStateException("Vitro home directory '" + vhd
+ "' does not exist.");
}
if (!Files.isDirectory(vhd)) {
throw new IllegalStateException("Vitro home directory '" + vhd
+ "' is not a directory.");
}
if (!Files.isReadable(vhd)) {
throw new IllegalStateException(
"Cannot read Vitro home directory '" + vhd + "'.");
}
if (!Files.isWritable(vhd)) {
throw new IllegalStateException(
"Can't write to Vitro home directory: '" + vhd + "'.");
}
}
/** We found it: where and how. */
private static class Found {
private final Path path;
private final String message;
public Found(Path path, String message) {
this.path = path;
this.message = message;
}
public Path getPath() {
return path;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "Found[path=" + path + ", message=" + message + "]";
}
}
}
}

View file

@ -7,12 +7,8 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
@ -20,6 +16,8 @@ import javax.servlet.ServletContextListener;
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.application.BuildProperties;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/** /**
@ -48,23 +46,11 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSetup.class); .getLog(ConfigurationPropertiesSetup.class);
/** JNDI path that defines the Vitro home directory */
private static final String VHD_JNDI_PATH = "java:comp/env/vitro/home";
/** System property that defines the Vitro home directory */
private static final String VHD_SYSTEM_PROPERTY = "vitro.home";
/** build.properties property that defines the Vitro home directory */
private static final String VHD_BUILD_PROPERTY = "vitro.home";
/** Configuration property to store the Vitro home directory */
private static final String VHD_CONFIGURATION_PROPERTY = "vitro.home";
/** Name of the file that contains runtime properties. */ /** Name of the file that contains runtime properties. */
private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties"; private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties";
/** Path to the file of build properties baked into the webapp. */ /** Configuration property to store the Vitro home directory */
private static final String PATH_BUILD_PROPERTIES = "/WEB-INF/resources/build.properties"; private static final String VHD_CONFIGURATION_PROPERTY = "vitro.home";
@Override @Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
@ -74,7 +60,8 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
try { try {
InputStream stream = null; InputStream stream = null;
try { try {
File vitroHomeDir = locateVitroHomeDirectory(ctx, ss); File vitroHomeDir = ApplicationUtils.instance()
.getHomeDirectory().getPath().toFile();
File runtimePropertiesFile = locateRuntimePropertiesFile( File runtimePropertiesFile = locateRuntimePropertiesFile(
vitroHomeDir, ss); vitroHomeDir, ss);
@ -84,7 +71,7 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
VHD_CONFIGURATION_PROPERTY, vitroHomeDir); VHD_CONFIGURATION_PROPERTY, vitroHomeDir);
ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl( ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl(
stream, preempts, getBuildProperties(ctx)); stream, preempts, new BuildProperties(ctx).getMap());
ConfigurationProperties.setBean(ctx, bean); ConfigurationProperties.setBean(ctx, bean);
ss.info(this, "Loaded " + bean.getPropertyMap().size() ss.info(this, "Loaded " + bean.getPropertyMap().size()
@ -103,141 +90,6 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
} }
} }
/**
* Look in the JDNI environment, the system properties, and the
* build.properties file.
*
* If we don't find it, fail. If we find it more than once, warn and use the
* first one.
*
* Confirm that it is an existing, readable directory.
*/
private File locateVitroHomeDirectory(ServletContext ctx, StartupStatus ss) {
Map<String, String> whereWasIt = new LinkedHashMap<String, String>();
getVhdFromJndi(whereWasIt);
getVhdFromSystemProperties(whereWasIt);
getVhdFromBuildProperties(ctx, whereWasIt);
if (whereWasIt.isEmpty()) {
String message = String.format("Can't find a value "
+ "for the Vitro home directory. "
+ "Looked in JNDI environment at '%s'. "
+ "Looked for a system property named '%s'. "
+ "Looked in 'WEB-INF/resources/build.properties' "
+ "for '%s'.", VHD_JNDI_PATH, VHD_SYSTEM_PROPERTY,
VHD_BUILD_PROPERTY);
throw new IllegalStateException(message);
} else if (whereWasIt.size() > 1) {
String message = String.format("Found multiple values for the "
+ "Vitro home directory: " + whereWasIt.keySet());
ss.warning(this, message);
}
String message = whereWasIt.keySet().iterator().next();
String vhdPath = whereWasIt.values().iterator().next();
ss.info(this, message);
File vhd = new File(vhdPath);
if (!vhd.exists()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' does not exist.");
}
if (!vhd.isDirectory()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' is not a directory.");
}
if (!vhd.canRead()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' cannot be read.");
}
if (!vhd.canWrite()) {
throw new IllegalStateException(
"Can't write to Vitro home directory: '" + vhdPath + "'.");
}
return vhd;
}
private void getVhdFromJndi(Map<String, String> whereWasIt) {
try {
String vhdPath = (String) new InitialContext()
.lookup(VHD_JNDI_PATH);
if (vhdPath == null) {
log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH
+ "'.");
return;
}
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: "
+ vhdPath);
String message = String.format(
"JNDI environment '%s' was set to '%s'", VHD_JNDI_PATH,
vhdPath);
whereWasIt.put(message, vhdPath);
} catch (NamingException e) {
log.debug("JNDI lookup failed. " + e);
}
}
private void getVhdFromSystemProperties(Map<String, String> whereWasIt) {
String vhdPath = System.getProperty(VHD_SYSTEM_PROPERTY);
if (vhdPath == null) {
log.debug("Didn't find a system property value at '"
+ VHD_SYSTEM_PROPERTY + "'.");
return;
}
log.debug("'" + VHD_SYSTEM_PROPERTY
+ "' as specified by system property: " + vhdPath);
String message = String.format("System property '%s' was set to '%s'",
VHD_SYSTEM_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
}
private void getVhdFromBuildProperties(ServletContext ctx,
Map<String, String> whereWasIt) {
Map<String, String> buildProps = getBuildProperties(ctx);
String vhdPath = buildProps.get(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("'" + PATH_BUILD_PROPERTIES
+ "' didn't contain a value for '" + VHD_BUILD_PROPERTY
+ "'.");
return;
}
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.",
PATH_BUILD_PROPERTIES, VHD_BUILD_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
}
private Map<String, String> getBuildProperties(ServletContext ctx) {
Map<String, String> map = new HashMap<>();
try (InputStream stream = ctx
.getResourceAsStream(PATH_BUILD_PROPERTIES)) {
if (stream == null) {
log.debug("Didn't find a resource at '" + PATH_BUILD_PROPERTIES
+ "'.");
} else {
Properties props = new Properties();
props.load(stream);
for (String key : props.stringPropertyNames()) {
map.put(key, props.getProperty(key));
}
}
} catch (IOException e) {
throw new SetupException("Failed to load from '"
+ PATH_BUILD_PROPERTIES + "'.", e);
}
return map;
}
private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) { private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) {
File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES); File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES);
@ -270,13 +122,4 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
// No need to remove the bean. It's only a map of strings, and if we // No need to remove the bean. It's only a map of strings, and if we
// restart the app, it will be replaced. // restart the app, it will be replaced.
} }
/**
* Indicates a problem setting up. Abandon ship.
*/
private static class SetupException extends RuntimeException {
public SetupException(String message, Throwable cause) {
super(message, cause);
}
}
} }

View file

@ -25,7 +25,6 @@ public class ConfigurationPropertiesSmokeTests implements
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSmokeTests.class); .getLog(ConfigurationPropertiesSmokeTests.class);
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home";
private static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; private static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace";
private static final String PROPERTY_LANGUAGE_BUILD = "languages.addToBuild"; private static final String PROPERTY_LANGUAGE_BUILD = "languages.addToBuild";
private static final String PROPERTY_LANGUAGE_SELECTABLE = "languages.selectableLocales"; private static final String PROPERTY_LANGUAGE_SELECTABLE = "languages.selectableLocales";
@ -38,47 +37,10 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props = ConfigurationProperties.getBean(ctx); ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
checkHomeDirectory(ctx, props, ss);
checkDefaultNamespace(ctx, props, ss); checkDefaultNamespace(ctx, props, ss);
checkLanguages(props, ss); checkLanguages(props, ss);
} }
/**
* Confirm that: a home directory has been specified; it exists; it is a
* directory; it is readable and writable.
*/
private void checkHomeDirectory(ServletContext ctx,
ConfigurationProperties props, StartupStatus ss) {
String homeDirectoryPath = props.getProperty(PROPERTY_HOME_DIRECTORY);
if (homeDirectoryPath == null || homeDirectoryPath.isEmpty()) {
ss.fatal(this, "Can't find a value for the home directory: '"
+ PROPERTY_HOME_DIRECTORY + "'");
return;
}
File homeDirectory = new File(homeDirectoryPath);
if (!homeDirectory.exists()) {
ss.fatal(this, PROPERTY_HOME_DIRECTORY + " '" + homeDirectoryPath
+ "' does not exist.");
return;
}
if (!homeDirectory.isDirectory()) {
ss.fatal(this, PROPERTY_HOME_DIRECTORY + " '" + homeDirectoryPath
+ "' is not a directory.");
return;
}
if (!homeDirectory.canRead()) {
ss.fatal(this, PROPERTY_HOME_DIRECTORY + " '" + homeDirectoryPath
+ "' cannot be read.");
}
if (!homeDirectory.canWrite()) {
ss.fatal(this, PROPERTY_HOME_DIRECTORY + " '" + homeDirectoryPath
+ "' cannot be written to.");
}
}
/** /**
* Confirm that the default namespace is specified and a syntactically valid * Confirm that the default namespace is specified and a syntactically valid
* URI. It should also end with "/individual/". * URI. It should also end with "/individual/".

View file

@ -25,8 +25,8 @@ import javax.servlet.http.HttpServletRequest;
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.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
@ -50,7 +50,6 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_ERROR = "contactForm-error.ftl"; private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private final static String TEMPLATE_FORM = "contactForm-form.ftl"; private final static String TEMPLATE_FORM = "contactForm-form.ftl";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal"; private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html"; private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html";
@ -116,7 +115,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
try { try {
// Write the message to the journal file // Write the message to the journal file
FileWriter fw = new FileWriter(locateTheJournalFile(vreq),true); FileWriter fw = new FileWriter(locateTheJournalFile(), true);
PrintWriter outFile = new PrintWriter(fw); PrintWriter outFile = new PrintWriter(fw);
writeBackupCopy(outFile, msgText, vreq); writeBackupCopy(outFile, msgText, vreq);
@ -159,21 +158,8 @@ public class ContactMailController extends FreemarkerHttpServlet {
* The journal file belongs in a sub-directory of the Vitro home directory. * The journal file belongs in a sub-directory of the Vitro home directory.
* If the sub-directory doesn't exist, create it. * If the sub-directory doesn't exist, create it.
*/ */
private File locateTheJournalFile(VitroRequest vreq) { private File locateTheJournalFile() {
String homeDirPath = ConfigurationProperties.getBean(vreq).getProperty( File homeDir = ApplicationUtils.instance().getHomeDirectory().getPath().toFile();
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 journalDir = new File(homeDir, EMAIL_JOURNAL_FILE_DIR); File journalDir = new File(homeDir, EMAIL_JOURNAL_FILE_DIR);
if (!journalDir.exists()) { if (!journalDir.exists()) {
boolean created = journalDir.mkdir(); boolean created = journalDir.mkdir();

View file

@ -11,6 +11,7 @@ import java.util.Collections;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
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.ComponentStartupStatus;
@ -22,7 +23,6 @@ import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
*/ */
public class FileStorageImplWrapper implements FileStorage { public class FileStorageImplWrapper implements FileStorage {
public static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; 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"; public static final String FILE_STORAGE_SUBDIRECTORY = "uploads";
private FileStorageImpl fs; private FileStorageImpl fs;
@ -35,7 +35,7 @@ public class FileStorageImplWrapper implements FileStorage {
ServletContext ctx = application.getServletContext(); ServletContext ctx = application.getServletContext();
try { try {
File baseDirectory = figureBaseDir(ctx); File baseDirectory = figureBaseDir();
Collection<String> fileNamespace = confirmDefaultNamespace(ctx); Collection<String> fileNamespace = confirmDefaultNamespace(ctx);
fs = new FileStorageImpl(baseDirectory, fileNamespace); fs = new FileStorageImpl(baseDirectory, fileNamespace);
} catch (Exception e) { } catch (Exception e) {
@ -47,21 +47,8 @@ public class FileStorageImplWrapper implements FileStorage {
* Get the configuration property for the file storage base directory, and * Get the configuration property for the file storage base directory, and
* check that it points to an existing, writeable directory. * check that it points to an existing, writeable directory.
*/ */
private File figureBaseDir(ServletContext ctx) throws IOException { private File figureBaseDir() throws IOException {
String homeDirPath = ConfigurationProperties.getBean(ctx).getProperty( File homeDir = ApplicationUtils.instance().getHomeDirectory().getPath().toFile();
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); File baseDir = new File(homeDir, FILE_STORAGE_SUBDIRECTORY);
if (!baseDir.exists()) { if (!baseDir.exists()) {
boolean created = baseDir.mkdir(); boolean created = baseDir.mkdir();

View file

@ -4,9 +4,12 @@ package edu.cornell.mannlib.vitro.webapp.modules;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.application.VitroHomeDirectory;
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage; 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.modules.tripleSource.ConfigurationTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
/** /**
* The interface that holds the modules and extensions together. * The interface that holds the modules and extensions together.
@ -14,12 +17,20 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
public interface Application { public interface Application {
ServletContext getServletContext(); ServletContext getServletContext();
VitroHomeDirectory getHomeDirectory();
SearchEngine getSearchEngine(); SearchEngine getSearchEngine();
ImageProcessor getImageProcessor(); ImageProcessor getImageProcessor();
FileStorage getFileStorage(); FileStorage getFileStorage();
ContentTripleSource getContentTripleSource();
ConfigurationTripleSource getConfigurationTripleSource();
void shutdown();
public interface Component { public interface Component {
enum LifecycleState { enum LifecycleState {
NEW, ACTIVE, STOPPED NEW, ACTIVE, STOPPED

View file

@ -18,6 +18,8 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineExcepti
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation;
/** /**
* Manages the life-cycle of the SearchEngine. Adds logging, controlled by * Manages the life-cycle of the SearchEngine. Adds logging, controlled by
@ -27,17 +29,30 @@ public class InstrumentedSearchEngineWrapper implements SearchEngine {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(InstrumentedSearchEngineWrapper.class); .getLog(InstrumentedSearchEngineWrapper.class);
private final SearchEngine innerEngine; private SearchEngine innerEngine;
private volatile LifecycleState lifecycleState = NEW; private volatile LifecycleState lifecycleState = NEW;
public InstrumentedSearchEngineWrapper(SearchEngine innerEngine) { @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#wraps")
public void setInnerEngine(SearchEngine inner) {
if (innerEngine == null) { if (innerEngine == null) {
throw new NullPointerException("innerEngine may not be null."); innerEngine = inner;
} else {
throw new IllegalStateException(
"Configuration includes multiple SearchEngine instancess: "
+ innerEngine + ", and " + inner);
} }
this.innerEngine = innerEngine;
} }
@Validation
public void validate() throws Exception {
if (innerEngine == null) {
throw new IllegalStateException(
"Configuration did not include a wrapped SearchEngine.");
}
}
/** /**
* Complain unless ACTIVE. * Complain unless ACTIVE.
*/ */

View file

@ -52,13 +52,12 @@ public class ConfigurationModelsSetup implements ServletContextListener {
private void loadFirstTimeFiles(ServletContext ctx, String modelPath, private void loadFirstTimeFiles(ServletContext ctx, String modelPath,
OntModel baseModel) { OntModel baseModel) {
RDFFilesLoader.loadFirstTimeFiles(ctx, modelPath, baseModel, RDFFilesLoader.loadFirstTimeFiles(modelPath, baseModel, baseModel.isEmpty());
baseModel.isEmpty());
} }
private void loadEveryTimeFiles(ServletContext ctx, String modelPath, private void loadEveryTimeFiles(ServletContext ctx, String modelPath,
OntModel memoryModel) { OntModel memoryModel) {
RDFFilesLoader.loadEveryTimeFiles(ctx, modelPath, memoryModel); RDFFilesLoader.loadEveryTimeFiles(modelPath, memoryModel);
} }
@Override @Override

View file

@ -62,13 +62,13 @@ public class ContentModelSetup extends JenaDataSourceSetupBase
if (isFirstStartup()) { if (isFirstStartup()) {
initializeApplicationMetadata(ctx, applicationMetadataModel); initializeApplicationMetadata(ctx, applicationMetadataModel);
RDFFilesLoader.loadFirstTimeFiles(ctx, "abox", baseABoxModel, true); RDFFilesLoader.loadFirstTimeFiles("abox", baseABoxModel, true);
RDFFilesLoader.loadFirstTimeFiles(ctx, "tbox", baseTBoxModel, true); RDFFilesLoader.loadFirstTimeFiles("tbox", baseTBoxModel, true);
} else { } else {
checkForNamespaceMismatch( applicationMetadataModel, ctx ); checkForNamespaceMismatch( applicationMetadataModel, ctx );
} }
RDFFilesLoader.loadEveryTimeFiles(ctx, "abox", baseABoxModel); RDFFilesLoader.loadEveryTimeFiles("abox", baseABoxModel);
RDFFilesLoader.loadEveryTimeFiles(ctx, "tbox", baseTBoxModel); RDFFilesLoader.loadEveryTimeFiles("tbox", baseTBoxModel);
log.info("Setting up DAO factories"); log.info("Setting up DAO factories");
} }
@ -89,7 +89,7 @@ public class ContentModelSetup extends JenaDataSourceSetupBase
private void initializeApplicationMetadata(ServletContext ctx, private void initializeApplicationMetadata(ServletContext ctx,
Model applicationMetadataModel) { Model applicationMetadataModel) {
OntModel temporaryAMModel = VitroModelFactory.createOntologyModel(); OntModel temporaryAMModel = VitroModelFactory.createOntologyModel();
RDFFilesLoader.loadFirstTimeFiles(ctx, "applicationMetadata", temporaryAMModel, true); RDFFilesLoader.loadFirstTimeFiles("applicationMetadata", temporaryAMModel, true);
setPortalUriOnFirstTime(temporaryAMModel, ctx); setPortalUriOnFirstTime(temporaryAMModel, ctx);
applicationMetadataModel.add(temporaryAMModel); applicationMetadataModel.add(temporaryAMModel);
} }

View file

@ -33,6 +33,7 @@ import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ModelMaker;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.jena.BlankNodeFilteringModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.BlankNodeFilteringModelMaker;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
@ -49,7 +50,6 @@ public class FileGraphSetup implements ServletContextListener {
private static final String ABOX = "abox"; private static final String ABOX = "abox";
private static final String TBOX = "tbox"; private static final String TBOX = "tbox";
private static final String FILEGRAPH = "filegraph"; private static final String FILEGRAPH = "filegraph";
private static final String PROPERTY_VITRO_HOME = "vitro.home";
public static final String FILEGRAPH_URI_ROOT = "http://vitro.mannlib.cornell.edu/filegraph/"; public static final String FILEGRAPH_URI_ROOT = "http://vitro.mannlib.cornell.edu/filegraph/";
@ -119,7 +119,7 @@ public class FileGraphSetup implements ServletContextListener {
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
ConfigurationProperties props = ConfigurationProperties.getBean(ctx); ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
String homeDirProperty = props.getProperty(PROPERTY_VITRO_HOME); String homeDirProperty = ApplicationUtils.instance().getHomeDirectory().getPath().toString();
Path filegraphDir = Paths.get(homeDirProperty, strings); Path filegraphDir = Paths.get(homeDirProperty, strings);
Set<Path> paths = new TreeSet<>(); Set<Path> paths = new TreeSet<>();

View file

@ -13,8 +13,6 @@ import java.nio.file.Paths;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -23,7 +21,7 @@ import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
/** /**
* Help to load RDF files on first time and on every startup. * Help to load RDF files on first time and on every startup.
@ -31,7 +29,6 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
public class RDFFilesLoader { public class RDFFilesLoader {
private static final Log log = LogFactory.getLog(RDFFilesLoader.class); private static final Log log = LogFactory.getLog(RDFFilesLoader.class);
private static final String PROPERTY_VITRO_HOME = "vitro.home";
private static final String DEFAULT_RDF_FORMAT = "RDF/XML"; private static final String DEFAULT_RDF_FORMAT = "RDF/XML";
private static final String RDF = "rdf"; private static final String RDF = "rdf";
private static final String FIRST_TIME = "firsttime"; private static final String FIRST_TIME = "firsttime";
@ -61,10 +58,10 @@ public class RDFFilesLoader {
* *
* The files from the directory are added to the model. * The files from the directory are added to the model.
*/ */
public static void loadFirstTimeFiles(ServletContext ctx, String modelPath, public static void loadFirstTimeFiles(String modelPath, Model model,
Model model, boolean firstTime) { boolean firstTime) {
if (firstTime) { if (firstTime) {
Set<Path> paths = getPaths(locateHomeDirectory(ctx), RDF, Set<Path> paths = getPaths(locateHomeDirectory(), RDF,
modelPath, FIRST_TIME); modelPath, FIRST_TIME);
for (Path p : paths) { for (Path p : paths) {
readOntologyFileIntoModel(p, model); readOntologyFileIntoModel(p, model);
@ -83,11 +80,10 @@ public class RDFFilesLoader {
* *
* The files from the directory become a sub-model of the model. * The files from the directory become a sub-model of the model.
*/ */
public static void loadEveryTimeFiles(ServletContext ctx, String modelPath, public static void loadEveryTimeFiles(String modelPath, OntModel model) {
OntModel model) {
OntModel everytimeModel = ModelFactory OntModel everytimeModel = ModelFactory
.createOntologyModel(OntModelSpec.OWL_MEM); .createOntologyModel(OntModelSpec.OWL_MEM);
String home = locateHomeDirectory(ctx); String home = locateHomeDirectory();
Set<Path> paths = getPaths(home, RDF, modelPath, EVERY_TIME); Set<Path> paths = getPaths(home, RDF, modelPath, EVERY_TIME);
for (Path p : paths) { for (Path p : paths) {
log.info("Loading " + relativePath(p, home)); log.info("Loading " + relativePath(p, home));
@ -177,9 +173,9 @@ public class RDFFilesLoader {
return DEFAULT_RDF_FORMAT; return DEFAULT_RDF_FORMAT;
} }
private static String locateHomeDirectory(ServletContext ctx) { private static String locateHomeDirectory() {
return ConfigurationProperties.getBean(ctx).getProperty( return ApplicationUtils.instance().getHomeDirectory().getPath()
PROPERTY_VITRO_HOME); .toString();
} }
/** /**

View file

@ -13,7 +13,6 @@ import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -44,6 +43,7 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
@ -98,7 +98,7 @@ public class UpdateKnowledgeBase implements ServletContextListener {
settings.setUnionOntModelSelector(ModelAccess.on(ctx).getOntModelSelector()); settings.setUnionOntModelSelector(ModelAccess.on(ctx).getOntModelSelector());
ConfigurationProperties props = ConfigurationProperties.getBean(ctx); ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
Path homeDir = Paths.get(props.getProperty("vitro.home")); Path homeDir = ApplicationUtils.instance().getHomeDirectory().getPath();
settings.setDisplayModel(ModelAccess.on(ctx).getOntModel(DISPLAY)); settings.setDisplayModel(ModelAccess.on(ctx).getOntModel(DISPLAY));
OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR));
settings.setOldTBoxModel(oldTBoxModel); settings.setOldTBoxModel(oldTBoxModel);
@ -202,8 +202,7 @@ public class UpdateKnowledgeBase implements ServletContextListener {
* Put the paths for the directories and files into the settings object. * Put the paths for the directories and files into the settings object.
*/ */
private void putReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) throws IOException { private void putReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) throws IOException {
ConfigurationProperties props = ConfigurationProperties.getBean(ctx); Path homeDir = ApplicationUtils.instance().getHomeDirectory().getPath();
Path homeDir = Paths.get(props.getProperty("vitro.home"));
Path dataDir = createDirectory(homeDir, "upgrade", "knowledgeBase"); Path dataDir = createDirectory(homeDir, "upgrade", "knowledgeBase");
settings.setDataDir(dataDir.toString()); settings.setDataDir(dataDir.toString());

View file

@ -1,113 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup;
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION;
import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.ContentDataStructuresProviderSPARQL.PROPERTY_SPARQL_ENDPOINT_URI;
import static edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ContentDataStructuresProviderTDB.PROPERTY_CONTENT_TDB_PATH;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntDocumentManager;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.BasicDataStructuresProvider;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ConfigurationDataStructuresProvider;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.ContentDataStructuresProvider;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sdb.ContentDataStructuresProviderSDB;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.sparql.ContentDataStructuresProviderSPARQL;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ConfigurationDataStructuresProviderTDB;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.rdfsetup.impl.tdb.ContentDataStructuresProviderTDB;
/**
* Create the RDFServiceFactories and ModelMakers for the application to use.
*/
public class RDFSetup implements ServletContextListener {
private static final Log log = LogFactory.getLog(RDFSetup.class);
private ServletContext ctx;
private ConfigurationProperties configProps;
private ContentDataStructuresProvider contentProvider;
private ConfigurationDataStructuresProvider configurationProvider;
private BasicDataStructuresProvider provider;
@Override
public void contextInitialized(ServletContextEvent sce) {
this.ctx = sce.getServletContext();
this.configProps = ConfigurationProperties.getBean(ctx);
configureJena();
createProviders();
RDFServiceUtils.setRDFServiceFactory(ctx,
contentProvider.getRDFServiceFactory());
RDFServiceUtils.setRDFServiceFactory(ctx,
configurationProvider.getRDFServiceFactory(), CONFIGURATION);
ModelAccess.setDataStructuresProvider(provider);
}
private void configureJena() {
// we do not want to fetch imports when we wrap Models in OntModels
OntDocumentManager.getInstance().setProcessImports(false);
}
/**
* For now, these steps are hard-coded. They should be driven by a
* configuration file.
*/
private void createProviders() {
if (isSparqlEndpointContentConfigured()) {
contentProvider = new ContentDataStructuresProviderSPARQL(ctx, this);
} else if (isTdbConfigured()) {
contentProvider = new ContentDataStructuresProviderTDB(ctx, this);
} else {
contentProvider = new ContentDataStructuresProviderSDB(ctx, this);
}
configurationProvider = new ConfigurationDataStructuresProviderTDB(ctx,
this);
provider = new BasicDataStructuresProvider(contentProvider,
configurationProvider);
}
private boolean isSparqlEndpointContentConfigured() {
return StringUtils.isNotBlank(configProps
.getProperty(PROPERTY_SPARQL_ENDPOINT_URI));
}
private boolean isTdbConfigured() {
return StringUtils.isNotBlank(configProps
.getProperty(PROPERTY_CONTENT_TDB_PATH));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (contentProvider != null) {
try {
contentProvider.close();
} catch (Exception e) {
log.error("Problem when closing content provider", e);
}
}
if (configurationProvider != null) {
try {
configurationProvider.close();
} catch (Exception e) {
log.error("Problem when closing configuration provider", e);
}
}
}
}

View file

@ -5,7 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.utils.developer;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.nio.file.Paths; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
@ -20,7 +20,7 @@ import javax.servlet.ServletContextListener;
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.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/** /**
@ -194,12 +194,10 @@ public class DeveloperSettings {
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext(); ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
ConfigurationProperties props = ConfigurationProperties
.getBean(ctx);
DeveloperSettings devSettings = DeveloperSettings.getInstance(); DeveloperSettings devSettings = DeveloperSettings.getInstance();
String home = props.getProperty("vitro.home"); Path homeDir = ApplicationUtils.instance().getHomeDirectory().getPath();
File dsFile = Paths.get(home, "developer.properties").toFile(); File dsFile = homeDir.resolve("developer.properties").toFile();
try (FileReader reader = new FileReader(dsFile)) { try (FileReader reader = new FileReader(dsFile)) {
Properties dsProps = new Properties(); Properties dsProps = new Properties();

View file

@ -124,8 +124,9 @@ public class StackTraceUtility {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (requested) { if (requested) {
for (StackTraceElement ste : stackTrace) { for (StackTraceElement ste : stackTrace) {
sb.append(String.format(" line %4d, %s \n", sb.append(String.format(" %s.%s(%s:%d) \n",
ste.getLineNumber(), ste.getClassName())); ste.getClassName(), ste.getMethodName(),
ste.getFileName(), ste.getLineNumber()));
} }
sb.append(" ...\n"); sb.append(" ...\n");
} }

View file

@ -7,10 +7,13 @@ import java.lang.reflect.Field;
import javax.servlet.ServletContext; 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.application.VitroHomeDirectory;
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.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.modules.tripleSource.ConfigurationTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
/** /**
* TODO * TODO
@ -61,6 +64,12 @@ public class ApplicationStub implements Application {
// Un-implemented methods // Un-implemented methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Override
public VitroHomeDirectory getHomeDirectory() {
throw new RuntimeException(
"ApplicationStub.getHomeDirectory() not implemented.");
}
@Override @Override
public ImageProcessor getImageProcessor() { public ImageProcessor getImageProcessor() {
throw new RuntimeException( throw new RuntimeException(
@ -74,4 +83,22 @@ public class ApplicationStub implements Application {
"ApplicationStub.getFileStorage() not implemented."); "ApplicationStub.getFileStorage() not implemented.");
} }
@Override
public void shutdown() {
throw new RuntimeException(
"ApplicationStub.shutdown() not implemented.");
}
@Override
public ContentTripleSource getContentTripleSource() {
throw new RuntimeException(
"ApplicationStub.getContentTripleSource() not implemented.");
}
@Override
public ConfigurationTripleSource getConfigurationTripleSource() {
throw new RuntimeException(
"ApplicationStub.getConfigurationTripleSource() not implemented.");
}
} }

View file

@ -7,6 +7,8 @@
edu.cornell.mannlib.vitro.webapp.servlet.setup.JvmSmokeTests edu.cornell.mannlib.vitro.webapp.servlet.setup.JvmSmokeTests
edu.cornell.mannlib.vitro.webapp.application.ApplicationSetup
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
@ -16,15 +18,12 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.GuardAgainstUnmigratedRDB
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$Setup edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$ComponentsSetup
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
# In 1.8, this should replace JenaPersistentDataSourceSetup, RDFServiceSetup, and maybe more.
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