Make DeveloperSettings a singleton, and other improvements.
By making it a singleton, we do need an explicit Setup operation. However, it means that we can refer to the settings in client code that doesn’t have access to a request or to the ServletContext. Other refactorings to simplify the logic or make it more scalable.
This commit is contained in:
parent
f6bd5804d5
commit
245763e9e7
20 changed files with 387 additions and 421 deletions
|
@ -77,7 +77,7 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
|||
}
|
||||
|
||||
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.ENABLE_DEVELOPER_PANEL.ACTIONS)) {
|
||||
urls.put("activateDeveloperPanel", "javascript:new DeveloperPanel(developerAjaxUrl).setupDeveloperPanel({developerEnabled: true});");
|
||||
urls.put("activateDeveloperPanel", "javascript:new DeveloperPanel(developerAjaxUrl).setupDeveloperPanel({developer_enabled: true});");
|
||||
}
|
||||
|
||||
return urls;
|
||||
|
|
|
@ -26,7 +26,7 @@ import edu.cornell.mannlib.vitro.webapp.freemarker.loader.FreemarkerTemplateLoad
|
|||
import edu.cornell.mannlib.vitro.webapp.i18n.freemarker.I18nMethodModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.directives.IndividualShortViewDirective;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective;
|
||||
|
@ -70,7 +70,7 @@ public abstract class FreemarkerConfiguration {
|
|||
confirmInstanceIsSet();
|
||||
|
||||
synchronized (instance) {
|
||||
clearTemplateCacheIfRequested(req);
|
||||
clearTemplateCacheIfRequested();
|
||||
keepTemplateLoaderCurrentWithThemeDirectory(req);
|
||||
setThreadLocalsForRequest(req);
|
||||
return instance;
|
||||
|
@ -84,21 +84,14 @@ public abstract class FreemarkerConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private static void clearTemplateCacheIfRequested(HttpServletRequest req) {
|
||||
if (isTemplateCacheInvalid(req)) {
|
||||
/** If the developer doesn't want the cache, clear it every time. */
|
||||
private static void clearTemplateCacheIfRequested() {
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
if (settings.getBoolean(Key.DEFEAT_FREEMARKER_CACHE)) {
|
||||
instance.clearTemplateCache();
|
||||
}
|
||||
}
|
||||
|
||||
/** If the developer doesn't want the cache, it's invalid. */
|
||||
private static boolean isTemplateCacheInvalid(HttpServletRequest req) {
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(req);
|
||||
if (settings.getBoolean(Keys.DEFEAT_FREEMARKER_CACHE)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of the theme directory. If it changes, create an appropriate
|
||||
* new TemplateLoader.
|
||||
|
@ -110,7 +103,7 @@ public abstract class FreemarkerConfiguration {
|
|||
HttpServletRequest req) {
|
||||
String themeDir = getThemeDirectory(req);
|
||||
if (hasThemeDirectoryChanged(themeDir)
|
||||
|| haveDeveloperSettingsChanged(req)) {
|
||||
|| haveDeveloperSettingsChanged()) {
|
||||
TemplateLoader tl = createTemplateLoader(req, themeDir);
|
||||
instance.setTemplateLoader(tl);
|
||||
}
|
||||
|
@ -131,9 +124,9 @@ public abstract class FreemarkerConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean haveDeveloperSettingsChanged(HttpServletRequest req) {
|
||||
Map<String, Object> settingsMap = DeveloperSettings.getBean(req)
|
||||
.getSettingsMap();
|
||||
private static boolean haveDeveloperSettingsChanged() {
|
||||
Map<String, Object> settingsMap = DeveloperSettings.getInstance()
|
||||
.getRawSettingsMap();
|
||||
if (settingsMap.equals(previousSettingsMap)) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -167,8 +160,8 @@ public abstract class FreemarkerConfiguration {
|
|||
TemplateLoader tl = new MultiTemplateLoader(loaderArray);
|
||||
|
||||
// If requested, add delimiters to the templates.
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(req);
|
||||
if (settings.getBoolean(Keys.INSERT_FREEMARKER_DELIMITERS)) {
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
if (settings.getBoolean(Key.INSERT_FREEMARKER_DELIMITERS)) {
|
||||
tl = new DelimitingTemplateLoader(tl);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
|
||||
/**
|
||||
* Provides access to a bundle of text strings, based on the name of the bundle,
|
||||
|
@ -108,7 +108,7 @@ public class I18n {
|
|||
protected I18nBundle getBundle(String bundleName, HttpServletRequest req) {
|
||||
log.debug("Getting bundle '" + bundleName + "'");
|
||||
|
||||
I18nLogger i18nLogger = new I18nLogger(req);
|
||||
I18nLogger i18nLogger = new I18nLogger();
|
||||
try {
|
||||
checkDevelopmentMode(req);
|
||||
checkForChangeInThemeDirectory(req);
|
||||
|
@ -133,7 +133,7 @@ public class I18n {
|
|||
* If we are in development mode, clear the cache on each request.
|
||||
*/
|
||||
private void checkDevelopmentMode(HttpServletRequest req) {
|
||||
if (DeveloperSettings.getBean(req).getBoolean(Keys.I18N_DEFEAT_CACHE)) {
|
||||
if (DeveloperSettings.getInstance().getBoolean(Key.I18N_DEFEAT_CACHE)) {
|
||||
log.debug("In development mode - clearing the cache.");
|
||||
clearCacheOnRequest(req);
|
||||
}
|
||||
|
|
|
@ -4,13 +4,11 @@ package edu.cornell.mannlib.vitro.webapp.i18n;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
|
||||
/**
|
||||
* If enabled in developer mode, write a message to the log each time someone
|
||||
|
@ -23,10 +21,9 @@ public class I18nLogger {
|
|||
|
||||
private final boolean isLogging;
|
||||
|
||||
public I18nLogger(HttpServletRequest req) {
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(req);
|
||||
this.isLogging = settings.getBoolean(Keys.ENABLED)
|
||||
&& settings.getBoolean(Keys.I18N_LOG_STRINGS)
|
||||
public I18nLogger() {
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
this.isLogging = settings.getBoolean(Key.I18N_LOG_STRINGS)
|
||||
&& log.isInfoEnabled();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public class RDFServiceUtils {
|
|||
* Every factory is wrapped in a logger, so we can dynamically
|
||||
* enable or disable logging.
|
||||
*/
|
||||
return new LoggingRDFServiceFactory(context, factory);
|
||||
return new LoggingRDFServiceFactory(factory);
|
||||
} else {
|
||||
log.error("Expecting an RDFServiceFactory on the context, but found " + o);
|
||||
return null;
|
||||
|
|
|
@ -5,8 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
|
|||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
|
@ -19,11 +17,9 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
|||
* For the other methods, it just delegates to the inner RDFService.
|
||||
*/
|
||||
public class LoggingRDFService implements RDFService {
|
||||
private final ServletContext ctx;
|
||||
private final RDFService innerService;
|
||||
|
||||
LoggingRDFService(ServletContext ctx, RDFService innerService) {
|
||||
this.ctx = ctx;
|
||||
LoggingRDFService(RDFService innerService) {
|
||||
this.innerService = innerService;
|
||||
}
|
||||
|
||||
|
@ -34,7 +30,7 @@ public class LoggingRDFService implements RDFService {
|
|||
@Override
|
||||
public boolean changeSetUpdate(ChangeSet changeSet)
|
||||
throws RDFServiceException {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, changeSet)) {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(changeSet)) {
|
||||
return innerService.changeSetUpdate(changeSet);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +38,7 @@ public class LoggingRDFService implements RDFService {
|
|||
@Override
|
||||
public InputStream sparqlConstructQuery(String query,
|
||||
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||
return innerService.sparqlConstructQuery(query, resultFormat);
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +46,7 @@ public class LoggingRDFService implements RDFService {
|
|||
@Override
|
||||
public InputStream sparqlDescribeQuery(String query,
|
||||
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||
return innerService.sparqlDescribeQuery(query, resultFormat);
|
||||
}
|
||||
}
|
||||
|
@ -58,14 +54,14 @@ public class LoggingRDFService implements RDFService {
|
|||
@Override
|
||||
public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat)
|
||||
throws RDFServiceException {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||
return innerService.sparqlSelectQuery(query, resultFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sparqlAskQuery(String query) throws RDFServiceException {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, query)) {
|
||||
try (RDFServiceLogger l = new RDFServiceLogger(query)) {
|
||||
return innerService.sparqlAskQuery(query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||
|
@ -14,23 +12,20 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
|||
* wrapped in a LoggingRDFService.
|
||||
*/
|
||||
public class LoggingRDFServiceFactory implements RDFServiceFactory {
|
||||
private final ServletContext ctx;
|
||||
private final RDFServiceFactory factory;
|
||||
|
||||
public LoggingRDFServiceFactory(ServletContext ctx,
|
||||
RDFServiceFactory factory) {
|
||||
this.ctx = ctx;
|
||||
public LoggingRDFServiceFactory(RDFServiceFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RDFService getRDFService() {
|
||||
return new LoggingRDFService(ctx, factory.getRDFService());
|
||||
return new LoggingRDFService(factory.getRDFService());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RDFService getShortTermRDFService() {
|
||||
return new LoggingRDFService(ctx, factory.getShortTermRDFService());
|
||||
return new LoggingRDFService(factory.getShortTermRDFService());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,14 +9,12 @@ import java.util.List;
|
|||
import java.util.ListIterator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
|
||||
/**
|
||||
* Writes the log message for the LoggingRDFService.
|
||||
|
@ -45,7 +43,6 @@ import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
|||
public class RDFServiceLogger implements AutoCloseable {
|
||||
private static final Log log = LogFactory.getLog(RDFServiceLogger.class);
|
||||
|
||||
private final ServletContext ctx;
|
||||
private final Object[] args;
|
||||
|
||||
private boolean isEnabled;
|
||||
|
@ -58,31 +55,33 @@ public class RDFServiceLogger implements AutoCloseable {
|
|||
|
||||
private long startTime;
|
||||
|
||||
public RDFServiceLogger(ServletContext ctx, Object... args) {
|
||||
this.ctx = ctx;
|
||||
public RDFServiceLogger(Object... args) {
|
||||
this.args = args;
|
||||
|
||||
try {
|
||||
getProperties();
|
||||
|
||||
if (isEnabled && log.isInfoEnabled()) {
|
||||
loadStackTrace();
|
||||
if (passesQueryRestriction() && passesStackRestriction()) {
|
||||
this.startTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to create instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void getProperties() {
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(ctx);
|
||||
isEnabled = settings.getBoolean(Keys.LOGGING_RDF_ENABLE);
|
||||
traceRequested = settings.getBoolean(Keys.LOGGING_RDF_STACK_TRACE);
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
isEnabled = settings.getBoolean(Key.LOGGING_RDF_ENABLE);
|
||||
traceRequested = settings.getBoolean(Key.LOGGING_RDF_STACK_TRACE);
|
||||
queryStringRestriction = patternFromSettings(settings,
|
||||
Keys.LOGGING_RDF_QUERY_RESTRICTION);
|
||||
Key.LOGGING_RDF_QUERY_RESTRICTION);
|
||||
callStackRestriction = patternFromSettings(settings,
|
||||
Keys.LOGGING_RDF_STACK_RESTRICTION);
|
||||
Key.LOGGING_RDF_STACK_RESTRICTION);
|
||||
}
|
||||
|
||||
private Pattern patternFromSettings(DeveloperSettings settings, Keys key) {
|
||||
private Pattern patternFromSettings(DeveloperSettings settings, Key key) {
|
||||
String patternString = settings.getString(key);
|
||||
if (StringUtils.isBlank(patternString)) {
|
||||
return null;
|
||||
|
@ -160,13 +159,13 @@ public class RDFServiceLogger implements AutoCloseable {
|
|||
}
|
||||
|
||||
private String assembleQueryString() {
|
||||
StringBuilder query = new StringBuilder();
|
||||
List<String> stringArgs = new ArrayList<>();
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof String) {
|
||||
query.append((String) arg).append(" ");
|
||||
stringArgs.add((String) arg);
|
||||
}
|
||||
}
|
||||
return query.deleteCharAt(query.length() - 1).toString();
|
||||
return StringUtils.join(stringArgs, " ");
|
||||
}
|
||||
|
||||
private boolean passesStackRestriction() {
|
||||
|
@ -188,6 +187,7 @@ public class RDFServiceLogger implements AutoCloseable {
|
|||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
if (startTime != 0L) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
|
||||
|
@ -199,6 +199,9 @@ public class RDFServiceLogger implements AutoCloseable {
|
|||
log.info(String.format("%8.3f %s %s %s", elapsedSeconds,
|
||||
methodName, cleanArgs, formattedTrace));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to write log record", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStackTrace() {
|
||||
|
|
|
@ -6,10 +6,9 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.services.shortview.FakeApplicationOntologyService.TemplateAndDataGetters;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
|
||||
/**
|
||||
* When we use a short view other than the default, log it.
|
||||
|
@ -17,31 +16,26 @@ import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
|||
public class ShortViewLogger {
|
||||
private static final Log log = LogFactory.getLog(ShortViewLogger.class);
|
||||
|
||||
public static void log(VitroRequest vreq, String contextName,
|
||||
Individual individual, String classUri, TemplateAndDataGetters tdg) {
|
||||
if (isLogging(vreq)) {
|
||||
public static void log(String contextName, Individual individual,
|
||||
String classUri, TemplateAndDataGetters tdg) {
|
||||
if (isLogging()) {
|
||||
log.info("Using custom short view in " + contextName + " because '"
|
||||
+ individual.getURI() + "' (" + individual.getLabel()
|
||||
+ ") has type '" + classUri + "': " + tdg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void log(VitroRequest vreq, String contextName,
|
||||
Individual individual) {
|
||||
if (isLogging(vreq)) {
|
||||
public static void log(String contextName, Individual individual) {
|
||||
if (isLogging()) {
|
||||
log.info("Using default short view in " + contextName + " for '"
|
||||
+ individual.getURI() + "' (" + individual.getLabel() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLogging(VitroRequest vreq) {
|
||||
if (!log.isInfoEnabled()) {
|
||||
return false;
|
||||
}
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
||||
return settings.getBoolean(Keys.ENABLED)
|
||||
&& settings
|
||||
.getBoolean(Keys.PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW);
|
||||
private static boolean isLogging() {
|
||||
return log.isInfoEnabled()
|
||||
&& DeveloperSettings.getInstance().getBoolean(
|
||||
Key.PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -114,13 +114,13 @@ public class ShortViewServiceImpl implements ShortViewService {
|
|||
TemplateAndDataGetters tdg = faker.getShortViewProperties(vreq,
|
||||
individual, classUri, svContext.name());
|
||||
if (tdg != null) {
|
||||
ShortViewLogger.log(vreq, svContext.name(), individual, classUri, tdg);
|
||||
ShortViewLogger.log(svContext.name(), individual, classUri, tdg);
|
||||
return tdg;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find one? Use the default values.
|
||||
ShortViewLogger.log(vreq, svContext.name(), individual);
|
||||
ShortViewLogger.log(svContext.name(), individual);
|
||||
return new TemplateAndDataGetters(svContext.getDefaultTemplateName());
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.utils.developer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
@ -13,251 +14,92 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Hold the global developer settings. Render to JSON when requested.
|
||||
* A singleton holder for the developer settings.
|
||||
*
|
||||
* On first request, the "developer.properties" file is loaded from the Vitro
|
||||
* home directory. If the file doesn't exist, or doesn't contain values for
|
||||
* certain properties, those propertiew will keep their default values.
|
||||
* Start with an empty settings map.
|
||||
*
|
||||
* The Setup class will read "developer.properties" from the Vitro home
|
||||
* directory, and load its settings. If the file doesn't exist, or doesn't
|
||||
* contain values for certain properties, those propertiew will keep their
|
||||
* default values.
|
||||
*
|
||||
* An AJAX request can be used to update the properties. If the request has
|
||||
* multiple values for a property, the first value will be used. If the request
|
||||
* does not contain a value for a property, that property will keep its current
|
||||
* value.
|
||||
*
|
||||
* The property names in "developer.properties" are not suitable as fields in
|
||||
* the HTML panel, because they contain periods. For the HTML panel, we
|
||||
* translate those periods to underscores.
|
||||
*
|
||||
* If the ENABLED flag is not set, then getBinary() will return false for all
|
||||
* keys, and getString() will return the empty string. This simplifies the logic
|
||||
* in the client code. Use getRawSettingsMap() to display the actual values in
|
||||
* the developer panel.
|
||||
*/
|
||||
public class DeveloperSettings {
|
||||
private static final Log log = LogFactory.getLog(DeveloperSettings.class);
|
||||
|
||||
public enum Keys {
|
||||
/**
|
||||
* Developer mode and developer panel is enabled.
|
||||
*/
|
||||
ENABLED("developer.enabled", true),
|
||||
|
||||
/**
|
||||
* Users don't need authority to use the developer panel. But they still
|
||||
* can't enable it without authority.
|
||||
*/
|
||||
PERMIT_ANONYMOUS_CONTROL("developer.permitAnonymousControl", true),
|
||||
|
||||
/**
|
||||
* Load Freemarker templates every time they are requested.
|
||||
*/
|
||||
DEFEAT_FREEMARKER_CACHE("developer.defeatFreemarkerCache", true),
|
||||
|
||||
/**
|
||||
* Show where each Freemarker template starts and stops.
|
||||
*/
|
||||
INSERT_FREEMARKER_DELIMITERS("developer.insertFreemarkerDelimiters",
|
||||
true),
|
||||
|
||||
/**
|
||||
* Load language property files every time they are requested.
|
||||
*/
|
||||
I18N_DEFEAT_CACHE("developer.i18n.defeatCache", true),
|
||||
|
||||
/**
|
||||
* Enable the I18nLogger to log each string request.
|
||||
*/
|
||||
I18N_LOG_STRINGS("developer.i18n.logStringRequests", true),
|
||||
|
||||
/**
|
||||
* Enable the LoggingRDFService
|
||||
*/
|
||||
LOGGING_RDF_ENABLE("developer.loggingRDFService.enable", true),
|
||||
|
||||
/**
|
||||
* When logging with the LoggingRDFService, include a stack trace
|
||||
*/
|
||||
LOGGING_RDF_STACK_TRACE("developer.loggingRDFService.stackTrace", true),
|
||||
|
||||
/**
|
||||
* Don't log with the LoggingRDFService unless the calling stack meets
|
||||
* this restriction.
|
||||
*/
|
||||
LOGGING_RDF_QUERY_RESTRICTION(
|
||||
"developer.loggingRDFService.queryRestriction", false),
|
||||
|
||||
/**
|
||||
* Don't log with the LoggingRDFService unless the calling stack meets
|
||||
* this restriction.
|
||||
*/
|
||||
LOGGING_RDF_STACK_RESTRICTION(
|
||||
"developer.loggingRDFService.stackRestriction", false),
|
||||
|
||||
/**
|
||||
* Tell the CustomListViewLogger to note the use of non-default custom
|
||||
* list views.
|
||||
*/
|
||||
PAGE_CONTENTS_LOG_CUSTOM_LIST_VIEW(
|
||||
"developer.pageContents.logCustomListView", true),
|
||||
|
||||
/**
|
||||
* Tell the ShortViewLogger to note the use of non-default short views.
|
||||
*/
|
||||
PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW(
|
||||
"developer.pageContents.logCustomShortView", true);
|
||||
|
||||
private final String propertyName;
|
||||
private final String elementId;
|
||||
private final boolean bool;
|
||||
|
||||
private Keys(String propertyName, boolean bool) {
|
||||
this.propertyName = propertyName;
|
||||
this.elementId = produceElementId();
|
||||
this.bool = bool;
|
||||
}
|
||||
|
||||
public String propertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public String elementId() {
|
||||
return elementId;
|
||||
}
|
||||
|
||||
boolean isBoolean() {
|
||||
return bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* The element ID is camel-case instead of period-delimited. So
|
||||
* "developer.enabled" becomes "developerEnabled".
|
||||
*/
|
||||
String produceElementId() {
|
||||
StringBuilder id = new StringBuilder(propertyName.length());
|
||||
boolean capitalize = false;
|
||||
for (int i = 0; i < propertyName.length(); i++) {
|
||||
char c = propertyName.charAt(i);
|
||||
if (c == '.') {
|
||||
capitalize = true;
|
||||
} else if (capitalize) {
|
||||
id.append(Character.toUpperCase(c));
|
||||
capitalize = false;
|
||||
} else {
|
||||
id.append(c);
|
||||
}
|
||||
}
|
||||
return id.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
static Keys fromElementId(String id) {
|
||||
for (Keys k : Keys.values()) {
|
||||
if (k.elementId.equals(id)) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
log.error("Can't find key for element id: '" + id + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
static Keys fromPropertyName(String name) {
|
||||
for (Keys k : Keys.values()) {
|
||||
if (k.propertyName.equals(name)) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
log.error("Can't find key for property name: '" + name + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The factory
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
protected static final String ATTRIBUTE_NAME = DeveloperSettings.class
|
||||
.getName();
|
||||
private static final DeveloperSettings instance = new DeveloperSettings();
|
||||
|
||||
public static DeveloperSettings getBean(HttpServletRequest req) {
|
||||
return getBean(req.getSession().getServletContext());
|
||||
}
|
||||
|
||||
public static DeveloperSettings getBean(ServletContext ctx) {
|
||||
Object o = ctx.getAttribute(ATTRIBUTE_NAME);
|
||||
if (o instanceof DeveloperSettings) {
|
||||
return (DeveloperSettings) o;
|
||||
} else {
|
||||
DeveloperSettings ds = new DeveloperSettings(ctx);
|
||||
ctx.setAttribute(ATTRIBUTE_NAME, ds);
|
||||
return ds;
|
||||
}
|
||||
public static DeveloperSettings getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The instance
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final Map<Keys, Object> settings = new EnumMap<>(Keys.class);
|
||||
private final Map<Key, String> settings;
|
||||
|
||||
protected DeveloperSettings(ServletContext ctx) {
|
||||
updateFromFile(ctx);
|
||||
private DeveloperSettings() {
|
||||
this.settings = new EnumMap<>(Key.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the initial settings from "developer.properties" in the Vitro home
|
||||
* directory.
|
||||
*
|
||||
* This method is "protected" so we can override it for unit tests.
|
||||
*/
|
||||
protected void updateFromFile(ServletContext ctx) {
|
||||
Map<Keys, String> fromFile = new HashMap<>();
|
||||
|
||||
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
|
||||
String home = props.getProperty("vitro.home");
|
||||
File dsFile = Paths.get(home, "developer.properties").toFile();
|
||||
|
||||
if (dsFile.isFile()) {
|
||||
try (FileReader reader = new FileReader(dsFile)) {
|
||||
Properties dsProps = new Properties();
|
||||
dsProps.load(reader);
|
||||
for (String key : dsProps.stringPropertyNames()) {
|
||||
fromFile.put(Keys.fromPropertyName(key),
|
||||
dsProps.getProperty(key));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to load 'developer.properties' file.", e);
|
||||
}
|
||||
} else {
|
||||
log.debug("No developer.properties file.");
|
||||
}
|
||||
|
||||
log.debug("Properties from file: " + fromFile);
|
||||
update(fromFile);
|
||||
}
|
||||
|
||||
/** Provide the parameter map from the HttpServletRequest */
|
||||
public void updateFromRequest(Map<String, String[]> parameterMap) {
|
||||
if (log.isDebugEnabled()) {
|
||||
dumpParameterMap(parameterMap);
|
||||
}
|
||||
|
||||
Map<Keys, String> fromRequest = new HashMap<>();
|
||||
Map<Key, String> fromRequest = new HashMap<>();
|
||||
for (String key : parameterMap.keySet()) {
|
||||
fromRequest.put(Keys.fromElementId(key), parameterMap.get(key)[0]);
|
||||
fromRequest.put(Key.fromElementId(key), parameterMap.get(key)[0]);
|
||||
}
|
||||
update(fromRequest);
|
||||
}
|
||||
|
||||
private void update(Map<Keys, String> changedSettings) {
|
||||
for (Keys key : Keys.values()) {
|
||||
public void updateFromProperties(Properties properties) {
|
||||
Map<Key, String> fromFile = new HashMap<>();
|
||||
for (String key : properties.stringPropertyNames()) {
|
||||
fromFile.put(Key.fromPropertyName(key), properties.getProperty(key));
|
||||
}
|
||||
update(fromFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update by known keys, so we will ignore any irrelevant request
|
||||
* parameters, or incorrect properties.
|
||||
*/
|
||||
private void update(Map<Key, String> changedSettings) {
|
||||
for (Key key : Key.values()) {
|
||||
String s = changedSettings.get(key);
|
||||
if (s != null) {
|
||||
if (key.isBoolean()) {
|
||||
settings.put(key, Boolean.valueOf(s));
|
||||
settings.put(key, Boolean.valueOf(s).toString());
|
||||
} else {
|
||||
settings.put(key, s);
|
||||
}
|
||||
|
@ -266,48 +108,68 @@ public class DeveloperSettings {
|
|||
log.debug("DeveloperSettings: " + this);
|
||||
}
|
||||
|
||||
public Object get(Keys key) {
|
||||
if (key.isBoolean()) {
|
||||
return getBoolean(key);
|
||||
} else {
|
||||
return getString(key);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBoolean(Keys key) {
|
||||
/**
|
||||
* If developerMode is enabled, return the boolean value of the stored
|
||||
* setting.
|
||||
*/
|
||||
public boolean getBoolean(Key key) {
|
||||
if (!key.isBoolean()) {
|
||||
throw new IllegalArgumentException("Key '" + key
|
||||
+ "' does not take a boolean value.");
|
||||
}
|
||||
if (settings.containsKey(key)) {
|
||||
if (Boolean.TRUE.equals(settings.get(Keys.ENABLED))) {
|
||||
return (Boolean) settings.get(key);
|
||||
}
|
||||
log.warn("Key '" + key + "' does not take a boolean value.");
|
||||
}
|
||||
if (isDeveloperModeEnabled()) {
|
||||
return Boolean.valueOf(settings.get(key));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(Keys key) {
|
||||
/**
|
||||
* If developerMode is enabled and the setting has a value, return that
|
||||
* value. Otherwise, return the empty string.
|
||||
*/
|
||||
public String getString(Key key) {
|
||||
if (key.isBoolean()) {
|
||||
throw new IllegalArgumentException("Key '" + key
|
||||
+ "' takes a boolean value.");
|
||||
}
|
||||
if (settings.containsKey(key)) {
|
||||
if (Boolean.TRUE.equals(settings.get(Keys.ENABLED))) {
|
||||
return (String) settings.get(key);
|
||||
}
|
||||
log.warn("Key '" + key + "' takes a boolean value.");
|
||||
}
|
||||
String value = settings.get(key);
|
||||
if (value != null && isDeveloperModeEnabled()) {
|
||||
return value;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> getSettingsMap() {
|
||||
private boolean isDeveloperModeEnabled() {
|
||||
return Boolean.valueOf(settings.get(Key.ENABLED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the values of all the settings, by element ID, regardless of whether
|
||||
* developerMode is enabled or not. Boolean settings are represented as
|
||||
* actual Booleans, so Freemarker can perform logical tests on them.
|
||||
*/
|
||||
public Map<String, Object> getRawSettingsMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (Keys key : Keys.values()) {
|
||||
map.put(key.elementId(), get(key));
|
||||
for (Key key : Key.values()) {
|
||||
map.put(key.elementId(), getRawValue(key));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a String or Boolean value, as appropriate for the key. A boolean key
|
||||
* with no value returns false. A non-boolean key with no value returns the
|
||||
* empty string.
|
||||
*/
|
||||
private Object getRawValue(Key key) {
|
||||
String value = settings.get(key);
|
||||
if (key.isBoolean()) {
|
||||
return Boolean.valueOf(value);
|
||||
} else {
|
||||
return (value == null) ? "" : value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeveloperSettings" + settings;
|
||||
|
@ -322,4 +184,42 @@ public class DeveloperSettings {
|
|||
log.debug("Parameter map: " + map);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Setup class
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static class Setup implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
ConfigurationProperties props = ConfigurationProperties
|
||||
.getBean(ctx);
|
||||
DeveloperSettings devSettings = DeveloperSettings.getInstance();
|
||||
|
||||
String home = props.getProperty("vitro.home");
|
||||
File dsFile = Paths.get(home, "developer.properties").toFile();
|
||||
|
||||
try (FileReader reader = new FileReader(dsFile)) {
|
||||
Properties dsProps = new Properties();
|
||||
dsProps.load(reader);
|
||||
devSettings.updateFromProperties(dsProps);
|
||||
ss.info(this, "Loaded the 'developer.properties' file: "
|
||||
+ devSettings);
|
||||
} catch (FileNotFoundException e) {
|
||||
ss.info(this, "'developer.properties' file does not exist.");
|
||||
} catch (Exception e) {
|
||||
ss.warning(this,
|
||||
"Failed to load the 'developer.properties' file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// Nothing to remove.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.developer;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys.PERMIT_ANONYMOUS_CONTROL;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.developer.Key.PERMIT_ANONYMOUS_CONTROL;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -42,7 +42,7 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
|||
@Override
|
||||
protected void doRequest(VitroRequest vreq, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
|
||||
/*
|
||||
* Are they allowed to control the panel?
|
||||
|
@ -70,8 +70,9 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
|||
private Map<String, Object> buildBodyMap(boolean authorized,
|
||||
DeveloperSettings settings) {
|
||||
Map<String, Object> settingsMap = new HashMap<>();
|
||||
settingsMap.putAll(settings.getSettingsMap());
|
||||
settingsMap.putAll(settings.getRawSettingsMap());
|
||||
settingsMap.put("mayControl", authorized);
|
||||
|
||||
Map<String, Object> bodyMap = new HashMap<>();
|
||||
bodyMap.put("settings", settingsMap);
|
||||
return bodyMap;
|
||||
|
@ -84,7 +85,7 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
|||
}
|
||||
|
||||
private boolean isAuthorized(VitroRequest vreq) {
|
||||
boolean authBySetting = DeveloperSettings.getBean(vreq).getBoolean(
|
||||
boolean authBySetting = DeveloperSettings.getInstance().getBoolean(
|
||||
PERMIT_ANONYMOUS_CONTROL);
|
||||
boolean authByPolicy = PolicyHelper.isAuthorizedForActions(vreq,
|
||||
SimplePermission.ENABLE_DEVELOPER_PANEL.ACTION);
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.developer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Keys for the DeveloperSettings. Each key holds these values:
|
||||
*
|
||||
* A property name, which specifies the key in developer.properties, like
|
||||
* "this.thatThing"
|
||||
*
|
||||
* A flag to say whether this key controls a boolean value. If false, then the
|
||||
* value is a string.
|
||||
*
|
||||
* We can derive the element ID for each key by replacing the periods in the
|
||||
* property name with underscores.
|
||||
*/
|
||||
public enum Key {
|
||||
/**
|
||||
* Developer mode and developer panel is enabled.
|
||||
*/
|
||||
ENABLED("developer.enabled", true),
|
||||
|
||||
/**
|
||||
* If the developer panel is enabled, can a non-logged-in user change the
|
||||
* settings?
|
||||
*/
|
||||
PERMIT_ANONYMOUS_CONTROL("developer.permitAnonymousControl", true),
|
||||
|
||||
/**
|
||||
* Load Freemarker templates every time they are requested.
|
||||
*/
|
||||
DEFEAT_FREEMARKER_CACHE("developer.defeatFreemarkerCache", true),
|
||||
|
||||
/**
|
||||
* Show where each Freemarker template starts and stops.
|
||||
*/
|
||||
INSERT_FREEMARKER_DELIMITERS("developer.insertFreemarkerDelimiters", true),
|
||||
|
||||
/**
|
||||
* Load language property files every time they are requested.
|
||||
*/
|
||||
I18N_DEFEAT_CACHE("developer.i18n.defeatCache", true),
|
||||
|
||||
/**
|
||||
* Enable the I18nLogger to log each string request.
|
||||
*/
|
||||
I18N_LOG_STRINGS("developer.i18n.logStringRequests", true),
|
||||
|
||||
/**
|
||||
* Enable the LoggingRDFService
|
||||
*/
|
||||
LOGGING_RDF_ENABLE("developer.loggingRDFService.enable", true),
|
||||
|
||||
/**
|
||||
* When logging with the LoggingRDFService, include a stack trace
|
||||
*/
|
||||
LOGGING_RDF_STACK_TRACE("developer.loggingRDFService.stackTrace", true),
|
||||
|
||||
/**
|
||||
* Don't log with the LoggingRDFService unless the calling stack meets this
|
||||
* restriction.
|
||||
*/
|
||||
LOGGING_RDF_QUERY_RESTRICTION(
|
||||
"developer.loggingRDFService.queryRestriction", false),
|
||||
|
||||
/**
|
||||
* Don't log with the LoggingRDFService unless the calling stack meets this
|
||||
* restriction.
|
||||
*/
|
||||
LOGGING_RDF_STACK_RESTRICTION(
|
||||
"developer.loggingRDFService.stackRestriction", false),
|
||||
|
||||
/**
|
||||
* Tell the CustomListViewLogger to note the use of non-default custom list
|
||||
* views.
|
||||
*/
|
||||
PAGE_CONTENTS_LOG_CUSTOM_LIST_VIEW(
|
||||
"developer.pageContents.logCustomListView", true),
|
||||
|
||||
/**
|
||||
* Tell the ShortViewLogger to note the use of non-default short views.
|
||||
*/
|
||||
PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW(
|
||||
"developer.pageContents.logCustomShortView", true);
|
||||
|
||||
private static final Log log = LogFactory.getLog(Key.class);
|
||||
private final String propertyName;
|
||||
private final boolean bool;
|
||||
|
||||
private Key(String propertyName, boolean bool) {
|
||||
this.propertyName = propertyName;
|
||||
this.bool = bool;
|
||||
}
|
||||
|
||||
public String propertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public String elementId() {
|
||||
return propertyName.replace('.', '_');
|
||||
}
|
||||
|
||||
boolean isBoolean() {
|
||||
return bool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
static Key fromElementId(String id) {
|
||||
return fromPropertyName(id.replace('_', '.'));
|
||||
}
|
||||
|
||||
static Key fromPropertyName(String name) {
|
||||
for (Key k : Key.values()) {
|
||||
if (k.propertyName.equals(name)) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
log.error("Can't find key for property name: '" + name + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,9 +6,8 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||
|
||||
/**
|
||||
* If enabled in the developer settings (and log levels), log every non-default
|
||||
|
@ -18,21 +17,19 @@ public class CustomListViewLogger {
|
|||
private static final Log log = LogFactory
|
||||
.getLog(CustomListViewLogger.class);
|
||||
|
||||
public static void log(VitroRequest vreq, ObjectProperty op,
|
||||
String configFileName) {
|
||||
if (isLogging(vreq)) {
|
||||
public static void log(ObjectProperty op, String configFileName) {
|
||||
if (isLogging()) {
|
||||
log.info("Using list view: '" + configFileName + "' for "
|
||||
+ op.getURI() + " (" + op.getLabel() + ")");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLogging(VitroRequest vreq) {
|
||||
private static boolean isLogging() {
|
||||
if (!log.isInfoEnabled()) {
|
||||
return false;
|
||||
}
|
||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
||||
return settings.getBoolean(Keys.ENABLED)
|
||||
&& settings.getBoolean(Keys.PAGE_CONTENTS_LOG_CUSTOM_LIST_VIEW);
|
||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||
return settings.getBoolean(Key.PAGE_CONTENTS_LOG_CUSTOM_LIST_VIEW);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectProp
|
|||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.ConfigError;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
|
||||
public class PropertyListConfig {
|
||||
private static final Log log = LogFactory.getLog(PropertyListConfig.class);
|
||||
|
@ -62,7 +61,7 @@ public class PropertyListConfig {
|
|||
if (configFileName == null) { // no custom config; use default config
|
||||
configFileName = DEFAULT_CONFIG_FILE_NAME;
|
||||
} else {
|
||||
CustomListViewLogger.log(vreq, op, configFileName);
|
||||
CustomListViewLogger.log(op, configFileName);
|
||||
}
|
||||
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());
|
||||
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.utils.developer;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||
|
||||
/**
|
||||
* Do everything that a standard DeveloperSettings would do, except loading from
|
||||
* a properties file.
|
||||
*
|
||||
* That way, we don't require ConfigurationProperties to find the Vitro home
|
||||
* directory, so we don't throw errors if there is no ConfigurationProperties.
|
||||
*/
|
||||
public class DeveloperSettingsStub extends DeveloperSettings {
|
||||
/**
|
||||
* Factory method. Create the stub and set it into the ServletContext.
|
||||
*/
|
||||
public static void set(ServletContext ctx) {
|
||||
ctx.setAttribute(ATTRIBUTE_NAME, new DeveloperSettingsStub(ctx));
|
||||
}
|
||||
|
||||
protected DeveloperSettingsStub(ServletContext ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFromFile(ServletContext ctx) {
|
||||
// Don't bother.
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,6 @@ import javax.servlet.ServletException;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettingsStub;
|
||||
|
||||
/**
|
||||
* A simple stand-in for the {@link ServletContext}, for use in unit tests.
|
||||
*/
|
||||
|
@ -38,11 +36,6 @@ public class ServletContextStub implements ServletContext {
|
|||
private final Map<String, String> mockResources = new HashMap<String, String>();
|
||||
private final Map<String, String> realPaths = new HashMap<String, String>();
|
||||
|
||||
public ServletContextStub() {
|
||||
// Assume that unit tests won't want to use Developer mode.
|
||||
DeveloperSettingsStub.set(this);
|
||||
}
|
||||
|
||||
public void setContextPath(String contextPath) {
|
||||
if (contextPath == null) {
|
||||
throw new NullPointerException("contextPath may not be null.");
|
||||
|
|
|
@ -11,6 +11,8 @@ edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
||||
|
|
|
@ -34,41 +34,41 @@ function DeveloperPanel(developerAjaxUrl) {
|
|||
document.getElementById("developerPanelSaveButton").onclick = function() {
|
||||
updateDeveloperPanel(collectFormData());
|
||||
}
|
||||
document.getElementById("developerEnabled").onchange = updateDisabledFields
|
||||
document.getElementById("developerLoggingRDFServiceEnable").onchange = updateDisabledFields
|
||||
document.getElementById("developer_enabled").onchange = updateDisabledFields
|
||||
document.getElementById("developer_loggingRDFService_enable").onchange = updateDisabledFields
|
||||
}
|
||||
|
||||
function updateDisabledFields() {
|
||||
var developerEnabled = document.getElementById("developerEnabled").checked;
|
||||
document.getElementById("developerPermitAnonymousControl").disabled = !developerEnabled;
|
||||
document.getElementById("developerDefeatFreemarkerCache").disabled = !developerEnabled;
|
||||
document.getElementById("developerInsertFreemarkerDelimiters").disabled = !developerEnabled;
|
||||
document.getElementById("developerPageContentsLogCustomListView").disabled = !developerEnabled;
|
||||
document.getElementById("developerPageContentsLogCustomShortView").disabled = !developerEnabled;
|
||||
document.getElementById("developerI18nDefeatCache").disabled = !developerEnabled;
|
||||
document.getElementById("developerI18nLogStringRequests").disabled = !developerEnabled;
|
||||
document.getElementById("developerLoggingRDFServiceEnable").disabled = !developerEnabled;
|
||||
var developerEnabled = document.getElementById("developer_enabled").checked;
|
||||
document.getElementById("developer_permitAnonymousControl").disabled = !developerEnabled;
|
||||
document.getElementById("developer_defeatFreemarkerCache").disabled = !developerEnabled;
|
||||
document.getElementById("developer_insertFreemarkerDelimiters").disabled = !developerEnabled;
|
||||
document.getElementById("developer_pageContents_logCustomListView").disabled = !developerEnabled;
|
||||
document.getElementById("developer_pageContents_logCustomShortView").disabled = !developerEnabled;
|
||||
document.getElementById("developer_i18n_defeatCache").disabled = !developerEnabled;
|
||||
document.getElementById("developer_i18n_logStringRequests").disabled = !developerEnabled;
|
||||
document.getElementById("developer_loggingRDFService_enable").disabled = !developerEnabled;
|
||||
|
||||
var rdfServiceEnabled = developerEnabled && document.getElementById("developerLoggingRDFServiceEnable").checked;
|
||||
document.getElementById("developerLoggingRDFServiceStackTrace").disabled = !rdfServiceEnabled;
|
||||
document.getElementById("developerLoggingRDFServiceQueryRestriction").disabled = !rdfServiceEnabled;
|
||||
document.getElementById("developerLoggingRDFServiceStackRestriction").disabled = !rdfServiceEnabled;
|
||||
var rdfServiceEnabled = developerEnabled && document.getElementById("developer_loggingRDFService_enable").checked;
|
||||
document.getElementById("developer_loggingRDFService_stackTrace").disabled = !rdfServiceEnabled;
|
||||
document.getElementById("developer_loggingRDFService_queryRestriction").disabled = !rdfServiceEnabled;
|
||||
document.getElementById("developer_loggingRDFService_stackRestriction").disabled = !rdfServiceEnabled;
|
||||
}
|
||||
|
||||
function collectFormData() {
|
||||
var data = new Object();
|
||||
getCheckbox("developerEnabled", data);
|
||||
getCheckbox("developerPermitAnonymousControl", data);
|
||||
getCheckbox("developerDefeatFreemarkerCache", data);
|
||||
getCheckbox("developerInsertFreemarkerDelimiters", data);
|
||||
getCheckbox("developerPageContentsLogCustomListView", data);
|
||||
getCheckbox("developerPageContentsLogCustomShortView", data);
|
||||
getCheckbox("developerI18nDefeatCache", data);
|
||||
getCheckbox("developerI18nLogStringRequests", data);
|
||||
getCheckbox("developerLoggingRDFServiceEnable", data);
|
||||
getCheckbox("developerLoggingRDFServiceStackTrace", data);
|
||||
getText("developerLoggingRDFServiceQueryRestriction", data);
|
||||
getText("developerLoggingRDFServiceStackRestriction", data);
|
||||
getCheckbox("developer_enabled", data);
|
||||
getCheckbox("developer_permitAnonymousControl", data);
|
||||
getCheckbox("developer_defeatFreemarkerCache", data);
|
||||
getCheckbox("developer_insertFreemarkerDelimiters", data);
|
||||
getCheckbox("developer_pageContents_logCustomListView", data);
|
||||
getCheckbox("developer_pageContents_logCustomShortView", data);
|
||||
getCheckbox("developer_i18n_defeatCache", data);
|
||||
getCheckbox("developer_i18n_logStringRequests", data);
|
||||
getCheckbox("developer_loggingRDFService_enable", data);
|
||||
getCheckbox("developer_loggingRDFService_stackTrace", data);
|
||||
getText("developer_loggingRDFService_queryRestriction", data);
|
||||
getText("developer_loggingRDFService_stackRestriction", data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<input type="text" id="${key}" size="30" value="${settings[key]}" >
|
||||
</#macro>
|
||||
|
||||
<#if !settings.developerEnabled>
|
||||
<#if !settings.developer_enabled>
|
||||
<#elseif !settings.mayControl>
|
||||
<div class="developer">
|
||||
<h1>${siteName} is running in developer mode.</h1>
|
||||
|
@ -22,11 +22,11 @@
|
|||
<div id="developerPanelBody">
|
||||
<div>
|
||||
<label>
|
||||
<@showCheckbox "developerEnabled" />
|
||||
<@showCheckbox "developer_enabled" />
|
||||
Enable developer mode
|
||||
</label>
|
||||
<label>
|
||||
<@showCheckbox "developerPermitAnonymousControl" />
|
||||
<@showCheckbox "developer_permitAnonymousControl" />
|
||||
Allow anonymous user to see and modify developer settings
|
||||
</label>
|
||||
</div>
|
||||
|
@ -35,11 +35,11 @@
|
|||
<div class="container">
|
||||
Page configuration
|
||||
<label>
|
||||
<@showCheckbox "developerPageContentsLogCustomListView" />
|
||||
<@showCheckbox "developer_pageContents_logCustomListView" />
|
||||
Log the use of custom list view XML files.
|
||||
</label>
|
||||
<label>
|
||||
<@showCheckbox "developerPageContentsLogCustomShortView" />
|
||||
<@showCheckbox "developer_pageContents_logCustomShortView" />
|
||||
Log the use of custom short views in search, index and browse pages.
|
||||
</label>
|
||||
</div>
|
||||
|
@ -47,11 +47,11 @@
|
|||
<div class="container">
|
||||
Language support
|
||||
<label>
|
||||
<@showCheckbox "developerI18nDefeatCache" />
|
||||
<@showCheckbox "developer_i18n_defeatCache" />
|
||||
Defeat the cache of language property files
|
||||
</label>
|
||||
<label>
|
||||
<@showCheckbox "developerI18nLogStringRequests" />
|
||||
<@showCheckbox "developer_i18n_logStringRequests" />
|
||||
Log the retrieval of language strings
|
||||
</label>
|
||||
</div>
|
||||
|
@ -71,11 +71,11 @@
|
|||
<div class="container">
|
||||
Freemarker templates
|
||||
<label>
|
||||
<@showCheckbox "developerDefeatFreemarkerCache" />
|
||||
<@showCheckbox "developer_defeatFreemarkerCache" />
|
||||
Defeat the template cache
|
||||
</label>
|
||||
<label>
|
||||
<@showCheckbox "developerInsertFreemarkerDelimiters" />
|
||||
<@showCheckbox "developer_insertFreemarkerDelimiters" />
|
||||
Insert HTML comments at start and end of templates
|
||||
</label>
|
||||
</div>
|
||||
|
@ -83,21 +83,21 @@
|
|||
<div class="container">
|
||||
SPARQL Queries
|
||||
<label>
|
||||
<@showCheckbox "developerLoggingRDFServiceEnable" />
|
||||
<@showCheckbox "developer_loggingRDFService_enable" />
|
||||
Log each query
|
||||
</label>
|
||||
<div class="within">
|
||||
<label>
|
||||
<@showCheckbox "developerLoggingRDFServiceStackTrace" />
|
||||
<@showCheckbox "developer_loggingRDFService_stackTrace" />
|
||||
Add stack trace
|
||||
</label>
|
||||
<label>
|
||||
Restrict by query string
|
||||
<@showTextbox "developerLoggingRDFServiceQueryRestriction" />
|
||||
<@showTextbox "developer_loggingRDFService_queryRestriction" />
|
||||
</label>
|
||||
<label>
|
||||
Restrict by calling stack
|
||||
<@showTextbox "developerLoggingRDFServiceStackRestriction" />
|
||||
<@showTextbox "developer_loggingRDFService_stackRestriction" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue