Merge branch 'develop' of https://github.com/vivo-project/Vitro into develop
This commit is contained in:
commit
95c90572e4
22 changed files with 370 additions and 349 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>
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,120 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
|
||||||
import edu.cornell.mannlib.vedit.beans.FormObject;
|
|
||||||
import edu.cornell.mannlib.vedit.beans.Option;
|
|
||||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
|
||||||
import edu.cornell.mannlib.vedit.util.FormUtils;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
|
||||||
|
|
||||||
public class ExternalIdRetryController extends BaseEditController {
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ExternalIdRetryController.class.getName());
|
|
||||||
|
|
||||||
public void doPost (HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
if (!isAuthorizedToDisplayPage(request, response,
|
|
||||||
SimplePermission.DO_BACK_END_EDITING.ACTIONS)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VitroRequest vreq = new VitroRequest(request);
|
|
||||||
|
|
||||||
//create an EditProcessObject for this and put it in the session
|
|
||||||
EditProcessObject epo = super.createEpo(request);
|
|
||||||
|
|
||||||
String action = "insert";
|
|
||||||
|
|
||||||
DataPropertyDao dpDao = vreq.getUnfilteredWebappDaoFactory().getDataPropertyDao();
|
|
||||||
DataPropertyStatementDao edDao = vreq.getUnfilteredWebappDaoFactory().getDataPropertyStatementDao();
|
|
||||||
epo.setDataAccessObject(edDao);
|
|
||||||
epo.setBeanClass(DataPropertyStatement.class);
|
|
||||||
|
|
||||||
IndividualDao eDao = vreq.getUnfilteredWebappDaoFactory().getIndividualDao();
|
|
||||||
|
|
||||||
DataPropertyStatement eidForEditing = null;
|
|
||||||
if (!epo.getUseRecycledBean()){
|
|
||||||
eidForEditing = new DataPropertyStatementImpl();
|
|
||||||
populateBeanFromParams(eidForEditing,vreq);
|
|
||||||
if (vreq.getParameter(MULTIPLEXED_PARAMETER_NAME) != null) {
|
|
||||||
action = "update";
|
|
||||||
}
|
|
||||||
epo.setOriginalBean(eidForEditing);
|
|
||||||
} else {
|
|
||||||
eidForEditing = (DataPropertyStatement) epo.getNewBean();
|
|
||||||
}
|
|
||||||
|
|
||||||
//make a simple mask for the class's id
|
|
||||||
Object[] simpleMaskPair = new Object[2];
|
|
||||||
simpleMaskPair[0]="Id";
|
|
||||||
//simpleMaskPair[1]=Integer.valueOf(eidForEditing.getId());
|
|
||||||
epo.getSimpleMask().add(simpleMaskPair);
|
|
||||||
|
|
||||||
//set up any listeners
|
|
||||||
|
|
||||||
FormObject foo = new FormObject();
|
|
||||||
HashMap OptionMap = new HashMap();
|
|
||||||
List entityList = new LinkedList();
|
|
||||||
if (eidForEditing.getIndividualURI() != null) {
|
|
||||||
Individual individual = eDao.getIndividualByURI(eidForEditing.getIndividualURI());
|
|
||||||
entityList.add(new Option(individual.getURI(),individual.getName(),true));
|
|
||||||
} else {
|
|
||||||
entityList.add(new Option ("-1", "Error: the entity must be specified", true));
|
|
||||||
}
|
|
||||||
OptionMap.put("IndividualURI",entityList);
|
|
||||||
// TOOD change following DAO call to getAllExternalIdDataProperties once implemented
|
|
||||||
List allExternalIdDataProperties = dpDao.getAllExternalIdDataProperties();
|
|
||||||
Collections.sort(allExternalIdDataProperties);
|
|
||||||
OptionMap.put("DatapropURI", FormUtils.makeOptionListFromBeans(allExternalIdDataProperties, "URI", "PublicName", eidForEditing.getDatapropURI(),""));
|
|
||||||
foo.setOptionLists(OptionMap);
|
|
||||||
foo.setErrorMap(epo.getErrMsgMap());
|
|
||||||
|
|
||||||
epo.setFormObject(foo);
|
|
||||||
|
|
||||||
FormUtils.populateFormFromBean(eidForEditing,action,foo,epo.getBadValueMap());
|
|
||||||
|
|
||||||
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
|
||||||
request.setAttribute("bodyJsp","/templates/edit/formBasic.jsp");
|
|
||||||
request.setAttribute("formJsp","/templates/edit/specific/externalIds_retry.jsp");
|
|
||||||
request.setAttribute("scripts","/templates/edit/formBasic.js");
|
|
||||||
request.setAttribute("title","External Id Editing Form");
|
|
||||||
request.setAttribute("_action",action);
|
|
||||||
request.setAttribute("unqualifiedClassName","External Id");
|
|
||||||
setRequestAttributes(request,epo);
|
|
||||||
|
|
||||||
try {
|
|
||||||
rd.forward(request, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("ExternalIdRetryController could not forward to view.");
|
|
||||||
log.error(e.getMessage());
|
|
||||||
log.error(e.getStackTrace());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
doPost(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -143,24 +143,25 @@ public class VclassEditController extends BaseEditController {
|
||||||
|
|
||||||
// if supported, we want to show only the asserted superclasses and subclasses.
|
// if supported, we want to show only the asserted superclasses and subclasses.
|
||||||
VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao();
|
VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao();
|
||||||
|
VClassDao displayVcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getVClassDao();
|
||||||
|
|
||||||
List<VClass> superVClasses = getVClassesForURIList(
|
List<VClass> superVClasses = getVClassesForURIList(
|
||||||
vcDao.getSuperClassURIs(vcl.getURI(),false), vcDao);
|
vcDao.getSuperClassURIs(vcl.getURI(),false), displayVcDao);
|
||||||
sortForPickList(superVClasses, request);
|
sortForPickList(superVClasses, request);
|
||||||
request.setAttribute("superclasses",superVClasses);
|
request.setAttribute("superclasses",superVClasses);
|
||||||
|
|
||||||
List<VClass> subVClasses = getVClassesForURIList(
|
List<VClass> subVClasses = getVClassesForURIList(
|
||||||
vcDao.getSubClassURIs(vcl.getURI()), vcDao);
|
vcDao.getSubClassURIs(vcl.getURI()), displayVcDao);
|
||||||
sortForPickList(subVClasses, request);
|
sortForPickList(subVClasses, request);
|
||||||
request.setAttribute("subclasses",subVClasses);
|
request.setAttribute("subclasses",subVClasses);
|
||||||
|
|
||||||
List<VClass> djVClasses = getVClassesForURIList(
|
List<VClass> djVClasses = getVClassesForURIList(
|
||||||
vcDao.getDisjointWithClassURIs(vcl.getURI()), vcDao);
|
vcDao.getDisjointWithClassURIs(vcl.getURI()), displayVcDao);
|
||||||
sortForPickList(djVClasses, request);
|
sortForPickList(djVClasses, request);
|
||||||
request.setAttribute("disjointClasses",djVClasses);
|
request.setAttribute("disjointClasses",djVClasses);
|
||||||
|
|
||||||
List<VClass> eqVClasses = getVClassesForURIList(
|
List<VClass> eqVClasses = getVClassesForURIList(
|
||||||
vcDao.getEquivalentClassURIs(vcl.getURI()), vcDao);
|
vcDao.getEquivalentClassURIs(vcl.getURI()), displayVcDao);
|
||||||
sortForPickList(eqVClasses, request);
|
sortForPickList(eqVClasses, request);
|
||||||
request.setAttribute("equivalentClasses",eqVClasses);
|
request.setAttribute("equivalentClasses",eqVClasses);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
||||||
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
|
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
|
||||||
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
|
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
|
||||||
String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
|
String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
|
||||||
if (rangeUri != null) {
|
if (rangeUri != null && !rangeUri.isEmpty()) {
|
||||||
VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(rangeUri);
|
VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(rangeUri);
|
||||||
if (!rangeVClass.isUnion()) {
|
if (!rangeVClass.isUnion()) {
|
||||||
types.add(rangeVClass);
|
types.add(rangeVClass);
|
||||||
|
@ -125,18 +125,23 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
||||||
}
|
}
|
||||||
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
|
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
|
||||||
//Get all vclasses applicable to subject
|
//Get all vclasses applicable to subject
|
||||||
List<VClass> vClasses = subject.getVClasses();
|
if(subject != null) {
|
||||||
HashMap<String, VClass> typesHash = new HashMap<String, VClass>();
|
List<VClass> vClasses = subject.getVClasses();
|
||||||
for(VClass vclass: vClasses) {
|
HashMap<String, VClass> typesHash = new HashMap<String, VClass>();
|
||||||
List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri);
|
for(VClass vclass: vClasses) {
|
||||||
if(rangeVclasses != null) {
|
List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri);
|
||||||
for(VClass range: rangeVclasses) {
|
if(rangeVclasses != null) {
|
||||||
//a hash will keep a unique list of types and so prevent duplicates
|
for(VClass range: rangeVclasses) {
|
||||||
typesHash.put(range.getURI(), range);
|
//a hash will keep a unique list of types and so prevent duplicates
|
||||||
|
typesHash.put(range.getURI(), range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
types.addAll(typesHash.values());
|
||||||
types.addAll(typesHash.values());
|
} else {
|
||||||
|
log.error("Subject individual was null for");
|
||||||
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -285,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() {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -179,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) {
|
||||||
|
@ -203,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,11 +547,14 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
|
||||||
rangeVClasses.addAll(rangeClass.getUnionComponents());
|
rangeVClasses.addAll(rangeClass.getUnionComponents());
|
||||||
}
|
}
|
||||||
for(VClass rangeVClass : rangeVClasses) {
|
for(VClass rangeVClass : rangeVClasses) {
|
||||||
vclasses.add(rangeVClass);
|
if(rangeVClass.getGroupURI() != null) {
|
||||||
|
vclasses.add(rangeVClass);
|
||||||
|
}
|
||||||
List<String> subURIs = wdf.getVClassDao().getAllSubClassURIs(rangeVClass.getURI());
|
List<String> subURIs = wdf.getVClassDao().getAllSubClassURIs(rangeVClass.getURI());
|
||||||
for (String subClassURI : subURIs) {
|
for (String subClassURI : subURIs) {
|
||||||
VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI);
|
VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI);
|
||||||
if (subClass != null) {
|
//if the subclass exists and also belongs to a particular class group
|
||||||
|
if (subClass != null && subClass.getGroupURI() != null) {
|
||||||
vclasses.add(subClass);
|
vclasses.add(subClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -567,7 +570,8 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
|
||||||
//add range vclass to hash
|
//add range vclass to hash
|
||||||
if(rangeVclasses != null) {
|
if(rangeVclasses != null) {
|
||||||
for(VClass v: rangeVclasses) {
|
for(VClass v: rangeVclasses) {
|
||||||
if(!vclassesURIs.contains(v.getURI())) {
|
//Need to make sure any class added will belong to a class group
|
||||||
|
if(!vclassesURIs.contains(v.getURI()) && v.getGroupURI() != null) {
|
||||||
vclassesURIs.add(v.getURI());
|
vclassesURIs.add(v.getURI());
|
||||||
vclasses.add(v);
|
vclasses.add(v);
|
||||||
}
|
}
|
||||||
|
@ -577,7 +581,13 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
//if each subject vclass resulted in null being returned for range vclasses, then size of vclasses would be zero
|
//if each subject vclass resulted in null being returned for range vclasses, then size of vclasses would be zero
|
||||||
if(vclasses.size() == 0) {
|
if(vclasses.size() == 0) {
|
||||||
vclasses = wdf.getVClassDao().getAllVclasses();
|
List<VClass> allVClasses = wdf.getVClassDao().getAllVclasses();
|
||||||
|
//Since these are all vclasses, we should check whether vclasses included are in a class group
|
||||||
|
for(VClass v:allVClasses) {
|
||||||
|
if(v.getGroupURI() != null) {
|
||||||
|
vclasses.add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -99,11 +99,6 @@
|
||||||
<input type="hidden" name="controller" value="Entity"/>
|
<input type="hidden" name="controller" value="Entity"/>
|
||||||
</form>
|
</form>
|
||||||
<form action="editForm" method="get">
|
<form action="editForm" method="get">
|
||||||
<input type="submit" class="form-button" value="Add an External Identifier"/>
|
|
||||||
<input type="hidden" name="IndividualURI" value="${individual.URI}"/>
|
|
||||||
<input type="hidden" name="controller" value="ExternalId"/>
|
|
||||||
</form>
|
|
||||||
<form action="editForm" method="get">
|
|
||||||
<input type="submit" class="form-button" value="Change URI"/>
|
<input type="submit" class="form-button" value="Change URI"/>
|
||||||
<input type="hidden" name="oldURI" value="${individual.URI}"/>
|
<input type="hidden" name="oldURI" value="${individual.URI}"/>
|
||||||
<input type="hidden" name="mode" value="renameResource"/>
|
<input type="hidden" name="mode" value="renameResource"/>
|
||||||
|
|
|
@ -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>
|
|
Loading…
Add table
Add a link
Reference in a new issue