Merge branch 'maint-rel-1.6' of https://github.com/vivo-project/Vitro into maint-rel-1.6

This commit is contained in:
brianjlowe 2013-11-20 16:48:30 -05:00
commit 216b1ac6eb
16 changed files with 351 additions and 101 deletions

View file

@ -32,6 +32,7 @@
# #
# developer.permitAnonymousControl # developer.permitAnonymousControl
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Freemarker # Freemarker
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -52,6 +53,25 @@
# #
# developer.defeatFreemarkerCache = true # developer.defeatFreemarkerCache = true
#------------------------------------------------------------------------------
# Page configuration
#------------------------------------------------------------------------------
#
# Turn on logging of custom list view configuration files. Each time a property
# uses a list view other than the default, note it in the log. The default is
# 'false'.
#
# developer.pageContents.logCustomListView = true
#
# Turn on logging of custom short views. Each time an individual uses a short
# view other than the default, note it in the log. The default is 'false'.
#
# developer.pageContents.logCustomShortView = true
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Internationalization # Internationalization
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -98,10 +118,18 @@
# developer.loggingRDFService.stackTrace = true # developer.loggingRDFService.stackTrace = true
# #
# If SPARQL query logging is enabled, a regular expression can be used to # If SPARQL query logging is enabled, restrict the number of log entries by
# restrict the number of entries that are produced. The expression is # matching a regular expression against the query string. If the expression
# tested against each line in the (unabridged) stack trace. If the # doesn't match the string, then no log entry is made. The default is "",
# expression doesn't match any line in the stack trace, then no log entry # which means no restriction.
# is made. The default is 'false'.
# #
# developer.loggingRDFService.restriction = true # developer.loggingRDFService.queryRestriction = .*
#
# If SPARQL query logging is enabled, restrict the number of log entries by
# matching a regular expression against the stack trace. The abridged stack
# trace is concatenated into a single string of fully qualified class names
# and method names. If the expression doesn't match the string, then no log
# entry is made. The default is "", which means no restriction.
#
# developer.loggingRDFService.stackRestriction = .*

View file

@ -481,6 +481,9 @@ restrict_logins_mixed_caps = Restringir conexiones
site_information = Información del sitio site_information = Información del sitio
user_accounts = Las cuentas de usuario user_accounts = Las cuentas de usuario
activate_developer_panel = Activar el panel desarrollador
activate_developer_panel_mixed_caps = Activar el panel desarrollador
# #
# search controller ( PagedSearchController.java ) # search controller ( PagedSearchController.java )
# #

View file

@ -73,6 +73,10 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
urls.put("rebuildSearchIndex", UrlBuilder.getUrl("/SearchIndex")); urls.put("rebuildSearchIndex", UrlBuilder.getUrl("/SearchIndex"));
} }
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.ENABLE_DEVELOPER_PANEL.ACTIONS)) {
urls.put("activateDeveloperPanel", "javascript:new DeveloperPanel(developerAjaxUrl).setupDeveloperPanel({developerEnabled: true});");
}
return urls; return urls;
} }

View file

@ -15,6 +15,8 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.Comparator; import java.util.Comparator;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -178,64 +180,71 @@ public class FreemarkerTemplateLoader implements TemplateLoader {
* search term, and how well they match. * search term, and how well they match.
*/ */
static class PathPieces { static class PathPieces {
static final Pattern PATTERN = Pattern.compile("(.+?)" // base name
+ "(_[a-z]{2})?" // optional language
+ "(_[A-Z]{2})?" // optional country
+ "(\\.\\w+)?" // optional extension
);
final Path path; final Path path;
final String base; final String base;
final String language; final String language;
final String region; final String region;
final String extension; final String extension;
public PathPieces(String searchTerm) { public PathPieces(String pathString) {
this(Paths.get(searchTerm)); this(Paths.get(pathString));
} }
public PathPieces(Path path) { public PathPieces(Path path) {
this.path = path; this.path = path;
String filename = path.getFileName().toString(); String filename = path.getFileName().toString();
int dotHere = filename.lastIndexOf('.');
String basename;
if (dotHere != -1) {
basename = filename.substring(0, dotHere);
this.extension = filename.substring(dotHere);
} else {
basename = filename;
this.extension = "";
}
int break2 = basename.lastIndexOf('_'); Matcher m = PATTERN.matcher(filename);
int break1 = basename.lastIndexOf('_', break2 - 1); if (m.matches()) {
if (break1 != -1) { base = getGroup(m, 1);
this.base = basename.substring(0, break1); language = getGroup(m, 2);
this.language = basename.substring(break1, break2); region = getGroup(m, 3);
this.region = basename.substring(break2); extension = getGroup(m, 4);
} else if (break2 != -1) {
this.base = basename.substring(0, break2);
this.language = basename.substring(break2);
this.region = "";
} else { } else {
this.base = basename; base = filename;
this.language = ""; language = "";
this.region = ""; region = "";
extension = "";
} }
} }
/** This is the search term. Does that candidate qualify as a result? */ private String getGroup(Matcher m, int i) {
return (m.start(i) == -1) ? "" : m.group(i);
}
/**
* If I'm searching for this, is that an acceptable match?
*
* Note that this is asymetrical -- a search term without a region will
* match a candidate with a region, but not vice versa. Same with
* language.
*/
public boolean matches(PathPieces that) { public boolean matches(PathPieces that) {
return base.equals(that.base) && extension.equals(that.extension) return base.equals(that.base) && extension.equals(that.extension)
&& (language.isEmpty() || language.equals(that.language)) && (language.isEmpty() || language.equals(that.language))
&& (region.isEmpty() || region.equals(that.region)); && (region.isEmpty() || region.equals(that.region));
} }
/**
* How good a match is that to this?
*/
public int score(PathPieces that) { public int score(PathPieces that) {
if (matches(that)) { if (matches(that)) {
if (that.language.equals(language)) { if (that.language.equals(language)) {
if (that.region.equals(region)) { if (that.region.equals(region)) {
return 3; // match language and region return 3; // exact match.
} else { } else {
return 2; // match language, default region. return 2; // same language, approximate region.
} }
} else { } else {
return 1; // default language. return 1; // approximate language.
} }
} else { } else {
return -1; // doesn't match. return -1; // doesn't match.

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

View file

@ -380,6 +380,12 @@ public class FakeApplicationOntologyService {
return dataGetters; return dataGetters;
} }
@Override
public String toString() {
return "[template=" + templateName + ", dataGetters=" + dataGetters
+ "]";
}
} }
/** The view specifications that we read from the config file. */ /** 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 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.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; 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;
import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateParsingException; import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateParsingException;
import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.services.freemarker.FreemarkerProcessingService.TemplateProcessingException;
@ -116,11 +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);
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);
return new TemplateAndDataGetters(svContext.getDefaultTemplateName()); return new TemplateAndDataGetters(svContext.getDefaultTemplateName());
} }

View file

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

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); String configFileName = wadf.getObjectPropertyDao().getCustomListViewConfigFileName(op);
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 {
CustomListViewLogger.log(vreq, 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());

View file

@ -286,18 +286,20 @@ public class FreemarkerTemplateLoaderTest {
* would. * would.
*/ */
private void assertFM(String searchTerm, int expectedNumberOfTries, private void assertFM(String searchTerm, int expectedNumberOfTries,
String expectedBestFit) { String expectedBestString) {
Path expectedBestFit = expectedBestString == null ? null : Paths
.get(expectedBestString);
PathPieces stPp = new PathPieces(searchTerm); PathPieces stPp = new PathPieces(searchTerm);
int actualNumberOfTries = 0; int actualNumberOfTries = 0;
String actualBestFit = null; Path actualBestFit = null;
if (StringUtils.isNotBlank(stPp.region)) { if (StringUtils.isNotBlank(stPp.region)) {
actualNumberOfTries++; actualNumberOfTries++;
SortedSet<PathPieces> matches = runTheVisitor(stPp.base SortedSet<PathPieces> matches = runTheVisitor(stPp.base
+ stPp.language + stPp.region + stPp.extension); + stPp.language + stPp.region + stPp.extension);
if (!matches.isEmpty()) { if (!matches.isEmpty()) {
actualBestFit = matches.last().path.toString(); actualBestFit = matches.last().path;
} }
} }
if (actualBestFit == null && StringUtils.isNotBlank(stPp.language)) { if (actualBestFit == null && StringUtils.isNotBlank(stPp.language)) {
@ -305,7 +307,7 @@ public class FreemarkerTemplateLoaderTest {
SortedSet<PathPieces> matches = runTheVisitor(stPp.base SortedSet<PathPieces> matches = runTheVisitor(stPp.base
+ stPp.language + stPp.extension); + stPp.language + stPp.extension);
if (!matches.isEmpty()) { if (!matches.isEmpty()) {
actualBestFit = matches.last().path.toString(); actualBestFit = matches.last().path;
} }
} }
if (actualBestFit == null) { if (actualBestFit == null) {
@ -313,7 +315,7 @@ public class FreemarkerTemplateLoaderTest {
SortedSet<PathPieces> matches = runTheVisitor(stPp.base SortedSet<PathPieces> matches = runTheVisitor(stPp.base
+ stPp.extension); + stPp.extension);
if (!matches.isEmpty()) { if (!matches.isEmpty()) {
actualBestFit = matches.last().path.toString(); actualBestFit = matches.last().path;
} }
} }

View file

@ -493,6 +493,9 @@ restrict_logins_mixed_caps = Restrict logins
site_information = Site information site_information = Site information
user_accounts = User accounts user_accounts = User accounts
activate_developer_panel = Activate developer panel
activate_developer_panel_mixed_caps = Activate developer panel
# #
# search controller ( PagedSearchController.java ) # search controller ( PagedSearchController.java )
# #

View file

@ -1,9 +1,9 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
function DeveloperPanel(developerAjaxUrl) { function DeveloperPanel(developerAjaxUrl) {
this.setupDeveloperPanel = updateDeveloperPanel; this.setupDeveloperPanel = updateDeveloperPanel;
function updateDeveloperPanel(data) { function updateDeveloperPanel(data) {
$.ajax({ $.ajax({
url: developerAjaxUrl, url: developerAjaxUrl,
dataType: "json", dataType: "json",
@ -42,13 +42,16 @@
var developerEnabled = document.getElementById("developerEnabled").checked; var developerEnabled = document.getElementById("developerEnabled").checked;
document.getElementById("developerDefeatFreemarkerCache").disabled = !developerEnabled; document.getElementById("developerDefeatFreemarkerCache").disabled = !developerEnabled;
document.getElementById("developerInsertFreemarkerDelimiters").disabled = !developerEnabled; document.getElementById("developerInsertFreemarkerDelimiters").disabled = !developerEnabled;
document.getElementById("developerPageContentsLogCustomListView").disabled = !developerEnabled;
document.getElementById("developerPageContentsLogCustomShortView").disabled = !developerEnabled;
document.getElementById("developerI18nDefeatCache").disabled = !developerEnabled; document.getElementById("developerI18nDefeatCache").disabled = !developerEnabled;
document.getElementById("developerI18nLogStringRequests").disabled = !developerEnabled; document.getElementById("developerI18nLogStringRequests").disabled = !developerEnabled;
document.getElementById("developerLoggingRDFServiceEnable").disabled = !developerEnabled; document.getElementById("developerLoggingRDFServiceEnable").disabled = !developerEnabled;
var rdfServiceEnabled = developerEnabled && document.getElementById("developerLoggingRDFServiceEnable").checked; var rdfServiceEnabled = developerEnabled && document.getElementById("developerLoggingRDFServiceEnable").checked;
document.getElementById("developerLoggingRDFServiceStackTrace").disabled = !rdfServiceEnabled; document.getElementById("developerLoggingRDFServiceStackTrace").disabled = !rdfServiceEnabled;
document.getElementById("developerLoggingRDFServiceRestriction").disabled = !rdfServiceEnabled; document.getElementById("developerLoggingRDFServiceQueryRestriction").disabled = !rdfServiceEnabled;
document.getElementById("developerLoggingRDFServiceStackRestriction").disabled = !rdfServiceEnabled;
} }
function collectFormData() { function collectFormData() {
@ -56,11 +59,14 @@
getCheckbox("developerEnabled", data); getCheckbox("developerEnabled", data);
getCheckbox("developerDefeatFreemarkerCache", data); getCheckbox("developerDefeatFreemarkerCache", data);
getCheckbox("developerInsertFreemarkerDelimiters", data); getCheckbox("developerInsertFreemarkerDelimiters", data);
getCheckbox("developerPageContentsLogCustomListView", data);
getCheckbox("developerPageContentsLogCustomShortView", data);
getCheckbox("developerI18nDefeatCache", data); getCheckbox("developerI18nDefeatCache", data);
getCheckbox("developerI18nLogStringRequests", data); getCheckbox("developerI18nLogStringRequests", data);
getCheckbox("developerLoggingRDFServiceEnable", data); getCheckbox("developerLoggingRDFServiceEnable", data);
getCheckbox("developerLoggingRDFServiceStackTrace", data); getCheckbox("developerLoggingRDFServiceStackTrace", data);
getText("developerLoggingRDFServiceRestriction", data); getText("developerLoggingRDFServiceQueryRestriction", data);
getText("developerLoggingRDFServiceStackRestriction", data);
return data; return data;
} }
@ -79,3 +85,4 @@
$(document).ready(function() { $(document).ready(function() {
new DeveloperPanel(developerAjaxUrl).setupDeveloperPanel({}); new DeveloperPanel(developerAjaxUrl).setupDeveloperPanel({});
}); });

View file

@ -18,6 +18,10 @@
<#if indexCacheRebuild.recomputeInferences?has_content> <#if indexCacheRebuild.recomputeInferences?has_content>
<li role="listitem"><a href="${indexCacheRebuild.recomputeInferences}" title="${i18n().recompute_inferences}">${i18n().recompute_inferences_mixed_caps}</a></li> <li role="listitem"><a href="${indexCacheRebuild.recomputeInferences}" title="${i18n().recompute_inferences}">${i18n().recompute_inferences_mixed_caps}</a></li>
</#if> </#if>
<#if indexCacheRebuild.activateDeveloperPanel?has_content>
<li role="listitem"><a href="${indexCacheRebuild.activateDeveloperPanel}" title="${i18n().activate_developer_panel}">${i18n().activate_developer_panel_mixed_caps}</a></li>
</#if>
</ul> </ul>
</section> </section>
</#if> </#if>

View file

@ -6,7 +6,7 @@
</#macro> </#macro>
<#macro showTextbox key> <#macro showTextbox key>
<input type="text" id="${key}" size="40" value="${settings[key]}" > <input type="text" id="${key}" size="30" value="${settings[key]}" >
</#macro> </#macro>
@ -14,17 +14,40 @@
div.developer { div.developer {
background-color: #f7dd8a; background-color: #f7dd8a;
padding: 0px 10px 0px 10px; padding: 0px 10px 0px 10px;
font-size: small;
font-variant: small-caps; font-variant: small-caps;
} }
div.developer #developerPanelBody { div.developer #developerPanelBody {
display: none; display: none;
line-height: 1em;
font-size: small;
} }
div.developer .container { div.developer div.devleft {
border: thin groove black width: 49%
} }
div.developer div.devright {
float: right;
width: 49%
}
div.developer div.container {
border: thin groove black;
padding: 3px 10px 0px 10px;
margin: 3px 0px 3px 0px;
}
div.developer div.within {
padding-left: 1em;
}
div.developer input[type="text"] {
padding: 2px 10px 2px 10px;
line-height: 1em;
margin: 2px 2px 2px 2px;
}
</style> </style>
<#if !settings.developerEnabled> <#if !settings.developerEnabled>
@ -38,12 +61,40 @@ div.developer .container {
<span id="developerPanelClickText">(click for Options)</span> <span id="developerPanelClickText">(click for Options)</span>
</h1> </h1>
<div id="developerPanelBody"> <div id="developerPanelBody">
<form> <div>
<label> <label>
<@showCheckbox "developerEnabled" /> <@showCheckbox "developerEnabled" />
Enable developer mode Enable developer mode
</label> </label>
</div>
<div class="devright">
<div class="container">
Page configuration
<label>
<@showCheckbox "developerPageContentsLogCustomListView" />
Log the use of custom list view XML files.
</label>
<label>
<@showCheckbox "developerPageContentsLogCustomShortView" />
Log the use of custom short views in search, index and browse pages.
</label>
</div>
<div class="container">
Language support
<label>
<@showCheckbox "developerI18nDefeatCache" />
Defeat the cache of language property files
</label>
<label>
<@showCheckbox "developerI18nLogStringRequests" />
Log the retrieval of language strings
</label>
</div>
</div>
<div class="devleft">
<div class="container"> <div class="container">
Freemarker templates Freemarker templates
<label> <label>
@ -62,30 +113,26 @@ div.developer .container {
<@showCheckbox "developerLoggingRDFServiceEnable" /> <@showCheckbox "developerLoggingRDFServiceEnable" />
Log each query Log each query
</label> </label>
<label> <div class="within">
<@showCheckbox "developerLoggingRDFServiceStackTrace" /> <label>
Add stack trace <@showCheckbox "developerLoggingRDFServiceStackTrace" />
</label> Add stack trace
<label> </label>
Restrict by calling stack <label>
<@showTextbox "developerLoggingRDFServiceRestriction" /> Restrict by query string
</label> <@showTextbox "developerLoggingRDFServiceQueryRestriction" />
</div> </label>
<label>
<div class="container"> Restrict by calling stack
Language support <@showTextbox "developerLoggingRDFServiceStackRestriction" />
<label> </label>
<@showCheckbox "developerI18nDefeatCache" /> </div>
Defeat the cache of language property files
</label>
<label>
<@showCheckbox "developerI18nLogStringRequests" />
Log the retrieval of language strings
</label>
</div> </div>
</div>
<div>
<input type="button" id="developerPanelSaveButton" value="Save Settings" name="foo" /> <input type="button" id="developerPanelSaveButton" value="Save Settings" name="foo" />
</form> </div>
</div> </div>
</div> </div>
</#if> </#if>