VIVO-541 Add functions and formatting to the developer panel.

This commit is contained in:
j2blake 2013-11-20 15:50:51 -05:00
parent 1f5c34bde9
commit 00f3e363e5
10 changed files with 288 additions and 64 deletions

View file

@ -23,9 +23,12 @@ import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys;
*
* If not enabled, or if the logging level is insufficient, this does nothing.
*
* If enabled, it checks for restrictions. If there is a restriction pattern
* (regular expression), the a log message will only be printed if one of the
* fully-qualified class names in the stack trace matches that pattern.
* If enabled, it checks for restrictions. If there is a restriction on the call
* stack (regular expression), then a log message will only be printed if the
* pattern is found in the concatenated call stack (fully-qualified class names
* and method names). If there is a restriction on the query string (regular
* expression) then a log message will only be printed if the pattern is found
* in the query string.
*
* If everything passes muster, the constructor will record the time that the
* instance was created.
@ -47,7 +50,8 @@ public class RDFServiceLogger implements AutoCloseable {
private boolean isEnabled;
private boolean traceRequested;
private Pattern restriction;
private Pattern queryStringRestriction;
private Pattern callStackRestriction;
private String methodName;
private List<StackTraceElement> trace = Collections.emptyList();
@ -62,7 +66,7 @@ public class RDFServiceLogger implements AutoCloseable {
if (isEnabled && log.isInfoEnabled()) {
loadStackTrace();
if (passesRestrictions()) {
if (passesQueryRestriction() && passesStackRestriction()) {
this.startTime = System.currentTimeMillis();
}
}
@ -72,20 +76,23 @@ public class RDFServiceLogger implements AutoCloseable {
DeveloperSettings settings = DeveloperSettings.getBean(ctx);
isEnabled = settings.getBoolean(Keys.LOGGING_RDF_ENABLE);
traceRequested = settings.getBoolean(Keys.LOGGING_RDF_STACK_TRACE);
queryStringRestriction = patternFromSettings(settings,
Keys.LOGGING_RDF_QUERY_RESTRICTION);
callStackRestriction = patternFromSettings(settings,
Keys.LOGGING_RDF_STACK_RESTRICTION);
}
String restrictionString = settings
.getString(Keys.LOGGING_RDF_RESTRICTION);
if (StringUtils.isBlank(restrictionString)) {
restriction = null;
} else {
try {
restriction = Pattern.compile(restrictionString);
} catch (Exception e) {
log.error("Failed to compile the pattern for "
+ Keys.LOGGING_RDF_RESTRICTION + " = " + restriction
+ " " + e);
isEnabled = false;
}
private Pattern patternFromSettings(DeveloperSettings settings, Keys key) {
String patternString = settings.getString(key);
if (StringUtils.isBlank(patternString)) {
return null;
}
try {
return Pattern.compile(patternString);
} catch (Exception e) {
log.error("Failed to compile the pattern for " + key + " = "
+ patternString + " " + e);
return Pattern.compile("^_____NEVER MATCH_____$");
}
}
@ -144,16 +151,39 @@ public class RDFServiceLogger implements AutoCloseable {
}
}
private boolean passesRestrictions() {
if (restriction == null) {
private boolean passesQueryRestriction() {
if (queryStringRestriction == null) {
return true;
}
for (StackTraceElement ste : trace) {
if (restriction.matcher(ste.getClassName()).find()) {
return true;
String q = assembleQueryString();
return queryStringRestriction.matcher(q).find();
}
private String assembleQueryString() {
StringBuilder query = new StringBuilder();
for (Object arg : args) {
if (arg instanceof String) {
query.append((String) arg).append(" ");
}
}
return false;
return query.deleteCharAt(query.length() - 1).toString();
}
private boolean passesStackRestriction() {
if (callStackRestriction == null) {
return true;
}
String q = assembleCallStackString();
return callStackRestriction.matcher(q).find();
}
private String assembleCallStackString() {
StringBuilder stack = new StringBuilder();
for (StackTraceElement ste : trace) {
stack.append(ste.getClassName()).append(" ")
.append(ste.getMethodName()).append(" ");
}
return stack.deleteCharAt(stack.length() - 1).toString();
}
@Override

View file

@ -380,6 +380,12 @@ public class FakeApplicationOntologyService {
return dataGetters;
}
@Override
public String toString() {
return "[template=" + templateName + ", dataGetters=" + dataGetters
+ "]";
}
}
/** The view specifications that we read from the config file. */

View file

@ -0,0 +1,47 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.services.shortview;
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;
/**
* When we use a short view other than the default, log it.
*/
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)) {
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)) {
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);
}
}

View file

@ -15,9 +15,7 @@ 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.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService;
import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateParsingException;
import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateProcessingException;
@ -116,11 +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);
return tdg;
}
}
// Didn't find one? Use the default values.
ShortViewLogger.log(vreq, svContext.name(), individual);
return new TemplateAndDataGetters(svContext.getDefaultTemplateName());
}

View file

@ -82,9 +82,29 @@ public class DeveloperSettings {
* Don't log with the LoggingRDFService unless the calling stack meets
* this restriction.
*/
LOGGING_RDF_RESTRICTION("developer.loggingRDFService.restriction",
false);
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;

View file

@ -0,0 +1,38 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview;
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;
/**
* If enabled in the developer settings (and log levels), log every non-default
* custom list view.
*/
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)) {
log.info("Using list view: '" + configFileName + "' for "
+ op.getURI() + " (" + op.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_LIST_VIEW);
}
}

View file

@ -61,6 +61,8 @@ public class PropertyListConfig {
String configFileName = wadf.getObjectPropertyDao().getCustomListViewConfigFileName(op);
if (configFileName == null) { // no custom config; use default config
configFileName = DEFAULT_CONFIG_FILE_NAME;
} else {
CustomListViewLogger.log(vreq, op, configFileName);
}
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());