Merge branch 'maint-rel-1.6' of https://github.com/vivo-project/Vitro into maint-rel-1.6
This commit is contained in:
commit
d30fb357bf
42 changed files with 847 additions and 404 deletions
|
@ -16,7 +16,7 @@
|
||||||
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
||||||
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
||||||
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
||||||
<auth:hasPermissionSet rdf:resource="http://permissionSet-50"/>
|
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#ADMIN"/>
|
||||||
</auth:UserAccount>
|
</auth:UserAccount>
|
||||||
|
|
||||||
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JohnCurator">
|
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JohnCurator">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
||||||
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
||||||
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
||||||
<auth:hasPermissionSet rdf:resource="http://permissionSet-5"/>
|
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#CURATOR"/>
|
||||||
</auth:UserAccount>
|
</auth:UserAccount>
|
||||||
|
|
||||||
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/SallyEditor">
|
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/SallyEditor">
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
||||||
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
||||||
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
||||||
<auth:hasPermissionSet rdf:resource="http://permissionSet-4"/>
|
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#EDITOR"/>
|
||||||
</auth:UserAccount>
|
</auth:UserAccount>
|
||||||
|
|
||||||
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JoeUser">
|
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JoeUser">
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
|
||||||
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
|
||||||
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
|
||||||
<auth:hasPermissionSet rdf:resource="http://permissionSet-1"/>
|
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#SELF_EDITOR"/>
|
||||||
</auth:UserAccount>
|
</auth:UserAccount>
|
||||||
|
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
|
|
|
@ -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 = .*
|
||||||
|
|
|
@ -444,7 +444,7 @@ please_create = Por favor, cree
|
||||||
a_classgroup = un grupo de clase
|
a_classgroup = un grupo de clase
|
||||||
associate_classes_with_group = y las clases asociadas con el grupo creado.
|
associate_classes_with_group = y las clases asociadas con el grupo creado.
|
||||||
|
|
||||||
refresh_content = Actualizar contenido
|
site_maintenance = Mantenimiento del sitio
|
||||||
rebuild_search_index = Reconstruir índice de búsqueda
|
rebuild_search_index = Reconstruir índice de búsqueda
|
||||||
rebuild_vis_cache = Reconstruir caché de visualización
|
rebuild_vis_cache = Reconstruir caché de visualización
|
||||||
recompute_inferences_mixed_caps = Inferencias Recompute
|
recompute_inferences_mixed_caps = Inferencias Recompute
|
||||||
|
|
|
@ -12,6 +12,7 @@ auth:ADMIN
|
||||||
|
|
||||||
# ADMIN-only permissions
|
# ADMIN-only permissions
|
||||||
auth:hasPermission simplePermission:AccessSpecialDataModels ;
|
auth:hasPermission simplePermission:AccessSpecialDataModels ;
|
||||||
|
auth:hasPermission simplePermission:EnableDeveloperPanel ;
|
||||||
auth:hasPermission simplePermission:LoginDuringMaintenance ;
|
auth:hasPermission simplePermission:LoginDuringMaintenance ;
|
||||||
auth:hasPermission simplePermission:ManageMenus ;
|
auth:hasPermission simplePermission:ManageMenus ;
|
||||||
auth:hasPermission simplePermission:ManageProxies ;
|
auth:hasPermission simplePermission:ManageProxies ;
|
||||||
|
@ -23,8 +24,12 @@ auth:ADMIN
|
||||||
auth:hasPermission simplePermission:UseAdvancedDataToolsPages ;
|
auth:hasPermission simplePermission:UseAdvancedDataToolsPages ;
|
||||||
auth:hasPermission simplePermission:UseMiscellaneousAdminPages ;
|
auth:hasPermission simplePermission:UseMiscellaneousAdminPages ;
|
||||||
auth:hasPermission simplePermission:UseSparqlQueryPage ;
|
auth:hasPermission simplePermission:UseSparqlQueryPage ;
|
||||||
auth:hasPermission simplePermission:PageViewableAdmin ;
|
auth:hasPermission simplePermission:PageViewableAdmin ;
|
||||||
auth:hasPermission simplePermission:EnableDeveloperPanel ;
|
|
||||||
|
# Uncomment the following permission line to enable the SPARQL update API.
|
||||||
|
# Before enabling, be sure that the URL api/sparqlUpdate is secured by SSH,
|
||||||
|
# so passwords will not be sent in clear text.
|
||||||
|
# auth:hasPermission simplePermission:UseSparqlUpdateApi ;
|
||||||
|
|
||||||
# permissions for CURATOR and above.
|
# permissions for CURATOR and above.
|
||||||
auth:hasPermission simplePermission:EditOntology ;
|
auth:hasPermission simplePermission:EditOntology ;
|
||||||
|
|
|
@ -38,6 +38,8 @@ public class SimplePermission extends Permission {
|
||||||
NAMESPACE + "EditOwnAccount");
|
NAMESPACE + "EditOwnAccount");
|
||||||
public static final SimplePermission EDIT_SITE_INFORMATION = new SimplePermission(
|
public static final SimplePermission EDIT_SITE_INFORMATION = new SimplePermission(
|
||||||
NAMESPACE + "EditSiteInformation");
|
NAMESPACE + "EditSiteInformation");
|
||||||
|
public static final SimplePermission ENABLE_DEVELOPER_PANEL = new SimplePermission(
|
||||||
|
NAMESPACE + "EnableDeveloperPanel");
|
||||||
public static final SimplePermission LOGIN_DURING_MAINTENANCE = new SimplePermission(
|
public static final SimplePermission LOGIN_DURING_MAINTENANCE = new SimplePermission(
|
||||||
NAMESPACE + "LoginDuringMaintenance");
|
NAMESPACE + "LoginDuringMaintenance");
|
||||||
public static final SimplePermission MANAGE_MENUS = new SimplePermission(
|
public static final SimplePermission MANAGE_MENUS = new SimplePermission(
|
||||||
|
@ -76,9 +78,8 @@ public class SimplePermission extends Permission {
|
||||||
NAMESPACE + "UseAdvancedDataToolsPages");
|
NAMESPACE + "UseAdvancedDataToolsPages");
|
||||||
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
|
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
|
||||||
NAMESPACE + "UseSparqlQueryPage");
|
NAMESPACE + "UseSparqlQueryPage");
|
||||||
public static final SimplePermission ENABLE_DEVELOPER_PANEL = new SimplePermission(
|
public static final SimplePermission USE_SPARQL_UPDATE_API = new SimplePermission(
|
||||||
NAMESPACE + "EnableDeveloperPanel");
|
NAMESPACE + "UseSparqlUpdateApi");
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// These instances are "catch all" permissions to cover poorly defined
|
// These instances are "catch all" permissions to cover poorly defined
|
||||||
|
|
|
@ -83,11 +83,11 @@ public class PolicyHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Authenticator basicAuth = new BasicAuthenticator(req);
|
Authenticator auth = Authenticator.getInstance(req);
|
||||||
UserAccount user = basicAuth.getAccountForInternalAuth( email );
|
UserAccount user = auth.getAccountForInternalAuth( email );
|
||||||
log.debug("userAccount is " + user==null?"null":user.getUri() );
|
log.debug("userAccount is " + user==null?"null":user.getUri() );
|
||||||
|
|
||||||
if( ! basicAuth.isCurrentPassword( user, password ) ){
|
if( ! auth.isCurrentPassword( user, password ) ){
|
||||||
log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
|
log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
|
||||||
user.getEmailAddress(), user.getUri()));
|
user.getEmailAddress(), user.getUri()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.api;
|
||||||
|
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
|
import com.hp.hpl.jena.update.GraphStore;
|
||||||
|
import com.hp.hpl.jena.update.GraphStoreFactory;
|
||||||
|
import com.hp.hpl.jena.update.UpdateAction;
|
||||||
|
import com.hp.hpl.jena.update.UpdateFactory;
|
||||||
|
import com.hp.hpl.jena.update.UpdateRequest;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This extends HttpServlet instead of VitroHttpServlet because we want to have
|
||||||
|
* full control over the response:
|
||||||
|
* <ul>
|
||||||
|
* <li>No redirecting to the login page if not authorized</li>
|
||||||
|
* <li>No redirecting to the home page on insufficient authorization</li>
|
||||||
|
* <li>No support for GET or HEAD requests, only POST.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* So these responses will be produced:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 200 Success
|
||||||
|
* 400 Failed to parse SPARQL update
|
||||||
|
* 400 SPARQL update must specify a GRAPH URI.
|
||||||
|
* 403 username/password combination is not valid
|
||||||
|
* 403 Account is not authorized
|
||||||
|
* 405 Method not allowed
|
||||||
|
* 500 Unknown error
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public class SparqlUpdateApiController extends HttpServlet {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(SparqlUpdateApiController.class);
|
||||||
|
|
||||||
|
private static final Actions REQUIRED_ACTIONS = SimplePermission.USE_SPARQL_UPDATE_API.ACTIONS;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
try {
|
||||||
|
checkAuthorization(req);
|
||||||
|
UpdateRequest parsed = parseUpdateString(req);
|
||||||
|
executeUpdate(req, parsed);
|
||||||
|
do200response(resp);
|
||||||
|
} catch (AuthException e) {
|
||||||
|
do403response(resp, e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
do400response(resp, e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
do500response(resp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAuthorization(HttpServletRequest req)
|
||||||
|
throws AuthException {
|
||||||
|
String email = req.getParameter("email");
|
||||||
|
String password = req.getParameter("password");
|
||||||
|
|
||||||
|
Authenticator auth = Authenticator.getInstance(req);
|
||||||
|
UserAccount account = auth.getAccountForInternalAuth(email);
|
||||||
|
if (!auth.isCurrentPassword(account, password)) {
|
||||||
|
log.debug("Invalid: '" + email + "'/'" + password + "'");
|
||||||
|
throw new AuthException("email/password combination is not valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PolicyHelper.isAuthorizedForActions(req, email, password,
|
||||||
|
REQUIRED_ACTIONS)) {
|
||||||
|
log.debug("Not authorized: '" + email + "'");
|
||||||
|
throw new AuthException("Account is not authorized");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Authorized for '" + email + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private UpdateRequest parseUpdateString(HttpServletRequest req)
|
||||||
|
throws ParseException {
|
||||||
|
String update = req.getParameter("update");
|
||||||
|
if (StringUtils.isBlank(update)) {
|
||||||
|
log.debug("No update parameter.");
|
||||||
|
throw new ParseException("No 'update' parameter.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.containsIgnoreCase(update, "GRAPH")) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("No GRAPH uri in '" + update + "'");
|
||||||
|
}
|
||||||
|
throw new ParseException("SPARQL update must specify a GRAPH URI.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return UpdateFactory.create(update);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Problem parsing", e);
|
||||||
|
throw new ParseException("Failed to parse SPARQL update", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeUpdate(HttpServletRequest req, UpdateRequest parsed) {
|
||||||
|
ServletContext ctx = req.getSession().getServletContext();
|
||||||
|
VitroRequest vreq = new VitroRequest(req);
|
||||||
|
|
||||||
|
IndexBuilder.getBuilder(ctx).pause();
|
||||||
|
try {
|
||||||
|
Dataset ds = new RDFServiceDataset(vreq.getUnfilteredRDFService());
|
||||||
|
GraphStore graphStore = GraphStoreFactory.create(ds);
|
||||||
|
UpdateAction.execute(parsed, graphStore);
|
||||||
|
} finally {
|
||||||
|
IndexBuilder.getBuilder(ctx).unpause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void do200response(HttpServletResponse resp) throws IOException {
|
||||||
|
doResponse(resp, SC_OK, "SPARQL update accepted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void do403response(HttpServletResponse resp, AuthException e)
|
||||||
|
throws IOException {
|
||||||
|
doResponse(resp, SC_FORBIDDEN, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void do400response(HttpServletResponse resp, ParseException e)
|
||||||
|
throws IOException {
|
||||||
|
if (e.getCause() == null) {
|
||||||
|
doResponse(resp, SC_BAD_REQUEST, e.getMessage());
|
||||||
|
} else {
|
||||||
|
doResponse(resp, SC_BAD_REQUEST, e.getMessage(), e.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void do500response(HttpServletResponse resp, Exception e)
|
||||||
|
throws IOException {
|
||||||
|
doResponse(resp, SC_INTERNAL_SERVER_ERROR, "Unknown error", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doResponse(HttpServletResponse resp, int statusCode,
|
||||||
|
String message) throws IOException {
|
||||||
|
resp.setStatus(statusCode);
|
||||||
|
PrintWriter writer = resp.getWriter();
|
||||||
|
writer.println("<H1>" + statusCode + " " + message + "</H1>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doResponse(HttpServletResponse resp, int statusCode,
|
||||||
|
String message, Throwable e) throws IOException {
|
||||||
|
resp.setStatus(statusCode);
|
||||||
|
PrintWriter writer = resp.getWriter();
|
||||||
|
writer.println("<H1>" + statusCode + " " + message + "</H1>");
|
||||||
|
writer.println("<pre>");
|
||||||
|
e.printStackTrace(writer);
|
||||||
|
writer.println("</pre>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private static class AuthException extends Exception {
|
||||||
|
private AuthException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ParseException extends Exception {
|
||||||
|
private ParseException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParseException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -53,14 +53,14 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
body.put("dataInput", getDataInputData(vreq));
|
body.put("dataInput", getDataInputData(vreq));
|
||||||
body.put("siteConfig", getSiteConfigData(vreq));
|
body.put("siteConfig", getSiteConfigData(vreq));
|
||||||
body.put("indexCacheRebuild", getIndexCacheRebuildUrls(vreq));
|
body.put("siteMaintenance", getSiteMaintenanceUrls(vreq));
|
||||||
body.put("ontologyEditor", getOntologyEditorData(vreq));
|
body.put("ontologyEditor", getOntologyEditorData(vreq));
|
||||||
body.put("dataTools", getDataToolsUrls(vreq));
|
body.put("dataTools", getDataToolsUrls(vreq));
|
||||||
|
|
||||||
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
|
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, String> getIndexCacheRebuildUrls(VitroRequest vreq) {
|
protected Map<String, String> getSiteMaintenanceUrls(VitroRequest vreq) {
|
||||||
|
|
||||||
Map<String, String> urls = new HashMap<String, String>();
|
Map<String, String> urls = new HashMap<String, String>();
|
||||||
|
|
||||||
|
@ -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.LOGIN_DURING_MAINTENANCE.ACTIONS)) {
|
||||||
|
urls.put("restrictLogins", UrlBuilder.getUrl("/admin/restrictLogins"));
|
||||||
|
}
|
||||||
|
|
||||||
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({developerEnabled: true});");
|
||||||
}
|
}
|
||||||
|
@ -147,10 +151,6 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
||||||
data.put("startupStatusAlert", !StartupStatus.getBean(getServletContext()).allClear());
|
data.put("startupStatusAlert", !StartupStatus.getBean(getServletContext()).allClear());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.LOGIN_DURING_MAINTENANCE.ACTIONS)) {
|
|
||||||
data.put("restrictLogins", UrlBuilder.getUrl("/admin/restrictLogins"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,15 +58,16 @@ public class PageController extends FreemarkerHttpServlet{
|
||||||
|
|
||||||
if( pageActs == null && dgActs == null){
|
if( pageActs == null && dgActs == null){
|
||||||
return Actions.AUTHORIZED;
|
return Actions.AUTHORIZED;
|
||||||
}else if( pageActs == null && dgActs != null ){
|
}else if( pageActs == null ){
|
||||||
return dgActs;
|
return dgActs;
|
||||||
|
}else if( dgActs == null ){
|
||||||
|
return pageActs;
|
||||||
}else{
|
}else{
|
||||||
return pageActs;
|
return pageActs.and(dgActs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO Auto-generated catch block
|
log.warn(e);
|
||||||
log.debug(e);
|
|
||||||
return Actions.UNAUTHORIZED;
|
return Actions.UNAUTHORIZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,13 +537,14 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
|
||||||
List<String> actions = new ArrayList<String>();
|
List<String> actions = new ArrayList<String>();
|
||||||
|
|
||||||
Model dModel = getOntModelSelector().getDisplayModel();
|
Model dModel = getOntModelSelector().getDisplayModel();
|
||||||
|
dModel.enterCriticalSection(false);
|
||||||
try{
|
try{
|
||||||
QueryExecution qe =
|
QueryExecution qe =
|
||||||
QueryExecutionFactory.create( requiredActionsQuery, dModel, initialBindings);
|
QueryExecutionFactory.create( requiredActionsQuery, dModel, initialBindings);
|
||||||
actions = executeQueryToList( qe );
|
actions = executeQueryToList( qe );
|
||||||
qe.close();
|
qe.close();
|
||||||
}finally{
|
}finally{
|
||||||
dModel.enterCriticalSection(false);
|
dModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.freemarker.config;
|
package edu.cornell.mannlib.vitro.webapp.freemarker.config;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -35,28 +36,52 @@ import freemarker.template.utility.DeepUnwrap;
|
||||||
* Extend the Freemarker Configuration class to include some information that is
|
* Extend the Freemarker Configuration class to include some information that is
|
||||||
* particular to the current request.
|
* particular to the current request.
|
||||||
*
|
*
|
||||||
* Takes advantage of the fact that each servlet request runs in a separate
|
* A reference to the current request is not always available to the Freemarker
|
||||||
* thread. Stores the request-based information in a ThreadLocal. Override any
|
* Configuration, so we take advantage of the fact that each request runs in a
|
||||||
* methods that should return that information instead of (or in addition to)
|
* separate thread, and store a reference to that request in a ThreadLocal
|
||||||
* the common info.
|
* object.
|
||||||
|
*
|
||||||
|
* Then, we override any methods that should return that request-based
|
||||||
|
* information instead of (or in addition to) the common info.
|
||||||
*
|
*
|
||||||
* Only the getters are overridden, not the setters. So if you call
|
* Only the getters are overridden, not the setters. So if you call
|
||||||
* setAllSharedVariables(), for example, it will have no effect on the
|
* setAllSharedVariables(), for example, it will have no effect on the
|
||||||
* request-based information.
|
* request-based information.
|
||||||
|
*
|
||||||
|
* Notice that the reference to the current request is actually stored through a
|
||||||
|
* WeakReference. This is because the ThreadLocal will not be cleared when the
|
||||||
|
* webapp is stopped, so none of the references from that ThreadLocal are
|
||||||
|
* eligible for garbage collection. If any of those references is an instance of
|
||||||
|
* a class that is loaded by the webapp, then the webapp ClassLoader is not
|
||||||
|
* eligible for garbage collection. This would be a huge memory leak.
|
||||||
|
*
|
||||||
|
* Thanks to the WeakReference, the request is eligible for garbage collection
|
||||||
|
* if nothing else refers to it. In theory, this means that the WeakReference
|
||||||
|
* could return a null, but if the garbage collector has taken the request, then
|
||||||
|
* who is invoking this object?
|
||||||
*/
|
*/
|
||||||
public class FreemarkerConfigurationImpl extends Configuration {
|
public class FreemarkerConfigurationImpl extends Configuration {
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory
|
||||||
.getLog(FreemarkerConfigurationImpl.class);
|
.getLog(FreemarkerConfigurationImpl.class);
|
||||||
|
|
||||||
private final ThreadLocal<RequestBasedInformation> rbiRef = new ThreadLocal<>();
|
private static final String ATTRIBUTE_NAME = RequestBasedInformation.class
|
||||||
|
.getName();
|
||||||
|
|
||||||
|
private final ThreadLocal<WeakReference<HttpServletRequest>> reqRef = new ThreadLocal<>();
|
||||||
|
|
||||||
void setRequestInfo(HttpServletRequest req) {
|
void setRequestInfo(HttpServletRequest req) {
|
||||||
rbiRef.set(new RequestBasedInformation(req, this));
|
reqRef.set(new WeakReference<>(req));
|
||||||
|
req.setAttribute(ATTRIBUTE_NAME, new RequestBasedInformation(req, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestBasedInformation getRequestInfo() {
|
||||||
|
HttpServletRequest req = reqRef.get().get();
|
||||||
|
return (RequestBasedInformation) req.getAttribute(ATTRIBUTE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getCustomAttribute(String name) {
|
public Object getCustomAttribute(String name) {
|
||||||
Map<String, Object> attribs = rbiRef.get().getCustomAttributes();
|
Map<String, Object> attribs = getRequestInfo().getCustomAttributes();
|
||||||
if (attribs.containsKey(name)) {
|
if (attribs.containsKey(name)) {
|
||||||
return attribs.get(name);
|
return attribs.get(name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -66,13 +91,13 @@ public class FreemarkerConfigurationImpl extends Configuration {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getCustomAttributeNames() {
|
public String[] getCustomAttributeNames() {
|
||||||
Set<String> rbiNames = rbiRef.get().getCustomAttributes().keySet();
|
Set<String> rbiNames = getRequestInfo().getCustomAttributes().keySet();
|
||||||
return joinNames(rbiNames, super.getCustomAttributeNames());
|
return joinNames(rbiNames, super.getCustomAttributeNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TemplateModel getSharedVariable(String name) {
|
public TemplateModel getSharedVariable(String name) {
|
||||||
Map<String, TemplateModel> vars = rbiRef.get().getSharedVariables();
|
Map<String, TemplateModel> vars = getRequestInfo().getSharedVariables();
|
||||||
if (vars.containsKey(name)) {
|
if (vars.containsKey(name)) {
|
||||||
return vars.get(name);
|
return vars.get(name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,7 +107,7 @@ public class FreemarkerConfigurationImpl extends Configuration {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getSharedVariableNames() {
|
public Set<String> getSharedVariableNames() {
|
||||||
Set<String> rbiNames = rbiRef.get().getSharedVariables().keySet();
|
Set<String> rbiNames = getRequestInfo().getSharedVariables().keySet();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<String> superNames = super.getSharedVariableNames();
|
Set<String> superNames = super.getSharedVariableNames();
|
||||||
|
@ -94,7 +119,7 @@ public class FreemarkerConfigurationImpl extends Configuration {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return rbiRef.get().getReq().getLocale();
|
return getRequestInfo().getReq().getLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] joinNames(Set<String> nameSet, String[] nameArray) {
|
private String[] joinNames(Set<String> nameSet, String[] nameArray) {
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -276,7 +285,7 @@ public class FreemarkerTemplateLoader implements TemplateLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean fileQualifies(Path path) {
|
public boolean fileQualifies(Path path) {
|
||||||
return Files.isRegularFile(path) && Files.isReadable(path);
|
return Files.isReadable(path) && !Files.isDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<PathPieces> getMatches() {
|
public SortedSet<PathPieces> getMatches() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -14,7 +15,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
||||||
import org.apache.commons.httpclient.NameValuePair;
|
import org.apache.commons.httpclient.NameValuePair;
|
||||||
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
|
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -38,6 +41,7 @@ import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
|
import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
|
||||||
|
@ -84,11 +88,11 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
|
||||||
this.readRepository = new HTTPRepository(readEndpointURI);
|
this.readRepository = new HTTPRepository(readEndpointURI);
|
||||||
this.updateRepository = new HTTPRepository(updateEndpointURI);
|
this.updateRepository = new HTTPRepository(updateEndpointURI);
|
||||||
|
|
||||||
testConnection();
|
|
||||||
|
|
||||||
MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
|
MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
|
||||||
mgr.getParams().setDefaultMaxConnectionsPerHost(10);
|
mgr.getParams().setDefaultMaxConnectionsPerHost(50);
|
||||||
this.httpClient = new HttpClient(mgr);
|
this.httpClient = new HttpClient(mgr);
|
||||||
|
|
||||||
|
testConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testConnection() {
|
private void testConnection() {
|
||||||
|
@ -278,13 +282,28 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InputStream sparqlSelectQuery(String queryStr, RDFService.ResultFormat resultFormat) throws RDFServiceException {
|
public InputStream sparqlSelectQuery(String queryStr, RDFService.ResultFormat resultFormat) throws RDFServiceException {
|
||||||
|
|
||||||
Query query = createQuery(queryStr);
|
//QueryEngineHTTP qh = new QueryEngineHTTP(readEndpointURI, queryStr);
|
||||||
QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query);
|
|
||||||
|
GetMethod meth = new GetMethod(readEndpointURI);
|
||||||
try {
|
try {
|
||||||
ResultSet resultSet = qe.execSelect();
|
meth.addRequestHeader("Accept", "application/sparql-results+xml");
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
NameValuePair param = new NameValuePair();
|
||||||
|
param.setName("query");
|
||||||
|
param.setValue(queryStr);
|
||||||
|
NameValuePair[] params = new NameValuePair[1];
|
||||||
|
params[0] = param;
|
||||||
|
meth.setQueryString(params);
|
||||||
|
int response = httpClient.executeMethod(meth);
|
||||||
|
if (response > 399) {
|
||||||
|
log.error("response " + response + " to query. \n");
|
||||||
|
log.debug("update string: \n" + queryStr);
|
||||||
|
throw new RDFServiceException("Unable to perform SPARQL UPDATE");
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream in = meth.getResponseBodyAsStream();
|
||||||
|
ResultSet resultSet = ResultSetFactory.fromXML(in);
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
switch (resultFormat) {
|
switch (resultFormat) {
|
||||||
case CSV:
|
case CSV:
|
||||||
|
@ -301,12 +320,14 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RDFServiceException("unrecognized result format");
|
throw new RDFServiceException("unrecognized result format");
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream result = new ByteArrayInputStream(outputStream.toByteArray());
|
InputStream result = new ByteArrayInputStream(outputStream.toByteArray());
|
||||||
return result;
|
return result;
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new RuntimeException(ioe);
|
||||||
} finally {
|
} finally {
|
||||||
qe.close();
|
//qh.close();
|
||||||
|
meth.releaseConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +495,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
|
||||||
int response = httpClient.executeMethod(meth);
|
int response = httpClient.executeMethod(meth);
|
||||||
if (response > 399) {
|
if (response > 399) {
|
||||||
log.error("response " + response + " to update. \n");
|
log.error("response " + response + " to update. \n");
|
||||||
log.debug("update string: \n" + updateString);
|
//log.debug("update string: \n" + updateString);
|
||||||
throw new RDFServiceException("Unable to perform SPARQL UPDATE");
|
throw new RDFServiceException("Unable to perform SPARQL UPDATE");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,44 +1,57 @@
|
||||||
/* $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$ */
|
||||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument.DONT_EXCLUDE;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
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.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exclude individuals with types from the Vitro namespace from the
|
* Exclude individuals with most specific types from the Vitro namespace from
|
||||||
* search index. (Other than old vitro Flag types).
|
* the search index. (Other than old vitro Flag types).
|
||||||
*/
|
*/
|
||||||
public class ExcludeNonFlagVitro implements SearchIndexExcluder {
|
public class ExcludeNonFlagVitro implements SearchIndexExcluder {
|
||||||
|
private static final Log log = LogFactory.getLog(ExcludeNonFlagVitro.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String checkForExclusion(Individual ind) {
|
public String checkForExclusion(Individual ind) {
|
||||||
if( ind != null && ind.getVClasses() != null ) {
|
if (ind == null) {
|
||||||
String excludeMsg = skipIfVitro(ind, ind.getVClasses() );
|
return DONT_EXCLUDE;
|
||||||
if( excludeMsg != null)
|
}
|
||||||
return excludeMsg;
|
|
||||||
}
|
List<String> mostSpecificTypeUris = ind.getMostSpecificTypeURIs();
|
||||||
return null;
|
if (mostSpecificTypeUris == null) {
|
||||||
}
|
return DONT_EXCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = skipIfVitro(ind, mostSpecificTypeUris);
|
||||||
|
if (!StringUtils.equals(DONT_EXCLUDE, message)) {
|
||||||
|
log.debug("msg=" + message + ", individual=" + ind.getURI() + " ("
|
||||||
|
+ ind.getLabel() + "), types=" + mostSpecificTypeUris);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
String skipIfVitro(Individual ind, List<String> mostSpecificTypeUris) {
|
||||||
|
for (String typeUri : mostSpecificTypeUris) {
|
||||||
|
if (typeUri == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (typeUri.startsWith(VitroVocabulary.vitroURI + "Flag")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (typeUri.startsWith(VitroVocabulary.vitroURI)) {
|
||||||
|
return "Skipped " + ind.getURI() + " because in "
|
||||||
|
+ VitroVocabulary.vitroURI + " namespace";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DONT_EXCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
String skipIfVitro(Individual ind, List<VClass> vclasses) {
|
|
||||||
for( VClass type: vclasses ){
|
|
||||||
if( type != null && type.getURI() != null ){
|
|
||||||
String typeURI = type.getURI();
|
|
||||||
|
|
||||||
if(typeURI.startsWith( VitroVocabulary.vitroURI )
|
|
||||||
&& ! typeURI.startsWith(VitroVocabulary.vitroURI + "Flag") ){
|
|
||||||
|
|
||||||
return "Skipped " + ind.getURI()+" because in "
|
|
||||||
+ VitroVocabulary.vitroURI + " namespace";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,9 @@ public class IndividualToSolrDocument {
|
||||||
for( SearchIndexExcluder excluder : excludes){
|
for( SearchIndexExcluder excluder : excludes){
|
||||||
try{
|
try{
|
||||||
String msg = excluder.checkForExclusion(ind);
|
String msg = excluder.checkForExclusion(ind);
|
||||||
|
log.debug("individual=" + ind.getURI() + " (" + ind.getLabel()
|
||||||
|
+ "), excluder=" + excluder + ", types="
|
||||||
|
+ ind.getMostSpecificTypeURIs() + ", msg=" + msg);
|
||||||
if( msg != DONT_EXCLUDE)
|
if( msg != DONT_EXCLUDE)
|
||||||
return msg;
|
return msg;
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,8 @@ public class ThemeInfoSetup implements ServletContextListener {
|
||||||
|
|
||||||
ApplicationBean.themeInfo = new ThemeInfo(themesBaseDir,
|
ApplicationBean.themeInfo = new ThemeInfo(themesBaseDir,
|
||||||
defaultThemeName, themeNames);
|
defaultThemeName, themeNames);
|
||||||
ss.info(this, ", current theme: " + currentThemeName
|
ss.info(this, "current theme: " + currentThemeName
|
||||||
+ "default theme: " + defaultThemeName + ", available themes: "
|
+ ", default theme: " + defaultThemeName + ", available themes: "
|
||||||
+ themeNames);
|
+ themeNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.query.Dataset;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.update.GraphStore;
|
|
||||||
import com.hp.hpl.jena.update.GraphStoreFactory;
|
|
||||||
import com.hp.hpl.jena.update.UpdateAction;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequiresActions;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a SPARQL Update request. This uses Jena ARQ and the RDFServiceDataset to
|
|
||||||
* evaluate a SPARQL Update with the RDFService.
|
|
||||||
*
|
|
||||||
* The reason to make this a DataGettere was to allow configuration in RDF of this
|
|
||||||
* service.
|
|
||||||
*/
|
|
||||||
public class SparqlUpdate implements DataGetter, RequiresActions{
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(SparqlUpdate.class);
|
|
||||||
|
|
||||||
VitroRequest vreq;
|
|
||||||
ServletContext context;
|
|
||||||
|
|
||||||
public SparqlUpdate(
|
|
||||||
VitroRequest vreq, Model displayModel, String dataGetterURI ) {
|
|
||||||
if( vreq == null )
|
|
||||||
throw new IllegalArgumentException("VitroRequest may not be null.");
|
|
||||||
this.vreq = vreq;
|
|
||||||
this.context = vreq.getSession().getServletContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the update from the request and then executes it on
|
|
||||||
* the RDFService.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String,Object> getData( Map<String, Object> valueMap ) {
|
|
||||||
HashMap<String, Object> data = new HashMap<String,Object>();
|
|
||||||
|
|
||||||
String update = vreq.getParameter("update");
|
|
||||||
|
|
||||||
if( update != null && !update.trim().isEmpty()){
|
|
||||||
try{
|
|
||||||
IndexBuilder.getBuilder(context).pause();
|
|
||||||
Dataset ds = new RDFServiceDataset( vreq.getUnfilteredRDFService() );
|
|
||||||
GraphStore graphStore = GraphStoreFactory.create(ds);
|
|
||||||
log.warn("The SPARQL update is '"+vreq.getParameter("update")+"'");
|
|
||||||
UpdateAction.parseExecute( vreq.getParameter("update") , graphStore );
|
|
||||||
}finally{
|
|
||||||
IndexBuilder.getBuilder(context).unpause();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
data.put("bodyTemplate", "page-sparqlUpdateTest.ftl");
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this request is authorized by the email/password.
|
|
||||||
* If not do normal authorization.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Actions requiredActions(VitroRequest vreq) {
|
|
||||||
String email = vreq.getParameter("email");
|
|
||||||
String password = vreq.getParameter("password");
|
|
||||||
|
|
||||||
boolean isAuth = PolicyHelper.isAuthorizedForActions(vreq,
|
|
||||||
email, password, SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS);
|
|
||||||
|
|
||||||
if( isAuth )
|
|
||||||
return Actions.AUTHORIZED;
|
|
||||||
else
|
|
||||||
return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -82,9 +82,29 @@ 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;
|
||||||
private final boolean bool;
|
private final boolean bool;
|
||||||
|
@ -159,7 +179,7 @@ public class DeveloperSettings {
|
||||||
// The factory
|
// The factory
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private static final String ATTRIBUTE_NAME = DeveloperSettings.class
|
protected static final String ATTRIBUTE_NAME = DeveloperSettings.class
|
||||||
.getName();
|
.getName();
|
||||||
|
|
||||||
public static DeveloperSettings getBean(HttpServletRequest req) {
|
public static DeveloperSettings getBean(HttpServletRequest req) {
|
||||||
|
@ -183,7 +203,7 @@ public class DeveloperSettings {
|
||||||
|
|
||||||
private final Map<Keys, Object> settings = new EnumMap<>(Keys.class);
|
private final Map<Keys, Object> settings = new EnumMap<>(Keys.class);
|
||||||
|
|
||||||
private DeveloperSettings(ServletContext ctx) {
|
protected DeveloperSettings(ServletContext ctx) {
|
||||||
updateFromFile(ctx);
|
updateFromFile(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
|
|
||||||
// save applicable ranges before deduping to filter later
|
// save applicable ranges before deduping to filter later
|
||||||
populatedObjectPropertyList = dedupe(populatedObjectPropertyList);
|
populatedObjectPropertyList = dedupe(populatedObjectPropertyList);
|
||||||
|
|
||||||
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
|
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
|
||||||
.getAdditionalFauxSubpropertiesForList(
|
.getAdditionalFauxSubpropertiesForList(
|
||||||
populatedObjectPropertyList, subject, vreq);
|
populatedObjectPropertyList, subject, vreq);
|
||||||
|
@ -121,13 +121,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
if (editing) {
|
if (editing) {
|
||||||
mergeAllPossibleDataProperties(propertyList);
|
mergeAllPossibleDataProperties(propertyList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not currently necessary since the language-specific version is now added
|
|
||||||
// during the merge
|
|
||||||
// if (editing) {
|
|
||||||
// propertyList = correctLanguageForProperties(propertyList);
|
|
||||||
// }
|
|
||||||
|
|
||||||
sort(propertyList);
|
sort(propertyList);
|
||||||
|
|
||||||
// Put the list into groups
|
// Put the list into groups
|
||||||
|
@ -176,35 +170,6 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
return filteredAdditions;
|
return filteredAdditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the language-filtering WebappDaoFactory to get the right version of
|
|
||||||
// each property. When editing, the methods that add to the property list
|
|
||||||
// are blissfully (and intentionally) language-unaware.
|
|
||||||
private List<Property> correctLanguageForProperties(List<Property> properties) {
|
|
||||||
List<Property> languageCorrectedProps = new ArrayList<Property>();
|
|
||||||
for (Property p : properties) {
|
|
||||||
Property correctedProp = null;
|
|
||||||
if (p instanceof ObjectProperty) {
|
|
||||||
ObjectProperty op = (ObjectProperty) p;
|
|
||||||
correctedProp = wdf.getObjectPropertyDao()
|
|
||||||
.getObjectPropertyByURIs(op.getURI(),
|
|
||||||
op.getDomainVClassURI(), op.getRangeVClassURI());
|
|
||||||
} else if (p instanceof DataProperty) {
|
|
||||||
correctedProp = wdf.getDataPropertyDao()
|
|
||||||
.getDataPropertyByURI(((DataProperty) p).getURI());
|
|
||||||
} else {
|
|
||||||
log.warn("Ignoring " + p.getURI() + " which is neither an " +
|
|
||||||
"ObjectProperty nor a DatatypeProperty.");
|
|
||||||
}
|
|
||||||
if (correctedProp != null) {
|
|
||||||
languageCorrectedProps.add(correctedProp);
|
|
||||||
} else {
|
|
||||||
log.error("Unable to retrieve property " + p.getURI() +
|
|
||||||
" using the WebappDaoFactory associated with the request.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return languageCorrectedProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's possible that an object property retrieved in the call to getPopulatedObjectPropertyList()
|
// It's possible that an object property retrieved in the call to getPopulatedObjectPropertyList()
|
||||||
// is now empty of statements, because if not editing, some statements without a linked individual
|
// is now empty of statements, because if not editing, some statements without a linked individual
|
||||||
// are not retrieved by the query. (See <linked-individual-required> elements in queries.)
|
// are not retrieved by the query. (See <linked-individual-required> elements in queries.)
|
||||||
|
@ -281,16 +246,17 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boolean addToList = true;
|
boolean addToList = true;
|
||||||
int opIndex = 0;
|
|
||||||
for(ObjectProperty op : populatedObjectPropertyList) {
|
for(ObjectProperty op : populatedObjectPropertyList) {
|
||||||
if(redundant(op, piOp)) {
|
RedundancyReason reason = redundant(op, piOp);
|
||||||
|
if(reason != null) {
|
||||||
addToList = false;
|
addToList = false;
|
||||||
if (moreRestrictiveRange(piOp, op, wadf)) {
|
if (reason == RedundancyReason.LABEL_AND_URI_MATCH
|
||||||
propertyList = replaceOpWithPiOpInList(piOp, op, opIndex, propertyList);
|
&& moreRestrictiveRange(piOp, op, wadf)) {
|
||||||
|
op.setRangeVClassURI(piOp.getRangeVClassURI());
|
||||||
|
op.setRangeVClass(piOp.getRangeVClass());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
opIndex++;
|
|
||||||
}
|
}
|
||||||
if(addToList) {
|
if(addToList) {
|
||||||
propertyList.add(piOp);
|
propertyList.add(piOp);
|
||||||
|
@ -315,6 +281,10 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
return propertyList;
|
return propertyList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum RedundancyReason {
|
||||||
|
LABEL_AND_URI_MATCH, LABEL_URI_DOMAIN_AND_RANGE_MATCH
|
||||||
|
}
|
||||||
|
|
||||||
private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
|
private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
|
||||||
WebappDaoFactory wadf) {
|
WebappDaoFactory wadf) {
|
||||||
if(piOp.getRangeVClassURI() == null) {
|
if(piOp.getRangeVClassURI() == null) {
|
||||||
|
@ -327,25 +297,9 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Property> replaceOpWithPiOpInList(ObjectProperty piOp,
|
private RedundancyReason redundant(ObjectProperty op, ObjectProperty op2) {
|
||||||
ObjectProperty op, int opIndex, List<Property> propertyList) {
|
|
||||||
|
|
||||||
List<Property> returnList = new ArrayList<Property>();
|
|
||||||
int index = 0;
|
|
||||||
for(Property p : propertyList) {
|
|
||||||
if(index == opIndex /* p.equals(op) */) {
|
|
||||||
returnList.add(piOp);
|
|
||||||
} else {
|
|
||||||
returnList.add(p);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
return returnList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean redundant(ObjectProperty op, ObjectProperty op2) {
|
|
||||||
if (op2.getURI() == null) {
|
if (op2.getURI() == null) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
boolean uriMatches = (op.getURI() != null
|
boolean uriMatches = (op.getURI() != null
|
||||||
&& op.getURI().equals(op2.getURI()));
|
&& op.getURI().equals(op2.getURI()));
|
||||||
|
@ -360,7 +314,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
labelMatches = true;
|
labelMatches = true;
|
||||||
}
|
}
|
||||||
if(uriMatches && labelMatches) {
|
if(uriMatches && labelMatches) {
|
||||||
return true;
|
return RedundancyReason.LABEL_AND_URI_MATCH;
|
||||||
}
|
}
|
||||||
if(op.getDomainVClassURI() == null) {
|
if(op.getDomainVClassURI() == null) {
|
||||||
if(op2.getDomainVClassURI() == null) {
|
if(op2.getDomainVClassURI() == null) {
|
||||||
|
@ -377,9 +331,9 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
rangeMatches = true;
|
rangeMatches = true;
|
||||||
}
|
}
|
||||||
if (uriMatches && domainMatches && rangeMatches) {
|
if (uriMatches && domainMatches && rangeMatches) {
|
||||||
return true;
|
return RedundancyReason.LABEL_URI_DOMAIN_AND_RANGE_MATCH;
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,
|
private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,
|
||||||
|
|
|
@ -9,6 +9,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.auth.policy.PolicyHelper;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
@ -50,8 +51,15 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel {
|
||||||
properties.add(tm);
|
properties.add(tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (p instanceof DataProperty){
|
||||||
|
DataProperty dp = (DataProperty) p;
|
||||||
|
RequestedAction dop = new DisplayDataProperty(dp);
|
||||||
|
if (!PolicyHelper.isAuthorizedForActions(vreq, dop)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
properties.add(new DataPropertyTemplateModel(dp, subject, vreq, editing, populatedDataPropertyList));
|
||||||
} else {
|
} else {
|
||||||
properties.add(new DataPropertyTemplateModel((DataProperty)p, subject, vreq, editing, populatedDataPropertyList));
|
log.debug(p.getURI() + " is neither an ObjectProperty nor a DataProperty; skipping display");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,14 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
||||||
|
|
||||||
|
@ -94,6 +97,27 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
||||||
|
|
||||||
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
|
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
|
||||||
verboseDisplay.put("propertyEditUrl", editUrl);
|
verboseDisplay.put("propertyEditUrl", editUrl);
|
||||||
|
|
||||||
|
if(isFauxProperty(property)) {
|
||||||
|
verboseDisplay.put("fauxProperty", "true");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFauxProperty(Property prop) {
|
||||||
|
if(!(prop instanceof ObjectProperty)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ObjectPropertyDao opDao = vreq.getWebappDaoFactory().getObjectPropertyDao();
|
||||||
|
ObjectProperty baseProp = opDao.getObjectPropertyByURI(prop.getURI());
|
||||||
|
if(baseProp == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ObjectProperty possibleFaux = (ObjectProperty) prop;
|
||||||
|
if (possibleFaux.getDomainPublic() == null) {
|
||||||
|
return (baseProp.getDomainPublic() != null);
|
||||||
|
} else {
|
||||||
|
return !possibleFaux.getDomainPublic().equals(baseProp.getDomainPublic());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract int getPropertyDisplayTier(Property p);
|
protected abstract int getPropertyDisplayTier(Property p);
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* $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,6 +21,8 @@ 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.
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +38,11 @@ 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.");
|
||||||
|
|
|
@ -1025,6 +1025,16 @@
|
||||||
<url-pattern>/admin/sparqlquery</url-pattern>
|
<url-pattern>/admin/sparqlquery</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>SparqlUpdateApi</servlet-name>
|
||||||
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.api.SparqlUpdateApiController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>SparqlUpdateApi</servlet-name>
|
||||||
|
<url-pattern>/api/sparqlUpdate</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>primitiveRdfEdit</servlet-name>
|
<servlet-name>primitiveRdfEdit</servlet-name>
|
||||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.PrimitiveRdfEdit</servlet-class>
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.PrimitiveRdfEdit</servlet-class>
|
||||||
|
|
48
webapp/web/css/developer/developerPanel.css
Normal file
48
webapp/web/css/developer/developerPanel.css
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
/* Styles for the developer panel. */
|
||||||
|
|
||||||
|
div.developer {
|
||||||
|
background-color: #f7dd8a;
|
||||||
|
padding: 0px 10px 0px 10px;
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer #developerPanelBody {
|
||||||
|
display: none;
|
||||||
|
line-height: 1em;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer div.devleft {
|
||||||
|
width: 49%
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer div.devright {
|
||||||
|
float: right;
|
||||||
|
width: 49%
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer div.container {
|
||||||
|
border: thin groove black;
|
||||||
|
padding: 3px 10px 3px 10px;
|
||||||
|
margin: 3px 0px 3px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer div.within {
|
||||||
|
padding-left: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer input[type="text"] {
|
||||||
|
padding: 2px 10px 2px 10px;
|
||||||
|
line-height: 1em;
|
||||||
|
margin: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer input[type="text"]:disabled {
|
||||||
|
background-color: #f8eeae;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.developer a {
|
||||||
|
margin: 3px;
|
||||||
|
}
|
|
@ -456,7 +456,7 @@ please_create = Please create
|
||||||
a_classgroup = a class group
|
a_classgroup = a class group
|
||||||
associate_classes_with_group = and associate classes with the group created.
|
associate_classes_with_group = and associate classes with the group created.
|
||||||
|
|
||||||
refresh_content = Refresh Content
|
site_maintenance = Site Maintenance
|
||||||
rebuild_search_index = Rebuild search index
|
rebuild_search_index = Rebuild search index
|
||||||
rebuild_vis_cache = Rebuild visualization cache
|
rebuild_vis_cache = Rebuild visualization cache
|
||||||
recompute_inferences_mixed_caps = Recompute inferences
|
recompute_inferences_mixed_caps = Recompute inferences
|
||||||
|
|
|
@ -42,13 +42,16 @@ function DeveloperPanel(developerAjaxUrl) {
|
||||||
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 @@ function DeveloperPanel(developerAjaxUrl) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,20 +13,16 @@ $(document).ready(function(){
|
||||||
jQuery('section#flash-message').css('display', 'none').fadeIn(1500);
|
jQuery('section#flash-message').css('display', 'none').fadeIn(1500);
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Home search fiter
|
// Home search filter
|
||||||
// Toggle filter select list
|
// Toggle filter select list
|
||||||
var $searchFilterList = $('#filter-search-nav');
|
var $searchFilterList = $('#filter-search-nav');
|
||||||
var $isFilterOpen = false;
|
var $isFilterOpen = false;
|
||||||
|
|
||||||
console.log("Filter is open = " + $isFilterOpen);
|
|
||||||
|
|
||||||
$('a.filter-search').click(function(e) {
|
$('a.filter-search').click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!$isFilterOpen) {
|
if (!$isFilterOpen) {
|
||||||
|
|
||||||
console.log("Filter is closed = " + $isFilterOpen);
|
|
||||||
|
|
||||||
//Change button filter state to selected
|
//Change button filter state to selected
|
||||||
//$(this).css('background','url(../../themes/vivo-cornell/images/filteredSearchActive.gif) no-repeat right top');
|
//$(this).css('background','url(../../themes/vivo-cornell/images/filteredSearchActive.gif) no-repeat right top');
|
||||||
$(this).removeClass('filter-default');
|
$(this).removeClass('filter-default');
|
||||||
|
@ -37,7 +33,6 @@ $(document).ready(function(){
|
||||||
|
|
||||||
$isFilterOpen = true;
|
$isFilterOpen = true;
|
||||||
|
|
||||||
console.log("open");
|
|
||||||
} else {
|
} else {
|
||||||
//Change button filter state to default
|
//Change button filter state to default
|
||||||
//$('a.filter-search').css('background','url(../../themes/vivo-cornell/images/filteredSearch.gif) no-repeat right top');
|
//$('a.filter-search').css('background','url(../../themes/vivo-cornell/images/filteredSearch.gif) no-repeat right top');
|
||||||
|
@ -49,7 +44,6 @@ $(document).ready(function(){
|
||||||
|
|
||||||
$isFilterOpen = false;
|
$isFilterOpen = false;
|
||||||
|
|
||||||
console.log("closed");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -63,7 +57,6 @@ $(document).ready(function(){
|
||||||
//Selected filter feedback
|
//Selected filter feedback
|
||||||
$('.search-filter-selected').text('');
|
$('.search-filter-selected').text('');
|
||||||
$('input[name="classgroup"]').val('');
|
$('input[name="classgroup"]').val('');
|
||||||
console.log("ALL");
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$('.search-filter-selected').text($(this).text()).fadeIn('slow');
|
$('.search-filter-selected').text($(this).text()).fadeIn('slow');
|
||||||
|
@ -110,6 +103,5 @@ $(document).ready(function(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("HIDE input value ") ;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<h3>SPARQL Update Test</h3>
|
|
||||||
|
|
||||||
<p>This is an expermental SPARQL update service.</p>
|
|
||||||
|
|
||||||
<form action="${urls.base}/sparqlUpdateTest" method="post">
|
|
||||||
<p>
|
|
||||||
<textarea name="update" rows="20" cols="80" ></textarea>
|
|
||||||
<input type="submit" />
|
|
||||||
</p>
|
|
||||||
</form>
|
|
|
@ -1,27 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Template for the main Site Administration page -->
|
|
||||||
|
|
||||||
<#if indexCacheRebuild?has_content>
|
|
||||||
<section class="pageBodyGroup indexCacheRebuild" role="region">
|
|
||||||
<h3>${i18n().refresh_content}</h3>
|
|
||||||
|
|
||||||
<ul role="navigation">
|
|
||||||
<#if indexCacheRebuild.rebuildSearchIndex?has_content>
|
|
||||||
<li role="listitem"><a href="${indexCacheRebuild.rebuildSearchIndex }" title="${i18n().rebuild_search_index}">${i18n().rebuild_search_index}</a></li>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
<#if indexCacheRebuild.rebuildVisCache?has_content>
|
|
||||||
<li role="listitem"><a href="${indexCacheRebuild.rebuildVisCache}" title="${i18n().rebuild_vis_cache}">${i18n().rebuild_vis_cache}</a></li>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
<#if indexCacheRebuild.recomputeInferences?has_content>
|
|
||||||
<li role="listitem"><a href="${indexCacheRebuild.recomputeInferences}" title="${i18n().recompute_inferences}">${i18n().recompute_inferences_mixed_caps}</a></li>
|
|
||||||
</#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>
|
|
||||||
</section>
|
|
||||||
</#if>
|
|
|
@ -13,5 +13,5 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/admin.css" />')
|
||||||
<#include "siteAdmin-siteConfiguration.ftl">
|
<#include "siteAdmin-siteConfiguration.ftl">
|
||||||
<#include "siteAdmin-ontologyEditor.ftl">
|
<#include "siteAdmin-ontologyEditor.ftl">
|
||||||
<#include "siteAdmin-advancedDataTools.ftl">
|
<#include "siteAdmin-advancedDataTools.ftl">
|
||||||
<#include "siteAdmin-indexCacheRebuild.ftl">
|
<#include "siteAdmin-siteMaintenance.ftl">
|
||||||
</div>
|
</div>
|
|
@ -23,10 +23,6 @@
|
||||||
<li role="listitem"><a href="${siteConfig.menuManagement}" title="${i18n().menu_ordering}">${i18n().menu_ordering_mixed_caps}</a></li>
|
<li role="listitem"><a href="${siteConfig.menuManagement}" title="${i18n().menu_ordering}">${i18n().menu_ordering_mixed_caps}</a></li>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if siteConfig.restrictLogins?has_content>
|
|
||||||
<li role="listitem"><a href="${siteConfig.restrictLogins}" title="${i18n().restrict_logins}">${i18n().restrict_logins_mixed_caps}</a></li>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
<#if siteConfig.siteInfo?has_content>
|
<#if siteConfig.siteInfo?has_content>
|
||||||
<li role="listitem"><a href="${siteConfig.siteInfo}" title="${i18n().site_information}">${i18n().site_information}</a></li>
|
<li role="listitem"><a href="${siteConfig.siteInfo}" title="${i18n().site_information}">${i18n().site_information}</a></li>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#-- Template for the main Site Administration page -->
|
||||||
|
|
||||||
|
<#if siteMaintenance?has_content>
|
||||||
|
<section class="pageBodyGroup" role="region">
|
||||||
|
<h3>${i18n().site_maintenance}</h3>
|
||||||
|
|
||||||
|
<ul role="navigation">
|
||||||
|
<#if siteMaintenance.rebuildSearchIndex?has_content>
|
||||||
|
<li role="listitem"><a href="${siteMaintenance.rebuildSearchIndex }" title="${i18n().rebuild_search_index}">${i18n().rebuild_search_index}</a></li>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if siteMaintenance.rebuildVisCache?has_content>
|
||||||
|
<li role="listitem"><a href="${siteMaintenance.rebuildVisCache}" title="${i18n().rebuild_vis_cache}">${i18n().rebuild_vis_cache}</a></li>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if siteMaintenance.recomputeInferences?has_content>
|
||||||
|
<li role="listitem"><a href="${siteMaintenance.recomputeInferences}" title="${i18n().recompute_inferences}">${i18n().recompute_inferences_mixed_caps}</a></li>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if siteMaintenance.restrictLogins?has_content>
|
||||||
|
<li role="listitem"><a href="${siteMaintenance.restrictLogins}" title="${i18n().restrict_logins}">${i18n().restrict_logins_mixed_caps}</a></li>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if siteMaintenance.activateDeveloperPanel?has_content>
|
||||||
|
<li role="listitem"><a href="${siteMaintenance.activateDeveloperPanel}" title="${i18n().activate_developer_panel}">${i18n().activate_developer_panel_mixed_caps}</a></li>
|
||||||
|
</#if>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</#if>
|
|
@ -142,7 +142,7 @@ name will be used as the label. -->
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro showAddLink propertyLocalName label url rangeUri domainUri="">
|
<#macro showAddLink propertyLocalName label url rangeUri domainUri="">
|
||||||
<#if (rangeUri?contains("Authorship") && domainUri?contains("IAO_0000030")) || (rangeUri?contains("Editorship") && domainUri?contains("IAO_0000030"))|| rangeUri?contains("URL") || label == "hasResearchArea">
|
<#if (rangeUri?contains("Authorship") && domainUri?contains("IAO_0000030")) || (rangeUri?contains("Editorship") && domainUri?contains("IAO_0000030"))|| rangeUri?contains("URL") || propertyLocalName == "hasResearchArea">
|
||||||
<a class="add-${propertyLocalName}" href="${url}" title="${i18n().manage_list_of} ${label?lower_case}">
|
<a class="add-${propertyLocalName}" href="${url}" title="${i18n().manage_list_of} ${label?lower_case}">
|
||||||
<img class="add-individual" src="${urls.images}/individual/manage-icon.png" alt="${i18n().manage}" /></a>
|
<img class="add-individual" src="${urls.images}/individual/manage-icon.png" alt="${i18n().manage}" /></a>
|
||||||
<#else>
|
<#else>
|
||||||
|
@ -231,6 +231,9 @@ name will be used as the label. -->
|
||||||
<#local verboseDisplay = property.verboseDisplay!>
|
<#local verboseDisplay = property.verboseDisplay!>
|
||||||
<#if verboseDisplay?has_content>
|
<#if verboseDisplay?has_content>
|
||||||
<section class="verbosePropertyListing">
|
<section class="verbosePropertyListing">
|
||||||
|
<#if verboseDisplay.fauxProperty??>
|
||||||
|
a faux property of
|
||||||
|
</#if>
|
||||||
<a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a>
|
<a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a>
|
||||||
(<span>${property.type?lower_case}</span> property);
|
(<span>${property.type?lower_case}</span> property);
|
||||||
order in group: <span>${verboseDisplay.displayRank};</span>
|
order in group: <span>${verboseDisplay.displayRank};</span>
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
<div id="developerPanel" > </div>
|
<div id="developerPanel" > </div>
|
||||||
<script>developerAjaxUrl = '${urls.developerAjax}'</script>
|
<script>developerAjaxUrl = '${urls.developerAjax}'</script>
|
||||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/developer/developerPanel.js"></script>')}
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/developer/developerPanel.js"></script>')}
|
||||||
|
<link rel="stylesheet" href="${urls.base}/css/developer/developerPanel.css" />
|
|
@ -6,27 +6,9 @@
|
||||||
</#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>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div.developer {
|
|
||||||
background-color: #f7dd8a;
|
|
||||||
padding: 0px 10px 0px 10px;
|
|
||||||
font-size: small;
|
|
||||||
font-variant: small-caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.developer #developerPanelBody {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.developer .container {
|
|
||||||
border: thin groove black
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<#if !settings.developerEnabled>
|
<#if !settings.developerEnabled>
|
||||||
<#elseif !settings.mayControl>
|
<#elseif !settings.mayControl>
|
||||||
<div class="developer">
|
<div class="developer">
|
||||||
|
@ -38,40 +20,26 @@ 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">
|
<div class="container">
|
||||||
Freemarker templates
|
Page configuration
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerDefeatFreemarkerCache" />
|
<@showCheckbox "developerPageContentsLogCustomListView" />
|
||||||
Defeat the template cache
|
Log the use of custom list view XML files.
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<@showCheckbox "developerInsertFreemarkerDelimiters" />
|
<@showCheckbox "developerPageContentsLogCustomShortView" />
|
||||||
Insert HTML comments at start and end of templates
|
Log the use of custom short views in search, index and browse pages.
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
SPARQL Queries
|
|
||||||
<label>
|
|
||||||
<@showCheckbox "developerLoggingRDFServiceEnable" />
|
|
||||||
Log each query
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<@showCheckbox "developerLoggingRDFServiceStackTrace" />
|
|
||||||
Add stack trace
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Restrict by calling stack
|
|
||||||
<@showTextbox "developerLoggingRDFServiceRestriction" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Language support
|
Language support
|
||||||
<label>
|
<label>
|
||||||
|
@ -84,8 +52,54 @@ div.developer .container {
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
Links
|
||||||
|
<br/>
|
||||||
|
<a href="${urls.base}/admin/log4j.jsp">Set log levels</a>
|
||||||
|
<a href="${urls.base}/admin/showAuth">Show authorization info</a>
|
||||||
|
<a href="${urls.base}/admin/showThreads">Show background threads</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="devleft">
|
||||||
|
<div class="container">
|
||||||
|
Freemarker templates
|
||||||
|
<label>
|
||||||
|
<@showCheckbox "developerDefeatFreemarkerCache" />
|
||||||
|
Defeat the template cache
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<@showCheckbox "developerInsertFreemarkerDelimiters" />
|
||||||
|
Insert HTML comments at start and end of templates
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
SPARQL Queries
|
||||||
|
<label>
|
||||||
|
<@showCheckbox "developerLoggingRDFServiceEnable" />
|
||||||
|
Log each query
|
||||||
|
</label>
|
||||||
|
<div class="within">
|
||||||
|
<label>
|
||||||
|
<@showCheckbox "developerLoggingRDFServiceStackTrace" />
|
||||||
|
Add stack trace
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Restrict by query string
|
||||||
|
<@showTextbox "developerLoggingRDFServiceQueryRestriction" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Restrict by calling stack
|
||||||
|
<@showTextbox "developerLoggingRDFServiceStackRestriction" />
|
||||||
|
</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>
|
Loading…
Add table
Reference in a new issue