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)) {
|
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;
|
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.i18n.freemarker.I18nMethodModel;
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
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;
|
||||||
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.IndividualShortViewDirective;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective;
|
import edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective;
|
import edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective;
|
||||||
|
@ -70,7 +70,7 @@ public abstract class FreemarkerConfiguration {
|
||||||
confirmInstanceIsSet();
|
confirmInstanceIsSet();
|
||||||
|
|
||||||
synchronized (instance) {
|
synchronized (instance) {
|
||||||
clearTemplateCacheIfRequested(req);
|
clearTemplateCacheIfRequested();
|
||||||
keepTemplateLoaderCurrentWithThemeDirectory(req);
|
keepTemplateLoaderCurrentWithThemeDirectory(req);
|
||||||
setThreadLocalsForRequest(req);
|
setThreadLocalsForRequest(req);
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -84,21 +84,14 @@ public abstract class FreemarkerConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void clearTemplateCacheIfRequested(HttpServletRequest req) {
|
/** If the developer doesn't want the cache, clear it every time. */
|
||||||
if (isTemplateCacheInvalid(req)) {
|
private static void clearTemplateCacheIfRequested() {
|
||||||
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
|
if (settings.getBoolean(Key.DEFEAT_FREEMARKER_CACHE)) {
|
||||||
instance.clearTemplateCache();
|
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
|
* Keep track of the theme directory. If it changes, create an appropriate
|
||||||
* new TemplateLoader.
|
* new TemplateLoader.
|
||||||
|
@ -110,7 +103,7 @@ public abstract class FreemarkerConfiguration {
|
||||||
HttpServletRequest req) {
|
HttpServletRequest req) {
|
||||||
String themeDir = getThemeDirectory(req);
|
String themeDir = getThemeDirectory(req);
|
||||||
if (hasThemeDirectoryChanged(themeDir)
|
if (hasThemeDirectoryChanged(themeDir)
|
||||||
|| haveDeveloperSettingsChanged(req)) {
|
|| haveDeveloperSettingsChanged()) {
|
||||||
TemplateLoader tl = createTemplateLoader(req, themeDir);
|
TemplateLoader tl = createTemplateLoader(req, themeDir);
|
||||||
instance.setTemplateLoader(tl);
|
instance.setTemplateLoader(tl);
|
||||||
}
|
}
|
||||||
|
@ -131,9 +124,9 @@ public abstract class FreemarkerConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean haveDeveloperSettingsChanged(HttpServletRequest req) {
|
private static boolean haveDeveloperSettingsChanged() {
|
||||||
Map<String, Object> settingsMap = DeveloperSettings.getBean(req)
|
Map<String, Object> settingsMap = DeveloperSettings.getInstance()
|
||||||
.getSettingsMap();
|
.getRawSettingsMap();
|
||||||
if (settingsMap.equals(previousSettingsMap)) {
|
if (settingsMap.equals(previousSettingsMap)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,8 +160,8 @@ public abstract class FreemarkerConfiguration {
|
||||||
TemplateLoader tl = new MultiTemplateLoader(loaderArray);
|
TemplateLoader tl = new MultiTemplateLoader(loaderArray);
|
||||||
|
|
||||||
// If requested, add delimiters to the templates.
|
// If requested, add delimiters to the templates.
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(req);
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
if (settings.getBoolean(Keys.INSERT_FREEMARKER_DELIMITERS)) {
|
if (settings.getBoolean(Key.INSERT_FREEMARKER_DELIMITERS)) {
|
||||||
tl = new DelimitingTemplateLoader(tl);
|
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.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale;
|
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;
|
||||||
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,
|
* 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) {
|
protected I18nBundle getBundle(String bundleName, HttpServletRequest req) {
|
||||||
log.debug("Getting bundle '" + bundleName + "'");
|
log.debug("Getting bundle '" + bundleName + "'");
|
||||||
|
|
||||||
I18nLogger i18nLogger = new I18nLogger(req);
|
I18nLogger i18nLogger = new I18nLogger();
|
||||||
try {
|
try {
|
||||||
checkDevelopmentMode(req);
|
checkDevelopmentMode(req);
|
||||||
checkForChangeInThemeDirectory(req);
|
checkForChangeInThemeDirectory(req);
|
||||||
|
@ -133,7 +133,7 @@ public class I18n {
|
||||||
* If we are in development mode, clear the cache on each request.
|
* If we are in development mode, clear the cache on each request.
|
||||||
*/
|
*/
|
||||||
private void checkDevelopmentMode(HttpServletRequest req) {
|
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.");
|
log.debug("In development mode - clearing the cache.");
|
||||||
clearCacheOnRequest(req);
|
clearCacheOnRequest(req);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,11 @@ package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
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.utils.developer.DeveloperSettings;
|
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
|
* 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;
|
private final boolean isLogging;
|
||||||
|
|
||||||
public I18nLogger(HttpServletRequest req) {
|
public I18nLogger() {
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(req);
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
this.isLogging = settings.getBoolean(Keys.ENABLED)
|
this.isLogging = settings.getBoolean(Key.I18N_LOG_STRINGS)
|
||||||
&& settings.getBoolean(Keys.I18N_LOG_STRINGS)
|
|
||||||
&& log.isInfoEnabled();
|
&& log.isInfoEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class RDFServiceUtils {
|
||||||
* Every factory is wrapped in a logger, so we can dynamically
|
* Every factory is wrapped in a logger, so we can dynamically
|
||||||
* enable or disable logging.
|
* enable or disable logging.
|
||||||
*/
|
*/
|
||||||
return new LoggingRDFServiceFactory(context, factory);
|
return new LoggingRDFServiceFactory(factory);
|
||||||
} else {
|
} else {
|
||||||
log.error("Expecting an RDFServiceFactory on the context, but found " + o);
|
log.error("Expecting an RDFServiceFactory on the context, but found " + o);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -5,8 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
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.
|
* For the other methods, it just delegates to the inner RDFService.
|
||||||
*/
|
*/
|
||||||
public class LoggingRDFService implements RDFService {
|
public class LoggingRDFService implements RDFService {
|
||||||
private final ServletContext ctx;
|
|
||||||
private final RDFService innerService;
|
private final RDFService innerService;
|
||||||
|
|
||||||
LoggingRDFService(ServletContext ctx, RDFService innerService) {
|
LoggingRDFService(RDFService innerService) {
|
||||||
this.ctx = ctx;
|
|
||||||
this.innerService = innerService;
|
this.innerService = innerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +30,7 @@ public class LoggingRDFService implements RDFService {
|
||||||
@Override
|
@Override
|
||||||
public boolean changeSetUpdate(ChangeSet changeSet)
|
public boolean changeSetUpdate(ChangeSet changeSet)
|
||||||
throws RDFServiceException {
|
throws RDFServiceException {
|
||||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, changeSet)) {
|
try (RDFServiceLogger l = new RDFServiceLogger(changeSet)) {
|
||||||
return innerService.changeSetUpdate(changeSet);
|
return innerService.changeSetUpdate(changeSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +38,7 @@ public class LoggingRDFService implements RDFService {
|
||||||
@Override
|
@Override
|
||||||
public InputStream sparqlConstructQuery(String query,
|
public InputStream sparqlConstructQuery(String query,
|
||||||
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
||||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||||
return innerService.sparqlConstructQuery(query, resultFormat);
|
return innerService.sparqlConstructQuery(query, resultFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +46,7 @@ public class LoggingRDFService implements RDFService {
|
||||||
@Override
|
@Override
|
||||||
public InputStream sparqlDescribeQuery(String query,
|
public InputStream sparqlDescribeQuery(String query,
|
||||||
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
ModelSerializationFormat resultFormat) throws RDFServiceException {
|
||||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||||
return innerService.sparqlDescribeQuery(query, resultFormat);
|
return innerService.sparqlDescribeQuery(query, resultFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,14 +54,14 @@ public class LoggingRDFService implements RDFService {
|
||||||
@Override
|
@Override
|
||||||
public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat)
|
public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat)
|
||||||
throws RDFServiceException {
|
throws RDFServiceException {
|
||||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
|
try (RDFServiceLogger l = new RDFServiceLogger(resultFormat, query)) {
|
||||||
return innerService.sparqlSelectQuery(query, resultFormat);
|
return innerService.sparqlSelectQuery(query, resultFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sparqlAskQuery(String query) throws RDFServiceException {
|
public boolean sparqlAskQuery(String query) throws RDFServiceException {
|
||||||
try (RDFServiceLogger l = new RDFServiceLogger(ctx, query)) {
|
try (RDFServiceLogger l = new RDFServiceLogger(query)) {
|
||||||
return innerService.sparqlAskQuery(query);
|
return innerService.sparqlAskQuery(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
|
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.ChangeListener;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||||
|
@ -14,23 +12,20 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||||
* wrapped in a LoggingRDFService.
|
* wrapped in a LoggingRDFService.
|
||||||
*/
|
*/
|
||||||
public class LoggingRDFServiceFactory implements RDFServiceFactory {
|
public class LoggingRDFServiceFactory implements RDFServiceFactory {
|
||||||
private final ServletContext ctx;
|
|
||||||
private final RDFServiceFactory factory;
|
private final RDFServiceFactory factory;
|
||||||
|
|
||||||
public LoggingRDFServiceFactory(ServletContext ctx,
|
public LoggingRDFServiceFactory(RDFServiceFactory factory) {
|
||||||
RDFServiceFactory factory) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RDFService getRDFService() {
|
public RDFService getRDFService() {
|
||||||
return new LoggingRDFService(ctx, factory.getRDFService());
|
return new LoggingRDFService(factory.getRDFService());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RDFService getShortTermRDFService() {
|
public RDFService getShortTermRDFService() {
|
||||||
return new LoggingRDFService(ctx, factory.getShortTermRDFService());
|
return new LoggingRDFService(factory.getShortTermRDFService());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,14 +9,12 @@ import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
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.utils.developer.DeveloperSettings;
|
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.
|
* 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 {
|
public class RDFServiceLogger implements AutoCloseable {
|
||||||
private static final Log log = LogFactory.getLog(RDFServiceLogger.class);
|
private static final Log log = LogFactory.getLog(RDFServiceLogger.class);
|
||||||
|
|
||||||
private final ServletContext ctx;
|
|
||||||
private final Object[] args;
|
private final Object[] args;
|
||||||
|
|
||||||
private boolean isEnabled;
|
private boolean isEnabled;
|
||||||
|
@ -58,31 +55,33 @@ public class RDFServiceLogger implements AutoCloseable {
|
||||||
|
|
||||||
private long startTime;
|
private long startTime;
|
||||||
|
|
||||||
public RDFServiceLogger(ServletContext ctx, Object... args) {
|
public RDFServiceLogger(Object... args) {
|
||||||
this.ctx = ctx;
|
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
|
||||||
getProperties();
|
try {
|
||||||
|
getProperties();
|
||||||
if (isEnabled && log.isInfoEnabled()) {
|
if (isEnabled && log.isInfoEnabled()) {
|
||||||
loadStackTrace();
|
loadStackTrace();
|
||||||
if (passesQueryRestriction() && passesStackRestriction()) {
|
if (passesQueryRestriction() && passesStackRestriction()) {
|
||||||
this.startTime = System.currentTimeMillis();
|
this.startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to create instance", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getProperties() {
|
private void getProperties() {
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(ctx);
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
isEnabled = settings.getBoolean(Keys.LOGGING_RDF_ENABLE);
|
isEnabled = settings.getBoolean(Key.LOGGING_RDF_ENABLE);
|
||||||
traceRequested = settings.getBoolean(Keys.LOGGING_RDF_STACK_TRACE);
|
traceRequested = settings.getBoolean(Key.LOGGING_RDF_STACK_TRACE);
|
||||||
queryStringRestriction = patternFromSettings(settings,
|
queryStringRestriction = patternFromSettings(settings,
|
||||||
Keys.LOGGING_RDF_QUERY_RESTRICTION);
|
Key.LOGGING_RDF_QUERY_RESTRICTION);
|
||||||
callStackRestriction = patternFromSettings(settings,
|
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);
|
String patternString = settings.getString(key);
|
||||||
if (StringUtils.isBlank(patternString)) {
|
if (StringUtils.isBlank(patternString)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -160,13 +159,13 @@ public class RDFServiceLogger implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String assembleQueryString() {
|
private String assembleQueryString() {
|
||||||
StringBuilder query = new StringBuilder();
|
List<String> stringArgs = new ArrayList<>();
|
||||||
for (Object arg : args) {
|
for (Object arg : args) {
|
||||||
if (arg instanceof String) {
|
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() {
|
private boolean passesStackRestriction() {
|
||||||
|
@ -188,16 +187,20 @@ public class RDFServiceLogger implements AutoCloseable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (startTime != 0L) {
|
try {
|
||||||
long endTime = System.currentTimeMillis();
|
if (startTime != 0L) {
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
|
||||||
float elapsedSeconds = (endTime - startTime) / 1000.0F;
|
float elapsedSeconds = (endTime - startTime) / 1000.0F;
|
||||||
String cleanArgs = Arrays.deepToString(args).replaceAll(
|
String cleanArgs = Arrays.deepToString(args).replaceAll(
|
||||||
"[\\n\\r\\t]+", " ");
|
"[\\n\\r\\t]+", " ");
|
||||||
String formattedTrace = formatStackTrace();
|
String formattedTrace = formatStackTrace();
|
||||||
|
|
||||||
log.info(String.format("%8.3f %s %s %s", elapsedSeconds,
|
log.info(String.format("%8.3f %s %s %s", elapsedSeconds,
|
||||||
methodName, cleanArgs, formattedTrace));
|
methodName, cleanArgs, formattedTrace));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to write log record", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
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.services.shortview.FakeApplicationOntologyService.TemplateAndDataGetters;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
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.
|
* 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 {
|
public class ShortViewLogger {
|
||||||
private static final Log log = LogFactory.getLog(ShortViewLogger.class);
|
private static final Log log = LogFactory.getLog(ShortViewLogger.class);
|
||||||
|
|
||||||
public static void log(VitroRequest vreq, String contextName,
|
public static void log(String contextName, Individual individual,
|
||||||
Individual individual, String classUri, TemplateAndDataGetters tdg) {
|
String classUri, TemplateAndDataGetters tdg) {
|
||||||
if (isLogging(vreq)) {
|
if (isLogging()) {
|
||||||
log.info("Using custom short view in " + contextName + " because '"
|
log.info("Using custom short view in " + contextName + " because '"
|
||||||
+ individual.getURI() + "' (" + individual.getLabel()
|
+ individual.getURI() + "' (" + individual.getLabel()
|
||||||
+ ") has type '" + classUri + "': " + tdg);
|
+ ") has type '" + classUri + "': " + tdg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(VitroRequest vreq, String contextName,
|
public static void log(String contextName, Individual individual) {
|
||||||
Individual individual) {
|
if (isLogging()) {
|
||||||
if (isLogging(vreq)) {
|
|
||||||
log.info("Using default short view in " + contextName + " for '"
|
log.info("Using default short view in " + contextName + " for '"
|
||||||
+ individual.getURI() + "' (" + individual.getLabel() + ")");
|
+ individual.getURI() + "' (" + individual.getLabel() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLogging(VitroRequest vreq) {
|
private static boolean isLogging() {
|
||||||
if (!log.isInfoEnabled()) {
|
return log.isInfoEnabled()
|
||||||
return false;
|
&& DeveloperSettings.getInstance().getBoolean(
|
||||||
}
|
Key.PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW);
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
|
||||||
return settings.getBoolean(Keys.ENABLED)
|
|
||||||
&& settings
|
|
||||||
.getBoolean(Keys.PAGE_CONTENTS_LOG_CUSTOM_SHORT_VIEW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,13 +114,13 @@ public class ShortViewServiceImpl implements ShortViewService {
|
||||||
TemplateAndDataGetters tdg = faker.getShortViewProperties(vreq,
|
TemplateAndDataGetters tdg = faker.getShortViewProperties(vreq,
|
||||||
individual, classUri, svContext.name());
|
individual, classUri, svContext.name());
|
||||||
if (tdg != null) {
|
if (tdg != null) {
|
||||||
ShortViewLogger.log(vreq, svContext.name(), individual, classUri, tdg);
|
ShortViewLogger.log(svContext.name(), individual, classUri, tdg);
|
||||||
return tdg;
|
return tdg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Didn't find one? Use the default values.
|
// Didn't find one? Use the default values.
|
||||||
ShortViewLogger.log(vreq, svContext.name(), individual);
|
ShortViewLogger.log(svContext.name(), individual);
|
||||||
return new TemplateAndDataGetters(svContext.getDefaultTemplateName());
|
return new TemplateAndDataGetters(svContext.getDefaultTemplateName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils.developer;
|
package edu.cornell.mannlib.vitro.webapp.utils.developer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -13,251 +14,92 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.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
|
* Start with an empty settings map.
|
||||||
* home directory. If the file doesn't exist, or doesn't contain values for
|
*
|
||||||
* certain properties, those propertiew will keep their default values.
|
* 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
|
* 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
|
* 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
|
* does not contain a value for a property, that property will keep its current
|
||||||
* value.
|
* 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 {
|
public class DeveloperSettings {
|
||||||
private static final Log log = LogFactory.getLog(DeveloperSettings.class);
|
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
|
// The factory
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
protected static final String ATTRIBUTE_NAME = DeveloperSettings.class
|
private static final DeveloperSettings instance = new DeveloperSettings();
|
||||||
.getName();
|
|
||||||
|
|
||||||
public static DeveloperSettings getBean(HttpServletRequest req) {
|
public static DeveloperSettings getInstance() {
|
||||||
return getBean(req.getSession().getServletContext());
|
return instance;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// The instance
|
// The instance
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private final Map<Keys, Object> settings = new EnumMap<>(Keys.class);
|
private final Map<Key, String> settings;
|
||||||
|
|
||||||
protected DeveloperSettings(ServletContext ctx) {
|
private DeveloperSettings() {
|
||||||
updateFromFile(ctx);
|
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) {
|
public void updateFromRequest(Map<String, String[]> parameterMap) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
dumpParameterMap(parameterMap);
|
dumpParameterMap(parameterMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Keys, String> fromRequest = new HashMap<>();
|
Map<Key, String> fromRequest = new HashMap<>();
|
||||||
for (String key : parameterMap.keySet()) {
|
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);
|
update(fromRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(Map<Keys, String> changedSettings) {
|
public void updateFromProperties(Properties properties) {
|
||||||
for (Keys key : Keys.values()) {
|
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);
|
String s = changedSettings.get(key);
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
if (key.isBoolean()) {
|
if (key.isBoolean()) {
|
||||||
settings.put(key, Boolean.valueOf(s));
|
settings.put(key, Boolean.valueOf(s).toString());
|
||||||
} else {
|
} else {
|
||||||
settings.put(key, s);
|
settings.put(key, s);
|
||||||
}
|
}
|
||||||
|
@ -266,48 +108,68 @@ public class DeveloperSettings {
|
||||||
log.debug("DeveloperSettings: " + this);
|
log.debug("DeveloperSettings: " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(Keys key) {
|
/**
|
||||||
if (key.isBoolean()) {
|
* If developerMode is enabled, return the boolean value of the stored
|
||||||
return getBoolean(key);
|
* setting.
|
||||||
} else {
|
*/
|
||||||
return getString(key);
|
public boolean getBoolean(Key key) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBoolean(Keys key) {
|
|
||||||
if (!key.isBoolean()) {
|
if (!key.isBoolean()) {
|
||||||
throw new IllegalArgumentException("Key '" + key
|
log.warn("Key '" + key + "' does not take a boolean value.");
|
||||||
+ "' does not take a boolean value.");
|
|
||||||
}
|
}
|
||||||
if (settings.containsKey(key)) {
|
if (isDeveloperModeEnabled()) {
|
||||||
if (Boolean.TRUE.equals(settings.get(Keys.ENABLED))) {
|
return Boolean.valueOf(settings.get(key));
|
||||||
return (Boolean) settings.get(key);
|
} else {
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
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()) {
|
if (key.isBoolean()) {
|
||||||
throw new IllegalArgumentException("Key '" + key
|
log.warn("Key '" + key + "' takes a boolean value.");
|
||||||
+ "' takes a boolean value.");
|
|
||||||
}
|
}
|
||||||
if (settings.containsKey(key)) {
|
String value = settings.get(key);
|
||||||
if (Boolean.TRUE.equals(settings.get(Keys.ENABLED))) {
|
if (value != null && isDeveloperModeEnabled()) {
|
||||||
return (String) settings.get(key);
|
return value;
|
||||||
}
|
} else {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
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<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
for (Keys key : Keys.values()) {
|
for (Key key : Key.values()) {
|
||||||
map.put(key.elementId(), get(key));
|
map.put(key.elementId(), getRawValue(key));
|
||||||
}
|
}
|
||||||
return map;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DeveloperSettings" + settings;
|
return "DeveloperSettings" + settings;
|
||||||
|
@ -322,4 +184,42 @@ public class DeveloperSettings {
|
||||||
log.debug("Parameter map: " + map);
|
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;
|
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.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -42,7 +42,7 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
||||||
@Override
|
@Override
|
||||||
protected void doRequest(VitroRequest vreq, HttpServletResponse resp)
|
protected void doRequest(VitroRequest vreq, HttpServletResponse resp)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Are they allowed to control the panel?
|
* Are they allowed to control the panel?
|
||||||
|
@ -70,8 +70,9 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
||||||
private Map<String, Object> buildBodyMap(boolean authorized,
|
private Map<String, Object> buildBodyMap(boolean authorized,
|
||||||
DeveloperSettings settings) {
|
DeveloperSettings settings) {
|
||||||
Map<String, Object> settingsMap = new HashMap<>();
|
Map<String, Object> settingsMap = new HashMap<>();
|
||||||
settingsMap.putAll(settings.getSettingsMap());
|
settingsMap.putAll(settings.getRawSettingsMap());
|
||||||
settingsMap.put("mayControl", authorized);
|
settingsMap.put("mayControl", authorized);
|
||||||
|
|
||||||
Map<String, Object> bodyMap = new HashMap<>();
|
Map<String, Object> bodyMap = new HashMap<>();
|
||||||
bodyMap.put("settings", settingsMap);
|
bodyMap.put("settings", settingsMap);
|
||||||
return bodyMap;
|
return bodyMap;
|
||||||
|
@ -84,7 +85,7 @@ public class DeveloperSettingsServlet extends VitroAjaxController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAuthorized(VitroRequest vreq) {
|
private boolean isAuthorized(VitroRequest vreq) {
|
||||||
boolean authBySetting = DeveloperSettings.getBean(vreq).getBoolean(
|
boolean authBySetting = DeveloperSettings.getInstance().getBoolean(
|
||||||
PERMIT_ANONYMOUS_CONTROL);
|
PERMIT_ANONYMOUS_CONTROL);
|
||||||
boolean authByPolicy = PolicyHelper.isAuthorizedForActions(vreq,
|
boolean authByPolicy = PolicyHelper.isAuthorizedForActions(vreq,
|
||||||
SimplePermission.ENABLE_DEVELOPER_PANEL.ACTION);
|
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 org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
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;
|
||||||
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
|
* 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
|
private static final Log log = LogFactory
|
||||||
.getLog(CustomListViewLogger.class);
|
.getLog(CustomListViewLogger.class);
|
||||||
|
|
||||||
public static void log(VitroRequest vreq, ObjectProperty op,
|
public static void log(ObjectProperty op, String configFileName) {
|
||||||
String configFileName) {
|
if (isLogging()) {
|
||||||
if (isLogging(vreq)) {
|
|
||||||
log.info("Using list view: '" + configFileName + "' for "
|
log.info("Using list view: '" + configFileName + "' for "
|
||||||
+ op.getURI() + " (" + op.getLabel() + ")");
|
+ op.getURI() + " (" + op.getLabel() + ")");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLogging(VitroRequest vreq) {
|
private static boolean isLogging() {
|
||||||
if (!log.isInfoEnabled()) {
|
if (!log.isInfoEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DeveloperSettings settings = DeveloperSettings.getBean(vreq);
|
DeveloperSettings settings = DeveloperSettings.getInstance();
|
||||||
return settings.getBoolean(Keys.ENABLED)
|
return settings.getBoolean(Key.PAGE_CONTENTS_LOG_CUSTOM_LIST_VIEW);
|
||||||
&& settings.getBoolean(Keys.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;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.ConfigError;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.ConfigError;
|
||||||
import freemarker.cache.TemplateLoader;
|
import freemarker.cache.TemplateLoader;
|
||||||
import freemarker.template.Configuration;
|
|
||||||
|
|
||||||
public class PropertyListConfig {
|
public class PropertyListConfig {
|
||||||
private static final Log log = LogFactory.getLog(PropertyListConfig.class);
|
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
|
if (configFileName == null) { // no custom config; use default config
|
||||||
configFileName = DEFAULT_CONFIG_FILE_NAME;
|
configFileName = DEFAULT_CONFIG_FILE_NAME;
|
||||||
} else {
|
} else {
|
||||||
CustomListViewLogger.log(vreq, op, configFileName);
|
CustomListViewLogger.log(op, configFileName);
|
||||||
}
|
}
|
||||||
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());
|
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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
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.
|
* 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> mockResources = new HashMap<String, String>();
|
||||||
private final Map<String, String> realPaths = 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) {
|
public void setContextPath(String contextPath) {
|
||||||
if (contextPath == null) {
|
if (contextPath == null) {
|
||||||
throw new NullPointerException("contextPath may not be 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.config.ConfigurationPropertiesSmokeTests
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -34,41 +34,41 @@ function DeveloperPanel(developerAjaxUrl) {
|
||||||
document.getElementById("developerPanelSaveButton").onclick = function() {
|
document.getElementById("developerPanelSaveButton").onclick = function() {
|
||||||
updateDeveloperPanel(collectFormData());
|
updateDeveloperPanel(collectFormData());
|
||||||
}
|
}
|
||||||
document.getElementById("developerEnabled").onchange = updateDisabledFields
|
document.getElementById("developer_enabled").onchange = updateDisabledFields
|
||||||
document.getElementById("developerLoggingRDFServiceEnable").onchange = updateDisabledFields
|
document.getElementById("developer_loggingRDFService_enable").onchange = updateDisabledFields
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDisabledFields() {
|
function updateDisabledFields() {
|
||||||
var developerEnabled = document.getElementById("developerEnabled").checked;
|
var developerEnabled = document.getElementById("developer_enabled").checked;
|
||||||
document.getElementById("developerPermitAnonymousControl").disabled = !developerEnabled;
|
document.getElementById("developer_permitAnonymousControl").disabled = !developerEnabled;
|
||||||
document.getElementById("developerDefeatFreemarkerCache").disabled = !developerEnabled;
|
document.getElementById("developer_defeatFreemarkerCache").disabled = !developerEnabled;
|
||||||
document.getElementById("developerInsertFreemarkerDelimiters").disabled = !developerEnabled;
|
document.getElementById("developer_insertFreemarkerDelimiters").disabled = !developerEnabled;
|
||||||
document.getElementById("developerPageContentsLogCustomListView").disabled = !developerEnabled;
|
document.getElementById("developer_pageContents_logCustomListView").disabled = !developerEnabled;
|
||||||
document.getElementById("developerPageContentsLogCustomShortView").disabled = !developerEnabled;
|
document.getElementById("developer_pageContents_logCustomShortView").disabled = !developerEnabled;
|
||||||
document.getElementById("developerI18nDefeatCache").disabled = !developerEnabled;
|
document.getElementById("developer_i18n_defeatCache").disabled = !developerEnabled;
|
||||||
document.getElementById("developerI18nLogStringRequests").disabled = !developerEnabled;
|
document.getElementById("developer_i18n_logStringRequests").disabled = !developerEnabled;
|
||||||
document.getElementById("developerLoggingRDFServiceEnable").disabled = !developerEnabled;
|
document.getElementById("developer_loggingRDFService_enable").disabled = !developerEnabled;
|
||||||
|
|
||||||
var rdfServiceEnabled = developerEnabled && document.getElementById("developerLoggingRDFServiceEnable").checked;
|
var rdfServiceEnabled = developerEnabled && document.getElementById("developer_loggingRDFService_enable").checked;
|
||||||
document.getElementById("developerLoggingRDFServiceStackTrace").disabled = !rdfServiceEnabled;
|
document.getElementById("developer_loggingRDFService_stackTrace").disabled = !rdfServiceEnabled;
|
||||||
document.getElementById("developerLoggingRDFServiceQueryRestriction").disabled = !rdfServiceEnabled;
|
document.getElementById("developer_loggingRDFService_queryRestriction").disabled = !rdfServiceEnabled;
|
||||||
document.getElementById("developerLoggingRDFServiceStackRestriction").disabled = !rdfServiceEnabled;
|
document.getElementById("developer_loggingRDFService_stackRestriction").disabled = !rdfServiceEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectFormData() {
|
function collectFormData() {
|
||||||
var data = new Object();
|
var data = new Object();
|
||||||
getCheckbox("developerEnabled", data);
|
getCheckbox("developer_enabled", data);
|
||||||
getCheckbox("developerPermitAnonymousControl", data);
|
getCheckbox("developer_permitAnonymousControl", data);
|
||||||
getCheckbox("developerDefeatFreemarkerCache", data);
|
getCheckbox("developer_defeatFreemarkerCache", data);
|
||||||
getCheckbox("developerInsertFreemarkerDelimiters", data);
|
getCheckbox("developer_insertFreemarkerDelimiters", data);
|
||||||
getCheckbox("developerPageContentsLogCustomListView", data);
|
getCheckbox("developer_pageContents_logCustomListView", data);
|
||||||
getCheckbox("developerPageContentsLogCustomShortView", data);
|
getCheckbox("developer_pageContents_logCustomShortView", data);
|
||||||
getCheckbox("developerI18nDefeatCache", data);
|
getCheckbox("developer_i18n_defeatCache", data);
|
||||||
getCheckbox("developerI18nLogStringRequests", data);
|
getCheckbox("developer_i18n_logStringRequests", data);
|
||||||
getCheckbox("developerLoggingRDFServiceEnable", data);
|
getCheckbox("developer_loggingRDFService_enable", data);
|
||||||
getCheckbox("developerLoggingRDFServiceStackTrace", data);
|
getCheckbox("developer_loggingRDFService_stackTrace", data);
|
||||||
getText("developerLoggingRDFServiceQueryRestriction", data);
|
getText("developer_loggingRDFService_queryRestriction", data);
|
||||||
getText("developerLoggingRDFServiceStackRestriction", data);
|
getText("developer_loggingRDFService_stackRestriction", data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<input type="text" id="${key}" size="30" value="${settings[key]}" >
|
<input type="text" id="${key}" size="30" value="${settings[key]}" >
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#if !settings.developerEnabled>
|
<#if !settings.developer_enabled>
|
||||||
<#elseif !settings.mayControl>
|
<#elseif !settings.mayControl>
|
||||||
<div class="developer">
|
<div class="developer">
|
||||||
<h1>${siteName} is running in developer mode.</h1>
|
<h1>${siteName} is running in developer mode.</h1>
|
||||||
|
@ -22,11 +22,11 @@
|
||||||
<div id="developerPanelBody">
|
<div id="developerPanelBody">
|
||||||
<div>
|
<div>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerEnabled" />
|
<@showCheckbox "developer_enabled" />
|
||||||
Enable developer mode
|
Enable developer mode
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerPermitAnonymousControl" />
|
<@showCheckbox "developer_permitAnonymousControl" />
|
||||||
Allow anonymous user to see and modify developer settings
|
Allow anonymous user to see and modify developer settings
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,11 +35,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Page configuration
|
Page configuration
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerPageContentsLogCustomListView" />
|
<@showCheckbox "developer_pageContents_logCustomListView" />
|
||||||
Log the use of custom list view XML files.
|
Log the use of custom list view XML files.
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerPageContentsLogCustomShortView" />
|
<@showCheckbox "developer_pageContents_logCustomShortView" />
|
||||||
Log the use of custom short views in search, index and browse pages.
|
Log the use of custom short views in search, index and browse pages.
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,11 +47,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Language support
|
Language support
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerI18nDefeatCache" />
|
<@showCheckbox "developer_i18n_defeatCache" />
|
||||||
Defeat the cache of language property files
|
Defeat the cache of language property files
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerI18nLogStringRequests" />
|
<@showCheckbox "developer_i18n_logStringRequests" />
|
||||||
Log the retrieval of language strings
|
Log the retrieval of language strings
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,11 +71,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Freemarker templates
|
Freemarker templates
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerDefeatFreemarkerCache" />
|
<@showCheckbox "developer_defeatFreemarkerCache" />
|
||||||
Defeat the template cache
|
Defeat the template cache
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerInsertFreemarkerDelimiters" />
|
<@showCheckbox "developer_insertFreemarkerDelimiters" />
|
||||||
Insert HTML comments at start and end of templates
|
Insert HTML comments at start and end of templates
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,21 +83,21 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
SPARQL Queries
|
SPARQL Queries
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerLoggingRDFServiceEnable" />
|
<@showCheckbox "developer_loggingRDFService_enable" />
|
||||||
Log each query
|
Log each query
|
||||||
</label>
|
</label>
|
||||||
<div class="within">
|
<div class="within">
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerLoggingRDFServiceStackTrace" />
|
<@showCheckbox "developer_loggingRDFService_stackTrace" />
|
||||||
Add stack trace
|
Add stack trace
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Restrict by query string
|
Restrict by query string
|
||||||
<@showTextbox "developerLoggingRDFServiceQueryRestriction" />
|
<@showTextbox "developer_loggingRDFService_queryRestriction" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Restrict by calling stack
|
Restrict by calling stack
|
||||||
<@showTextbox "developerLoggingRDFServiceStackRestriction" />
|
<@showTextbox "developer_loggingRDFService_stackRestriction" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue