NIHVIVO-2343 Implement editing and removing relationships, and status messages. Test pagination.

This commit is contained in:
j2blake 2011-11-04 18:35:55 +00:00
parent 91c34b4fc9
commit 5e86051baa
5 changed files with 275 additions and 5 deletions

View file

@ -5,9 +5,12 @@ package edu.cornell.mannlib.vitro.webapp.controller;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -114,4 +117,75 @@ public abstract class AbstractPageHandler {
return expected.equals(getStringParameter(key, "")); return expected.equals(getStringParameter(key, ""));
} }
// ----------------------------------------------------------------------
// Message methods
// ----------------------------------------------------------------------
/**
* If a Message has been set in the session, get it, store its info in the
* body map under "message", and remove it from the session, so it will not
* be displayed again.
*/
protected void applyMessage(HttpServletRequest req, Map<String, Object> body) {
Message.applyMessageToBodyMap(req, body, "message");
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
/**
* Indicates that parameters have failed validation.
*/
protected static class InvalidParametersException extends Exception {
public InvalidParametersException(String message) {
super(message);
}
}
/**
* Set one of these on the session, so it can be interpreted and displayed
* at the next request. It will only be displayed once.
*
* Allows one page handler to pass a message to another page handler through
* a re-direct.
*/
public abstract static class Message {
private static final String ATTRIBUTE = Message.class.getName();
public static void setMessage(HttpServletRequest req, Message message) {
log.debug("Added message to session: " + message.getMessageInfoMap());
req.getSession().setAttribute(ATTRIBUTE, message);
}
public static void applyMessageToBodyMap(HttpServletRequest req,
Map<String, Object> body, String key) {
Object o = req.getSession().getAttribute(ATTRIBUTE);
req.getSession().removeAttribute(ATTRIBUTE);
if (o instanceof Message) {
body.put(key, ((Message) o).getMessageInfoMap());
}
}
public Map<String, Object> assembleMap(Object... args) {
if (args.length % 2 != 0) {
throw new IllegalArgumentException(
"you must provide keys and values in pairs.");
}
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < args.length; i += 2) {
if (!(args[i] instanceof String)) {
throw new IllegalArgumentException("args[" + i
+ "] is not a String");
}
map.put((String) args[i], args[i + 1]);
}
return map;
}
public abstract Map<String, Object> getMessageInfoMap();
}
} }

View file

@ -2,13 +2,17 @@
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies; package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageProxies; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageProxies;
import edu.cornell.mannlib.vitro.webapp.controller.AbstractPageHandler.Message;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/** /**
@ -18,6 +22,8 @@ public class ManageProxiesController extends FreemarkerHttpServlet {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(ManageProxiesController.class); .getLog(ManageProxiesController.class);
private static final String ACTION_EDIT = "/edit";
@Override @Override
protected Actions requiredActions(VitroRequest vreq) { protected Actions requiredActions(VitroRequest vreq) {
return new Actions(new ManageProxies()); return new Actions(new ManageProxies());
@ -32,12 +38,51 @@ public class ManageProxiesController extends FreemarkerHttpServlet {
String action = vreq.getPathInfo(); String action = vreq.getPathInfo();
log.debug("action = '" + action + "'"); log.debug("action = '" + action + "'");
if (ACTION_EDIT.equals(action)) {
return handleEditRequest(vreq);
} else {
return handleListRequest(vreq); return handleListRequest(vreq);
} }
}
private ResponseValues handleEditRequest(VitroRequest vreq) {
ManageProxiesEditPage page = new ManageProxiesEditPage(vreq);
if (page.isValid()) {
page.applyEdits();
Message.setMessage(vreq, new SuccessMessage());
} else {
Message.setMessage(vreq, new FailureMessage());
}
return redirectToList();
}
private ResponseValues handleListRequest(VitroRequest vreq) { private ResponseValues handleListRequest(VitroRequest vreq) {
ManageProxiesListPage page = new ManageProxiesListPage(vreq); ManageProxiesListPage page = new ManageProxiesListPage(vreq);
return page.showPage(); return page.showPage();
} }
/**
* After an successful change, redirect to the list instead of forwarding.
* That way, a browser "refresh" won't try to repeat the operation.
*/
private ResponseValues redirectToList() {
return new RedirectResponseValues("/manageProxies/list");
}
private static class SuccessMessage extends Message {
@Override
public Map<String, Object> getMessageInfoMap() {
return assembleMap("success", Boolean.TRUE);
}
}
private static class FailureMessage extends Message {
@Override
public Map<String, Object> getMessageInfoMap() {
return assembleMap("failure", Boolean.TRUE);
}
}
} }

View file

@ -0,0 +1,131 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
import java.util.Collections;
import java.util.List;
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.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.AbstractPageHandler;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* This is not really a page, in that it doesn't display anything. It's just a
* way to separate out some of the logic of the ManageProxies list page.
*/
public class ManageProxiesEditPage extends AbstractPageHandler {
private static final Log log = LogFactory
.getLog(ManageProxiesEditPage.class);
private static final String PARAMETER_DELETE_PROXY = "deleteProxy";
private static final String PARAMETER_EDIT_PROFILES = "modifyProfileList";
private static final String PARAMETER_PROXY_URI = "proxyUri";
private static final String PARAMETER_PROFILE_URI = "profileUri";
private enum Function {
DELETE_PROXY, EDIT_PROFILES, UNKNOWN
}
private Function function;
private List<String> proxyUris;
private List<UserAccount> proxyAccounts;
private List<String> profileUris;
/** The result of checking whether this request is valid. */
private boolean valid = true;
protected ManageProxiesEditPage(VitroRequest vreq) {
super(vreq);
parseParameters();
}
private void parseParameters() {
proxyUris = getStringParameters(PARAMETER_PROXY_URI);
profileUris = getStringParameters(PARAMETER_PROFILE_URI);
try {
if (isFlagOnRequest(PARAMETER_EDIT_PROFILES)) {
function = Function.EDIT_PROFILES;
proxyAccounts = findSingleProxyAccount(PARAMETER_EDIT_PROFILES);
validateProfileUris();
} else if (isFlagOnRequest(PARAMETER_DELETE_PROXY)) {
function = Function.DELETE_PROXY;
proxyAccounts = findSingleProxyAccount(PARAMETER_EDIT_PROFILES);
} else {
function = Function.UNKNOWN;
}
} catch (InvalidParametersException e) {
log.error(e.getMessage());
valid = false;
}
}
private List<UserAccount> findSingleProxyAccount(String functionParameter)
throws InvalidParametersException {
if (proxyUris.isEmpty()) {
throw new InvalidParametersException("'" + functionParameter
+ "' was requested, but no '" + PARAMETER_PROXY_URI
+ "' parameter was found.");
}
if (proxyUris.size() > 1) {
throw new InvalidParametersException("'" + functionParameter
+ "' was requested, but there were " + proxyUris.size()
+ "'" + PARAMETER_PROXY_URI + "' parameters.");
}
String proxyUri = proxyUris.get(0);
UserAccount proxy = userAccountsDao.getUserAccountByUri(proxyUri);
if (proxy == null) {
throw new InvalidParametersException(
"Found no User Account for proxyUri='" + proxyUri + "'");
}
return Collections.singletonList(proxy);
}
private void validateProfileUris() throws InvalidParametersException {
for (String profileUri : profileUris) {
Individual ind = indDao.getIndividualByURI(profileUri);
if (ind == null) {
throw new InvalidParametersException(
"Found no Individual for profileUri='" + profileUri
+ "'");
}
}
}
public boolean isValid() {
return valid;
}
public void applyEdits() {
if (!valid) {
return;
}
if (function == Function.DELETE_PROXY) {
deleteRelationshipsFromProxy();
} else if (function == Function.EDIT_PROFILES) {
editRelationshipsOnProxy();
}
}
private void deleteRelationshipsFromProxy() {
UserAccount proxyAccount = proxyAccounts.get(0);
proxyAccount.setProxiedIndividualUris(Collections.<String> emptyList());
userAccountsDao.updateUserAccount(proxyAccount);
}
private void editRelationshipsOnProxy() {
UserAccount proxyAccount = proxyAccounts.get(0);
proxyAccount.setProxiedIndividualUris(profileUris);
userAccountsDao.updateUserAccount(proxyAccount);
}
}

View file

@ -97,6 +97,9 @@ public class ManageProxiesListPage extends AbstractPageHandler {
body.put("formUrls", buildUrlsMap()); body.put("formUrls", buildUrlsMap());
applyMessage(vreq, body);
log.debug("body map is: " + body);
return body; return body;
} }

View file

@ -8,18 +8,35 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/cust
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/autocomplete.css" />')} ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/autocomplete.css" />')}
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')} ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')}
<#if message??>
<section class="account-feedback">
<#if message.success?? >
<p>
The operation was successful.
</p>
</#if>
<#if message.failure?? >
<p>
The operation was unsuccessful. Full details can be found in the system log.
</p>
</#if>
</section>
</#if>
<p> <p>
<#if page.previous??> <#if page.previous??>
<a href="${formUrls.list}?pageIndex='${page.previous}'">Previous</a> <a href="${formUrls.list}?pageIndex=${page.previous}&searchTerm=${searchTerm}}">Previous</a>
</#if> </#if>
${page.current} of ${page.last} ${page.current} of ${page.last}
<#if page.next??> <#if page.next??>
<a href="${formUrls.list}?pageIndex='${page.next}'">Next</a> <a href="${formUrls.list}?pageIndex=${page.next}&searchTerm=${searchTerm}">Next</a>
</#if> </#if>
</p> </p>
<#list relationships as r> <#list relationships as r>
<form action="${formUrls.edit} method="POST"> <form action="${formUrls.edit}" method="POST">
<table style="width: 100%;"> <table style="width: 100%;">
<tr> <tr>
<td style="border: thin solid black; width: 50%;"> <td style="border: thin solid black; width: 50%;">
@ -81,7 +98,7 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/sm
</td> </td>
</tr> </tr>
</table> </table>
<input type="hidden" name="proxyUri" value="%uri%" > <input type="hidden" name="profileUri" templatePart="uriField" value="%uri%" >
</div> </div>
</div> </div>
</div> </div>