This commit is contained in:
commit
e5f73e181c
82 changed files with 1842 additions and 1072 deletions
|
@ -46,4 +46,11 @@ public class RequestIdentifiers {
|
|||
return (IdentifierBundle) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* The login status has changed, so discard the cached Identifiers.
|
||||
*/
|
||||
public static void resetIdentifiers(ServletRequest request) {
|
||||
request.removeAttribute(ATTRIBUTE_ID_BUNDLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
|||
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
|
||||
/**
|
||||
|
@ -73,7 +72,7 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
|
|||
private Collection<? extends Identifier> createRootUserIdentifiers(
|
||||
HttpServletRequest req) {
|
||||
UserAccount user = LoginStatusBean.getCurrentUser(req);
|
||||
if (isRootUser(user)) {
|
||||
if ((user != null) && user.isRootUser()) {
|
||||
return Collections.singleton(new IsRootUser());
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
|
@ -143,25 +142,6 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
|
|||
return individuals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this user a root user?
|
||||
*/
|
||||
private boolean isRootUser(UserAccount user) {
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WebappDaoFactory wdf = (WebappDaoFactory) context
|
||||
.getAttribute("webappDaoFactory");
|
||||
if (wdf == null) {
|
||||
log.error("Could not get a WebappDaoFactory from the ServletContext");
|
||||
return false;
|
||||
}
|
||||
|
||||
UserAccountsDao uaDao = wdf.getUserAccountsDao();
|
||||
return uaDao.isRootUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + " - " + hashCode();
|
||||
|
|
|
@ -9,11 +9,6 @@ import javax.servlet.ServletContextListener;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
|
@ -25,9 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
|||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
|
||||
|
||||
/**
|
||||
|
@ -73,10 +66,11 @@ public class RootUserPolicy implements PolicyIface {
|
|||
|
||||
try {
|
||||
UserAccountsDao uaDao = getUserAccountsDao(ctx);
|
||||
OntModel userAccountsModel = getUserAccountsModel(ctx);
|
||||
|
||||
checkForWrongRootUser(ctx, uaDao);
|
||||
|
||||
if (!rootUserExists(uaDao)) {
|
||||
createRootUser(ctx, uaDao, userAccountsModel);
|
||||
createRootUser(ctx, uaDao);
|
||||
}
|
||||
|
||||
ServletPolicyList.addPolicy(ctx, new RootUserPolicy());
|
||||
|
@ -98,26 +92,41 @@ public class RootUserPolicy implements PolicyIface {
|
|||
return wadf.getUserAccountsDao();
|
||||
}
|
||||
|
||||
private OntModel getUserAccountsModel(ServletContext ctx) {
|
||||
return ModelContext.getBaseOntModelSelector(ctx)
|
||||
.getUserAccountsModel();
|
||||
private void checkForWrongRootUser(ServletContext ctx,
|
||||
UserAccountsDao uaDao) {
|
||||
UserAccount root = getRootUser(uaDao);
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
String actualRootEmail = root.getEmailAddress();
|
||||
|
||||
String configRootEmail = ConfigurationProperties.getBean(ctx)
|
||||
.getProperty(PROPERTY_ROOT_USER_EMAIL);
|
||||
if (actualRootEmail.equals(configRootEmail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.warn("Root user '" + actualRootEmail + "' already exists.");
|
||||
}
|
||||
|
||||
private boolean rootUserExists(UserAccountsDao uaDao) {
|
||||
return (getRootUser(uaDao) != null);
|
||||
}
|
||||
|
||||
private UserAccount getRootUser(UserAccountsDao uaDao) {
|
||||
for (UserAccount ua : uaDao.getAllUserAccounts()) {
|
||||
if (uaDao.isRootUser(ua)) {
|
||||
return true;
|
||||
if (ua.isRootUser()) {
|
||||
return ua;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO The first and last name should be left blank, so the user will
|
||||
* be forced to edit them. However, that's not in place yet.
|
||||
*/
|
||||
private void createRootUser(ServletContext ctx, UserAccountsDao uaDao,
|
||||
OntModel userAccountsModel) {
|
||||
private void createRootUser(ServletContext ctx, UserAccountsDao uaDao) {
|
||||
String emailAddress = ConfigurationProperties.getBean(ctx)
|
||||
.getProperty(PROPERTY_ROOT_USER_EMAIL);
|
||||
if (emailAddress == null) {
|
||||
|
@ -147,19 +156,10 @@ public class RootUserPolicy implements PolicyIface {
|
|||
.applyMd5Encoding(ROOT_USER_INITIAL_PASSWORD));
|
||||
ua.setPasswordChangeRequired(true);
|
||||
ua.setStatus(Status.ACTIVE);
|
||||
ua.setRootUser(true);
|
||||
|
||||
uaDao.insertUserAccount(ua);
|
||||
|
||||
userAccountsModel.enterCriticalSection(Lock.WRITE);
|
||||
try {
|
||||
Resource r = userAccountsModel.getResource(ua.getUri());
|
||||
Resource t = userAccountsModel
|
||||
.getResource(VitroVocabulary.USERACCOUNT_ROOT_USER);
|
||||
userAccountsModel.add(r, RDF.type, t);
|
||||
} finally {
|
||||
userAccountsModel.leaveCriticalSection();
|
||||
}
|
||||
|
||||
log.info("Created root user as '" + emailAddress + "'");
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ public class UserAccount {
|
|||
/** This may be empty, but should never be null. */
|
||||
private Set<String> permissionSetUris = Collections.emptySet();
|
||||
|
||||
private boolean rootUser = false;
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
@ -172,10 +174,18 @@ public class UserAccount {
|
|||
this.permissionSetUris = new HashSet<String>(permissionSetUris);
|
||||
}
|
||||
|
||||
public boolean isRootUser() {
|
||||
return rootUser;
|
||||
}
|
||||
|
||||
public void setRootUser(boolean rootUser) {
|
||||
this.rootUser = rootUser;
|
||||
}
|
||||
|
||||
private <T> T nonNull(T value, T defaultValue) {
|
||||
return (value == null) ? defaultValue : value;
|
||||
}
|
||||
|
||||
|
||||
private String limitStringLength(int limit, String s) {
|
||||
if (s == null) {
|
||||
return "";
|
||||
|
@ -196,6 +206,7 @@ public class UserAccount {
|
|||
+ (", passwordChangeRequired=" + passwordChangeRequired)
|
||||
+ (", loginCount=" + loginCount) + (", status=" + status)
|
||||
+ (", externalAuthId=" + externalAuthId)
|
||||
+ (", rootUser=" + rootUser)
|
||||
+ (", permissionSetUris=" + permissionSetUris) + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,352 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.SendFailedException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.servlet.ServletException;
|
||||
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.vitro.webapp.beans.ApplicationBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
|
||||
public class ContactMailServlet extends VitroHttpServlet {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ContactMailServlet.class);
|
||||
|
||||
private final static String CONFIRM_PAGE = "/templates/parts/thankyou.jsp";
|
||||
private final static String ERR_PAGE = "/templates/parts/contact_err.jsp";
|
||||
private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
|
||||
private final static String EMAIL_BACKUP_FILE_PATH = "/WEB-INF/LatestMessage.html";
|
||||
|
||||
private final static String WEB_USERNAME_PARAM = "webusername";
|
||||
private final static String WEB_USEREMAIL_PARAM = "webuseremail";
|
||||
private final static String COMMENTS_PARAM = "s34gfd88p9x1";
|
||||
|
||||
@Override
|
||||
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
||||
throws ServletException, IOException {
|
||||
|
||||
VitroRequest vreq = new VitroRequest(request);
|
||||
|
||||
ApplicationBean appBean = vreq.getAppBean();
|
||||
|
||||
String statusMsg = null; // holds the error status
|
||||
|
||||
if (!FreemarkerEmailFactory.isConfigured(vreq)) {
|
||||
statusMsg = "This application has not yet been configured to send mail. "
|
||||
+ "Email properties must be specified in the configuration properties file.";
|
||||
redirectToError(response, statusMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
String webusername = vreq.getParameter(WEB_USERNAME_PARAM);
|
||||
String webuseremail = vreq.getParameter(WEB_USEREMAIL_PARAM);
|
||||
String comments = vreq.getParameter(COMMENTS_PARAM);
|
||||
|
||||
String validationMessage = validateInput(webusername, webuseremail,
|
||||
comments);
|
||||
if (validationMessage != null) {
|
||||
redirectToError(response, validationMessage);
|
||||
return;
|
||||
}
|
||||
webusername = webusername.trim();
|
||||
webuseremail = webuseremail.trim();
|
||||
comments = comments.trim();
|
||||
|
||||
String spamReason = null;
|
||||
|
||||
String originalReferer = (String) request.getSession()
|
||||
.getAttribute("commentsFormReferer");
|
||||
if (originalReferer != null) {
|
||||
request.getSession().removeAttribute("commentsFormReferer");
|
||||
/* does not support legitimate clients that don't send the Referer header
|
||||
String referer = request.getHeader("Referer");
|
||||
if (referer == null ||
|
||||
(referer.indexOf("comments") <0
|
||||
&& referer.indexOf("correction") <0) ) {
|
||||
spamReason = "The form was not submitted from the " +
|
||||
"Contact Us or Corrections page.";
|
||||
statusMsg = SPAM_MESSAGE;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
originalReferer = "none";
|
||||
}
|
||||
|
||||
if (spamReason == null) {
|
||||
spamReason = checkForSpam(comments);
|
||||
if (spamReason != null) {
|
||||
statusMsg = SPAM_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
String formType = vreq.getParameter("DeliveryType");
|
||||
String[] deliverToArray = null;
|
||||
int recipientCount = 0;
|
||||
String deliveryfrom = null;
|
||||
|
||||
if ("comment".equals(formType)) {
|
||||
if (appBean.getContactMail() == null || appBean.getContactMail().trim().length()==0) {
|
||||
log.error("No contact mail address defined in current application");
|
||||
throw new Error(
|
||||
"To establish the Contact Us mail capability the system administrators must "
|
||||
+ "specify an email address in the current portal.");
|
||||
} else {
|
||||
deliverToArray = appBean.getContactMail().split(",");
|
||||
}
|
||||
deliveryfrom = "Message from the "+appBean.getApplicationName()+" Contact Form";
|
||||
} else if ("correction".equals(formType)) {
|
||||
if (appBean.getCorrectionMail() == null || appBean.getCorrectionMail().trim().length()==0) {
|
||||
log.error("Expecting one or more correction email addresses to be specified in current application; will attempt to use contact mail address");
|
||||
if (appBean.getContactMail() == null || appBean.getContactMail().trim().length()==0) {
|
||||
log.error("No contact mail address or correction mail address defined in current application");
|
||||
} else {
|
||||
deliverToArray = appBean.getContactMail().split(",");
|
||||
}
|
||||
} else {
|
||||
deliverToArray = appBean.getCorrectionMail().split(",");
|
||||
}
|
||||
deliveryfrom = "Message from the "+appBean.getApplicationName()+" Correction Form (ARMANN-nospam)";
|
||||
} else {
|
||||
deliverToArray = appBean.getContactMail().split(",");
|
||||
statusMsg = SPAM_MESSAGE ;
|
||||
spamReason = "The form specifies no delivery type.";
|
||||
}
|
||||
recipientCount=(deliverToArray == null) ? 0 : deliverToArray.length;
|
||||
if (recipientCount == 0) {
|
||||
log.error("recipientCount is 0 when DeliveryType specified as \""+formType+"\"");
|
||||
throw new Error(
|
||||
"To establish the Contact Us mail capability the system administrators must "
|
||||
+ "specify at least one email address in the current portal.");
|
||||
}
|
||||
|
||||
String msgText = composeEmail(webusername, webuseremail, comments,
|
||||
deliveryfrom, originalReferer, request.getRemoteAddr());
|
||||
|
||||
// debugging
|
||||
PrintWriter outFile = new PrintWriter
|
||||
(new FileWriter(request.getSession().getServletContext()
|
||||
.getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush
|
||||
writeBackupCopy(outFile, msgText, spamReason);
|
||||
|
||||
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
|
||||
//s.setDebug(true);
|
||||
try {
|
||||
|
||||
if (spamReason == null) {
|
||||
sendMessage(s, webuseremail, deliverToArray, deliveryfrom,
|
||||
recipientCount, msgText);
|
||||
}
|
||||
|
||||
} catch (AddressException e) {
|
||||
statusMsg = "Please supply a valid email address.";
|
||||
outFile.println( statusMsg );
|
||||
outFile.println( e.getMessage() );
|
||||
} catch (SendFailedException e) {
|
||||
statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
|
||||
outFile.println( statusMsg );
|
||||
outFile.println( e.getMessage() );
|
||||
} catch (MessagingException e) {
|
||||
statusMsg = "The system was unable to deliver your mail. Please try again later. [MESSAGING]";
|
||||
outFile.println( statusMsg );
|
||||
outFile.println( e.getMessage() );
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
outFile.flush();
|
||||
outFile.close();
|
||||
|
||||
// Redirect to the appropriate confirmation page
|
||||
if (statusMsg == null && spamReason == null) {
|
||||
// message was sent successfully
|
||||
redirectToConfirmation(response, statusMsg);
|
||||
} else {
|
||||
// exception occurred
|
||||
redirectToError( response, statusMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPost( HttpServletRequest request, HttpServletResponse response )
|
||||
throws ServletException, IOException
|
||||
{
|
||||
doGet( request, response );
|
||||
}
|
||||
|
||||
private void redirectToConfirmation(HttpServletResponse response,
|
||||
String statusMsg) throws IOException {
|
||||
response.sendRedirect( "test?bodyJsp=" + CONFIRM_PAGE + "&home=" );
|
||||
}
|
||||
|
||||
private void redirectToError(HttpServletResponse response, String statusMsg)
|
||||
throws IOException {
|
||||
response.sendRedirect("test?bodyJsp=" + ERR_PAGE + "&ERR=" + statusMsg);
|
||||
}
|
||||
|
||||
/** Intended to mangle url so it can get through spam filtering
|
||||
* http://host/dir/servlet?param=value -> host: dir/servlet?param=value */
|
||||
public String stripProtocol( String in ){
|
||||
if( in == null )
|
||||
return "";
|
||||
else
|
||||
return in.replaceAll("http://", "host: " );
|
||||
}
|
||||
|
||||
private String composeEmail(String webusername, String webuseremail,
|
||||
String comments, String deliveryfrom,
|
||||
String originalReferer, String ipAddr) {
|
||||
|
||||
StringBuffer msgBuf = new StringBuffer();
|
||||
// contains the intro copy for the body of the email message
|
||||
|
||||
String lineSeparator = System.getProperty("line.separator");
|
||||
// \r\n on windows, \n on unix
|
||||
|
||||
// from MyLibrary
|
||||
msgBuf.setLength(0);
|
||||
msgBuf.append("Content-Type: text/html; charset='us-ascii'" + lineSeparator);
|
||||
msgBuf.append("<html>" + lineSeparator );
|
||||
msgBuf.append("<head>" + lineSeparator );
|
||||
msgBuf.append("<style>a {text-decoration: none}</style>" + lineSeparator );
|
||||
msgBuf.append("<title>" + deliveryfrom + "</title>" + lineSeparator );
|
||||
msgBuf.append("</head>" + lineSeparator );
|
||||
msgBuf.append("<body>" + lineSeparator );
|
||||
msgBuf.append("<h4>" + deliveryfrom + "</h4>" + lineSeparator );
|
||||
msgBuf.append("<h4>From: "+webusername +" (" + webuseremail + ")" +
|
||||
" at IP address " + ipAddr + "</h4>"+lineSeparator);
|
||||
|
||||
if (!(originalReferer == null || originalReferer.equals("none"))){
|
||||
//The spam filter that is being used by the listsrv is rejecting <a href="...
|
||||
//so try with out the markup, if that sill doesn't work,
|
||||
//uncomment the following line to strip the http://
|
||||
//msgBuf.append("<p><i>likely viewing page " + stripProtocol(originalReferer) );
|
||||
msgBuf.append("<p><i>likely viewing page " + originalReferer );
|
||||
}
|
||||
|
||||
msgBuf.append(lineSeparator + "</i></p><h3>Comments:</h3>" + lineSeparator );
|
||||
if (comments==null || comments.equals("")) {
|
||||
msgBuf.append("<p>BLANK MESSAGE</p>");
|
||||
} else {
|
||||
msgBuf.append("<p>"+comments+"</p>");
|
||||
}
|
||||
msgBuf.append("</body>" + lineSeparator );
|
||||
msgBuf.append("</html>" + lineSeparator );
|
||||
|
||||
return msgBuf.toString();
|
||||
|
||||
}
|
||||
|
||||
private void writeBackupCopy(PrintWriter outFile, String msgText,
|
||||
String spamReason) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
outFile.println("<hr/>");
|
||||
outFile.println();
|
||||
outFile.println("<p>"+cal.getTime()+"</p>");
|
||||
outFile.println();
|
||||
if (spamReason != null) {
|
||||
outFile.println("<p>REJECTED - SPAM</p>");
|
||||
outFile.println("<p>"+spamReason+"</p>");
|
||||
outFile.println();
|
||||
}
|
||||
outFile.print( msgText );
|
||||
outFile.println();
|
||||
outFile.println();
|
||||
outFile.flush();
|
||||
// outFile.close();
|
||||
}
|
||||
|
||||
private void sendMessage(Session s, String webuseremail,
|
||||
String[] deliverToArray, String deliveryfrom, int recipientCount,
|
||||
String msgText)
|
||||
throws AddressException, SendFailedException, MessagingException {
|
||||
// Construct the message
|
||||
MimeMessage msg = new MimeMessage( s );
|
||||
//System.out.println("trying to send message from servlet");
|
||||
|
||||
// Set the from address
|
||||
msg.setFrom( new InternetAddress( webuseremail ));
|
||||
|
||||
// Set the recipient address
|
||||
|
||||
if (recipientCount>0){
|
||||
InternetAddress[] address=new InternetAddress[recipientCount];
|
||||
for (int i=0; i<recipientCount; i++){
|
||||
address[i] = new InternetAddress(deliverToArray[i]);
|
||||
}
|
||||
msg.setRecipients( Message.RecipientType.TO, address );
|
||||
}
|
||||
|
||||
// Set the subject and text
|
||||
msg.setSubject( deliveryfrom );
|
||||
|
||||
// add the multipart to the message
|
||||
msg.setContent(msgText,"text/html");
|
||||
|
||||
// set the Date: header
|
||||
msg.setSentDate( new Date() );
|
||||
|
||||
Transport.send( msg ); // try to send the message via smtp - catch error exceptions
|
||||
|
||||
}
|
||||
|
||||
private String validateInput(String webusername, String webuseremail,
|
||||
String comments) {
|
||||
|
||||
if( webusername == null || "".equals(webusername.trim()) ){
|
||||
return "A proper webusername field was not found in the form submitted.";
|
||||
}
|
||||
|
||||
if( webuseremail == null || "".equals(webuseremail.trim()) ){
|
||||
return "A proper webuser email field was not found in the form submitted.";
|
||||
}
|
||||
|
||||
if (comments==null || "".equals(comments.trim())) {
|
||||
return "The proper comments field was not found in the form submitted.";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* @return null if message not judged to be spam, otherwise a String
|
||||
* containing the reason the message was flagged as spam.
|
||||
*/
|
||||
private String checkForSpam(String comments) {
|
||||
|
||||
/* if this blog markup is found, treat comment as blog spam */
|
||||
if (
|
||||
(comments.indexOf("[/url]") > -1
|
||||
|| comments.indexOf("[/URL]") > -1
|
||||
|| comments.indexOf("[url=") > -1
|
||||
|| comments.indexOf("[URL=") > -1)) {
|
||||
return "The message contained blog link markup.";
|
||||
}
|
||||
|
||||
/* if message is absurdly short, treat as blog spam */
|
||||
if (comments.length()<15) {
|
||||
return "The message was too short.";
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,753 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Datatype;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.SearchException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc.VitroLuceneTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup;
|
||||
|
||||
/**
|
||||
* This servlet is for servicing Google Refine's
|
||||
* "Add columns from VIVO" requests.
|
||||
*
|
||||
* @author Eliza Chan (elc2013@med.cornell.edu)
|
||||
*
|
||||
*/
|
||||
public class GrefinePropertyListServlet extends VitroHttpServlet {
|
||||
|
||||
private int MAXDEPTH = 7;
|
||||
private int NUM_COLS = 9;
|
||||
private static String QUERY_PARAMETER_NAME = "term";
|
||||
public static final int MAX_QUERY_LENGTH = 500;
|
||||
private static final Log log = LogFactory.getLog(GrefinePropertyListServlet.class.getName());
|
||||
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
//resp.setContentType("application/json");
|
||||
super.doPost(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
super.doGet(req, resp);
|
||||
resp.setContentType("application/json");
|
||||
VitroRequest vreq = new VitroRequest(req);
|
||||
|
||||
try {
|
||||
|
||||
String callbackStr = (vreq.getParameter("callback") == null) ? ""
|
||||
: vreq.getParameter("callback");
|
||||
ServletOutputStream out = resp.getOutputStream();
|
||||
|
||||
|
||||
// *******
|
||||
// methodology adopted from DatatypePropertiesListingController and ClassHierarchyListingController
|
||||
// *******
|
||||
VClassDao vcDao = vreq.getFullWebappDaoFactory().getVClassDao();
|
||||
DataPropertyDao dao = vreq.getFullWebappDaoFactory().getDataPropertyDao();
|
||||
String topUri = vreq.getParameter("type");
|
||||
VClass topClass = vcDao.getVClassByURI(topUri);
|
||||
HashSet<String> propURIs = new HashSet<String>();
|
||||
HashMap<VClass, List<DataProperty>> classPropertiesMap =
|
||||
populateClassPropertiesMap(vcDao, dao, topUri, propURIs);
|
||||
|
||||
|
||||
// Construct json String
|
||||
JSONObject completeJson = new JSONObject();
|
||||
JSONArray propertiesJsonArr = new JSONArray();
|
||||
if (classPropertiesMap.size() > 0) {
|
||||
for (Iterator<VClass> iter = classPropertiesMap.keySet().iterator(); iter.hasNext();) { // add results to schema
|
||||
VClass vc = (VClass) iter.next();
|
||||
System.out.println("vc uri: " + vc.getURI());
|
||||
System.out.println("vc name: " + vc.getName());
|
||||
|
||||
ArrayList<DataProperty> vcProps = (ArrayList<DataProperty>)classPropertiesMap.get(vc);
|
||||
for (DataProperty prop: vcProps) {
|
||||
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||
System.out.println("--- uri: " + prop.getURI());
|
||||
System.out.println("--- name: " + nameStr);
|
||||
// top level
|
||||
JSONObject propertiesItemJson = new JSONObject();
|
||||
JSONObject rootSchemaJson = new JSONObject();
|
||||
rootSchemaJson.put("id", vc.getURI());
|
||||
rootSchemaJson.put("name", vc.getName());
|
||||
rootSchemaJson.put("alias", new JSONArray());
|
||||
propertiesItemJson.put("schema", rootSchemaJson);
|
||||
// second level
|
||||
propertiesItemJson.put("id", prop.getURI());
|
||||
propertiesItemJson.put("name", nameStr);
|
||||
propertiesItemJson.put("alias", new JSONArray());
|
||||
|
||||
JSONObject expectsJson = new JSONObject();
|
||||
expectsJson.put("id", prop.getURI());
|
||||
expectsJson.put("name", nameStr);
|
||||
expectsJson.put("alias", new JSONArray());
|
||||
propertiesItemJson.put("expects", expectsJson);
|
||||
|
||||
propertiesJsonArr.put(propertiesItemJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get data properties from subclasses
|
||||
List<VClass> lvl2Classes = new ArrayList<VClass>();
|
||||
List roots = null;
|
||||
String requestType = vreq.getParameter("type");
|
||||
if (requestType != null) {
|
||||
roots = new LinkedList<VClass>();
|
||||
roots.add(vcDao.getVClassByURI(requestType));
|
||||
}
|
||||
|
||||
if (roots != null) {
|
||||
String ontologyUri = null;
|
||||
Collections.sort(roots);
|
||||
Iterator rootIt = roots.iterator();
|
||||
if (rootIt.hasNext()) {
|
||||
while (rootIt.hasNext()) {
|
||||
VClass root = (VClass) rootIt.next();
|
||||
if (root != null) {
|
||||
List<VClass> lvl2ChildClasses = new ArrayList<VClass>();
|
||||
addChildren(vcDao, vreq.getFullWebappDaoFactory(), root, lvl2ChildClasses, 0, ontologyUri);
|
||||
lvl2Classes.addAll(lvl2ChildClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (VClass lvl2Class: lvl2Classes) {
|
||||
HashMap<VClass, List<DataProperty>> lvl2ClassPropertiesMap =
|
||||
populateClassPropertiesMap(vcDao, dao, lvl2Class.getURI(), propURIs);
|
||||
if (lvl2ClassPropertiesMap.size() > 0) {
|
||||
for (Iterator<VClass> iter = lvl2ClassPropertiesMap.keySet().iterator(); iter.hasNext();) { // add results to schema
|
||||
VClass vc = (VClass) iter.next();
|
||||
ArrayList<DataProperty> vcProps = (ArrayList<DataProperty>)lvl2ClassPropertiesMap.get(vc);
|
||||
for (DataProperty prop: vcProps) {
|
||||
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||
// top level
|
||||
JSONObject propertiesItemJson = new JSONObject();
|
||||
|
||||
JSONObject rootSchemaJson = new JSONObject();
|
||||
rootSchemaJson.put("id", topClass.getURI());
|
||||
rootSchemaJson.put("name", topClass.getName());
|
||||
rootSchemaJson.put("alias", new JSONArray());
|
||||
propertiesItemJson.put("schema", rootSchemaJson);
|
||||
|
||||
// second level
|
||||
propertiesItemJson.put("id", vc.getURI());
|
||||
propertiesItemJson.put("name", vc.getName());
|
||||
propertiesItemJson.put("alias", new JSONArray());
|
||||
|
||||
propertiesItemJson.put("id2", prop.getURI());
|
||||
propertiesItemJson.put("name2", nameStr);
|
||||
propertiesItemJson.put("alias2", new JSONArray());
|
||||
|
||||
JSONObject expectsJson = new JSONObject();
|
||||
expectsJson.put("id", prop.getURI());
|
||||
expectsJson.put("name", nameStr);
|
||||
expectsJson.put("alias", new JSONArray());
|
||||
propertiesItemJson.put("expects", expectsJson);
|
||||
|
||||
propertiesJsonArr.put(propertiesItemJson);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
completeJson.put("properties", propertiesJsonArr);
|
||||
out.print(callbackStr + "(" + completeJson.toString() + ")");
|
||||
|
||||
|
||||
|
||||
} catch (Exception ex) {
|
||||
log.warn(ex, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private HashMap<VClass, List<DataProperty>> populateClassPropertiesMap (
|
||||
VClassDao vcDao,
|
||||
DataPropertyDao dao,
|
||||
String uri,
|
||||
HashSet<String> propURIs) {
|
||||
|
||||
HashMap<VClass, List<DataProperty>> classPropertiesMap = new HashMap<VClass, List<DataProperty>>();
|
||||
List<DataProperty> props = new ArrayList<DataProperty>();
|
||||
VClass topVc = vcDao.getVClassByURI(uri);
|
||||
Collection <DataProperty> dataProps = dao.getDataPropertiesForVClass(uri);
|
||||
Iterator<DataProperty> dataPropIt = dataProps.iterator();
|
||||
while (dataPropIt.hasNext()) {
|
||||
DataProperty dp = dataPropIt.next();
|
||||
if (!(propURIs.contains(dp.getURI()))) {
|
||||
propURIs.add(dp.getURI());
|
||||
DataProperty prop = dao.getDataPropertyByURI(dp.getURI());
|
||||
if (prop != null) {
|
||||
props.add(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (props.size() > 0) {
|
||||
|
||||
Collections.sort(props);
|
||||
for (DataProperty prop: props) {
|
||||
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||
if (nameStr != null) {
|
||||
if (prop.getDomainClassURI() != null) {
|
||||
VClass vc = vcDao.getVClassByURI(prop.getDomainClassURI());
|
||||
if (classPropertiesMap.get(vc) != null) {
|
||||
ArrayList<DataProperty> existingList = (ArrayList<DataProperty>)classPropertiesMap.get(vc);
|
||||
existingList.add(prop);
|
||||
} else {
|
||||
ArrayList<DataProperty> newList = new ArrayList<DataProperty>();
|
||||
newList.add(prop);
|
||||
classPropertiesMap.put(vc, newList);
|
||||
}
|
||||
|
||||
} else { // some properties have no domain, belong to top vc by default
|
||||
if (classPropertiesMap.get(topVc) != null) {
|
||||
ArrayList<DataProperty> existingList = (ArrayList<DataProperty>)classPropertiesMap.get(topVc);
|
||||
existingList.add(prop);
|
||||
} else {
|
||||
ArrayList<DataProperty> newList = new ArrayList<DataProperty>();
|
||||
newList.add(prop);
|
||||
classPropertiesMap.put(topVc, newList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return classPropertiesMap;
|
||||
}
|
||||
|
||||
private void addChildren(VClassDao vcDao, WebappDaoFactory wadf, VClass parent, List<VClass> list, int position, String ontologyUri) {
|
||||
List<VClass> rowElts = addVClassDataToResultsList(wadf, parent, position, ontologyUri);
|
||||
int childShift = (rowElts.size() > 0) ? 1 : 0; // if addVClassDataToResultsList filtered out the result, don't shift the children over
|
||||
list.addAll(rowElts);
|
||||
List childURIstrs = vcDao.getSubClassURIs(parent.getURI());
|
||||
if ((childURIstrs.size()>0) && position<MAXDEPTH) {
|
||||
List childClasses = new ArrayList();
|
||||
Iterator childURIstrIt = childURIstrs.iterator();
|
||||
while (childURIstrIt.hasNext()) {
|
||||
String URIstr = (String) childURIstrIt.next();
|
||||
try {
|
||||
VClass child = (VClass) vcDao.getVClassByURI(URIstr);
|
||||
if (!child.getURI().equals(OWL.Nothing.getURI())) {
|
||||
childClasses.add(child);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
Collections.sort(childClasses);
|
||||
Iterator childClassIt = childClasses.iterator();
|
||||
while (childClassIt.hasNext()) {
|
||||
VClass child = (VClass) childClassIt.next();
|
||||
addChildren(vcDao, wadf, child, list, position + childShift, ontologyUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<VClass> addVClassDataToResultsList(WebappDaoFactory wadf, VClass vcw, int position, String ontologyUri) {
|
||||
List<VClass> results = new ArrayList<VClass>();
|
||||
if (ontologyUri == null || ( (vcw.getNamespace()!=null) && (vcw.getNamespace().equals(ontologyUri)) ) ) {
|
||||
results.add(vcw);
|
||||
|
||||
/*
|
||||
for (int i=0; i<position; i++) {
|
||||
results.add("@@entities");
|
||||
}
|
||||
if (position==0)
|
||||
results.add("XX"); // column 1
|
||||
Integer numCols = (NUM_COLS-1)-position;
|
||||
|
||||
try {
|
||||
numCols = addColToResults(((vcw.getLocalNameWithPrefix() == null) ? "" : "<a href=\"vclassEdit?uri="+URLEncoder.encode(vcw.getURI(),"UTF-8")+"\">"+vcw.getLocalNameWithPrefix()+"</a>"), results, numCols);
|
||||
} catch (Exception e) {
|
||||
numCols = addColToResults(((vcw.getLocalNameWithPrefix() == null) ? "" : vcw.getLocalNameWithPrefix()), results, numCols); // column 2
|
||||
}
|
||||
numCols = addColToResults(((vcw.getShortDef() == null) ? "" : vcw.getShortDef()), results, numCols); // column 3
|
||||
numCols = addColToResults(((vcw.getExample() == null) ? "" : vcw.getExample()), results, numCols); // column 4
|
||||
|
||||
// Get group name if it exists
|
||||
VClassGroupDao groupDao= wadf.getVClassGroupDao();
|
||||
String groupURI = vcw.getGroupURI();
|
||||
String groupName = null;
|
||||
VClassGroup classGroup = null;
|
||||
if(groupURI != null) {
|
||||
classGroup = groupDao.getGroupByURI(groupURI);
|
||||
if (classGroup != null) {
|
||||
groupName = classGroup.getPublicName();
|
||||
}
|
||||
}
|
||||
numCols = addColToResults(((groupName == null) ? "" : groupName), results, numCols); // column 5
|
||||
|
||||
// Get ontology name
|
||||
String ontName = null;
|
||||
try {
|
||||
OntologyDao ontDao = wadf.getOntologyDao();
|
||||
Ontology ont = ontDao.getOntologyByURI(vcw.getNamespace());
|
||||
ontName = ont.getName();
|
||||
} catch (Exception e) {}
|
||||
numCols = addColToResults(((ontName == null) ? "" : ontName), results, numCols); // column 6
|
||||
|
||||
numCols = addColToResults(vcw.getHiddenFromDisplayBelowRoleLevel() == null ? "unspecified" : vcw.getHiddenFromDisplayBelowRoleLevel().getShorthand(), results, numCols); // column 7
|
||||
numCols = addColToResults(vcw.getProhibitedFromUpdateBelowRoleLevel() == null ? "unspecified" : vcw.getProhibitedFromUpdateBelowRoleLevel().getShorthand(), results, numCols); // column 8
|
||||
|
||||
results.add("XX"); // column 9
|
||||
*/
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private Integer addColToResults (String value, List results, Integer colIndex) {
|
||||
if (colIndex>0) {
|
||||
results.add(value);
|
||||
}
|
||||
return colIndex-1;
|
||||
}
|
||||
|
||||
protected JSONObject getResult(VitroRequest vreq, HttpServletRequest req,
|
||||
HttpServletResponse resp) throws ServletException {
|
||||
|
||||
HashMap<String, JSONObject> searchWithTypeMap = new HashMap<String, JSONObject>();
|
||||
HashMap<String, JSONObject> searchNoTypeMap = new HashMap<String, JSONObject>();
|
||||
ArrayList<String> queries = new ArrayList<String>();
|
||||
Object qObj = vreq.getParameter("queries");
|
||||
|
||||
if (qObj == null) {
|
||||
qObj = vreq.getParameter("query");
|
||||
}
|
||||
|
||||
if (qObj != null && qObj instanceof String) {
|
||||
// e.g.
|
||||
// {"q0":{"query":"Cathleen","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"},
|
||||
// "q1":{"query":"Geoffrey","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"},
|
||||
// "q2":{"query":"Dina","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"}}
|
||||
String qStr = (String) qObj;
|
||||
queries.add(qStr);
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < queries.size(); i++) {
|
||||
String queryStr = (String) queries.get(i);
|
||||
JSONObject json = new JSONObject(queryStr);
|
||||
|
||||
if (json.has("query")) { // single query
|
||||
if (json.has("type")) {
|
||||
searchWithTypeMap.put("query", json);
|
||||
} else {
|
||||
// user did not specify a type
|
||||
searchNoTypeMap.put("query", json);
|
||||
}
|
||||
} else { // multiple queries
|
||||
for (Iterator<String> iter = json.keys(); iter.hasNext();) {
|
||||
ArrayList<JSONObject> jsonList = new ArrayList<JSONObject>();
|
||||
String key = (String) iter.next();
|
||||
Object obj = json.get(key);
|
||||
JSONObject jsonLvl2 = (JSONObject) obj;
|
||||
if (jsonLvl2.has("query")) {
|
||||
if (jsonLvl2.has("type")) {
|
||||
searchWithTypeMap.put(key, jsonLvl2);
|
||||
} else {
|
||||
// user did not specify a type
|
||||
searchNoTypeMap.put(key, jsonLvl2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||
+ ex);
|
||||
}
|
||||
|
||||
// Run index search
|
||||
JSONObject qJson = null;
|
||||
if (searchWithTypeMap.size() > 0) {
|
||||
qJson = runSearch(searchWithTypeMap, vreq);
|
||||
} else {
|
||||
qJson = runSearch(searchNoTypeMap, vreq);
|
||||
}
|
||||
return qJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a default JSON response.
|
||||
*
|
||||
* @param req
|
||||
* @param resp
|
||||
* @return
|
||||
* @throws ServletException
|
||||
*/
|
||||
protected JSONObject getMetadata(HttpServletRequest req, HttpServletResponse resp, String defaultNamespace,
|
||||
String defaultTypeList, String serverName, int serverPort) throws ServletException {
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put("name", "VIVO Reconciliation Service");
|
||||
if (defaultNamespace != null) {
|
||||
json.put("identifierSpace", defaultNamespace);
|
||||
json.put("schemaSpace", defaultNamespace);
|
||||
}
|
||||
JSONObject viewJson = new JSONObject();
|
||||
StringBuffer urlBuf = new StringBuffer();
|
||||
urlBuf.append("http://" + serverName);
|
||||
if (serverPort == 8080) {
|
||||
urlBuf.append(":" + serverPort);
|
||||
}
|
||||
if (req.getContextPath() != null) {
|
||||
urlBuf.append(req.getContextPath());
|
||||
}
|
||||
viewJson.put("url", urlBuf.toString() + "/individual?uri={{id}}");
|
||||
json.put("view", viewJson);
|
||||
|
||||
// parse defaultTypeList from deploy.properties
|
||||
if (defaultTypeList != null) {
|
||||
String[] splitList = defaultTypeList.split(";");
|
||||
String[][] idNameArray = new String[splitList.length][splitList.length];
|
||||
for(int i = 0; i<splitList.length; i++) {
|
||||
idNameArray[i] = splitList[i].split(",");
|
||||
}
|
||||
// process and add to json defaultTypes
|
||||
JSONArray defaultTypesJsonArr = new JSONArray();
|
||||
for (int i = 0; i<idNameArray.length; i++) {
|
||||
JSONObject defaultTypesJson = new JSONObject();
|
||||
defaultTypesJson.put("id", idNameArray[i][0].trim());
|
||||
defaultTypesJson.put("name", idNameArray[i][1].trim());
|
||||
defaultTypesJsonArr.put(defaultTypesJson);
|
||||
}
|
||||
json.put("defaultTypes", defaultTypesJsonArr);
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
throw new ServletException(
|
||||
"JSONReconcileServlet: Could not create metadata: " + ex);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
private JSONObject runSearch(HashMap<String, JSONObject> currMap,
|
||||
VitroRequest vreq) throws ServletException {
|
||||
JSONObject qJson = new JSONObject();
|
||||
try {
|
||||
Analyzer analyzer = getAnalyzer(getServletContext());
|
||||
IndexSearcher searcherForRequest = LuceneIndexFactory
|
||||
.getIndexSearcher(getServletContext());
|
||||
|
||||
for (Map.Entry<String, JSONObject> entry : currMap.entrySet()) {
|
||||
JSONObject resultAllJson = new JSONObject();
|
||||
String key = entry.getKey();
|
||||
JSONObject json = (JSONObject) entry.getValue();
|
||||
String queryVal = json.getString("query");
|
||||
|
||||
// continue with properties list
|
||||
String searchType = null;
|
||||
int limit = 3; // default
|
||||
String typeStrict = "should"; // default
|
||||
ArrayList<String[]> propertiesList = new ArrayList<String[]>();
|
||||
|
||||
if (json.has("type")) {
|
||||
searchType = json.getString("type");
|
||||
}
|
||||
if (json.has("limit")) {
|
||||
limit = json.getInt("limit");
|
||||
}
|
||||
if (json.has("type_strict")) { // Not sure what this variable
|
||||
// represents. Skip for now.
|
||||
typeStrict = json.getString("type_strict");
|
||||
}
|
||||
if (json.has("properties")) {
|
||||
JSONArray properties = json.getJSONArray("properties");
|
||||
for (int i = 0; i < properties.length(); i++) {
|
||||
String[] pvPair = new String[2];
|
||||
JSONObject jsonProperty = properties.getJSONObject(i);
|
||||
String pid = jsonProperty.getString("pid");
|
||||
String v = jsonProperty.getString("v");
|
||||
pvPair[0] = pid;
|
||||
pvPair[1] = v;
|
||||
propertiesList.add(pvPair);
|
||||
}
|
||||
}
|
||||
|
||||
// begin search
|
||||
JSONArray resultJsonArr = new JSONArray();
|
||||
Query query = getReconcileQuery(vreq, analyzer,
|
||||
queryVal, searchType, propertiesList);
|
||||
|
||||
TopDocs topDocs = searcherForRequest.search(query, null, limit);
|
||||
if (topDocs != null && topDocs.scoreDocs != null) {
|
||||
int hitsLength = topDocs.scoreDocs.length;
|
||||
if (hitsLength > 0) {
|
||||
for (int i = 0; i < topDocs.scoreDocs.length; i++) {
|
||||
JSONObject resultJson = new JSONObject();
|
||||
float score = topDocs.scoreDocs[i].score;
|
||||
resultJson.put("score", score);
|
||||
|
||||
Document doc = searcherForRequest
|
||||
.doc(topDocs.scoreDocs[i].doc);
|
||||
String uri = doc.get(Entity2LuceneDoc.term.URI);
|
||||
IndividualDao iDao = vreq.getWebappDaoFactory()
|
||||
.getIndividualDao();
|
||||
Individual ind = iDao.getIndividualByURI(uri);
|
||||
if (ind != null) {
|
||||
String name = ind.getName();
|
||||
// encode # to %23
|
||||
String modUri = uri.replace("#", "%23");
|
||||
resultJson.put("id", modUri);
|
||||
resultJson.put("name", name);
|
||||
}
|
||||
List fields = doc.getFields();
|
||||
JSONArray typesJsonArr = new JSONArray();
|
||||
for (int j = 0; j < fields.size(); j++) {
|
||||
Field field = (Field) fields.get(j);
|
||||
String fieldName = field.name();
|
||||
if ("type".equals(fieldName)) {
|
||||
// e.g. http://aims.fao.org/aos/geopolitical.owl#area
|
||||
String type = field.stringValue();
|
||||
int lastIndex2 = type.lastIndexOf('/') + 1;
|
||||
String typeName = type
|
||||
.substring(lastIndex2);
|
||||
typeName = typeName.replace("#", ":");
|
||||
JSONObject typesJson = new JSONObject();
|
||||
typesJson.put("id", type);
|
||||
typesJson.put("name", typeName);
|
||||
typesJsonArr.put(typesJson);
|
||||
}
|
||||
}
|
||||
resultJson.put("type", typesJsonArr);
|
||||
resultJson.put("match", "false");
|
||||
resultJsonArr.put(resultJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultAllJson.put("result", resultJsonArr);
|
||||
qJson.put(key, resultAllJson);
|
||||
}
|
||||
|
||||
} catch (JSONException ex) {
|
||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||
+ ex);
|
||||
} catch (SearchException ex) {
|
||||
System.err.println("JSONReconcileServlet SearchException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet SearchException: "
|
||||
+ ex);
|
||||
} catch (IOException ex) {
|
||||
System.err.println("JSONReconcileServlet IOException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet IOException: "
|
||||
+ ex);
|
||||
}
|
||||
|
||||
return qJson;
|
||||
}
|
||||
|
||||
private Analyzer getAnalyzer(ServletContext servletContext)
|
||||
throws SearchException {
|
||||
Object obj = servletContext.getAttribute(LuceneSetup.ANALYZER);
|
||||
if (obj == null || !(obj instanceof Analyzer))
|
||||
throw new SearchException("Could not get anlyzer");
|
||||
else
|
||||
return (Analyzer) obj;
|
||||
}
|
||||
|
||||
private Query makeReconcileNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||
|
||||
/* Original code
|
||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||
boolean tokenize = "true".equals(tokenizeParam);
|
||||
|
||||
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
||||
// query will not be stemmed. So we don't look at the stem parameter until we get to
|
||||
// makeTokenizedNameQuery().
|
||||
if (tokenize) {
|
||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||
} else {
|
||||
return makeUntokenizedNameQuery(querystr);
|
||||
}
|
||||
*/
|
||||
|
||||
// modified code for reconciliation service
|
||||
request.setAttribute("stem", true);
|
||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||
}
|
||||
|
||||
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||
|
||||
String stemParam = (String) request.getParameter("stem");
|
||||
boolean stem = "true".equals(stemParam);
|
||||
String termName = stem ? VitroLuceneTermNames.NAME_STEMMED : VitroLuceneTermNames.NAME_UNSTEMMED;
|
||||
|
||||
BooleanQuery boolQuery = new BooleanQuery();
|
||||
|
||||
// Use the query parser to analyze the search term the same way the indexed text was analyzed.
|
||||
// For example, text is lowercased, and function words are stripped out.
|
||||
QueryParser parser = getQueryParser(termName, analyzer);
|
||||
|
||||
// The wildcard query doesn't play well with stemming. Query term name:tales* doesn't match
|
||||
// "tales", which is indexed as "tale", while query term name:tales does. Obviously we need
|
||||
// the wildcard for name:tal*, so the only way to get them all to match is use a disjunction
|
||||
// of wildcard and non-wildcard queries. The query will look have only an implicit disjunction
|
||||
// operator: e.g., +(name:tales name:tales*)
|
||||
try {
|
||||
log.debug("Adding non-wildcard query for " + querystr);
|
||||
Query query = parser.parse(querystr);
|
||||
boolQuery.add(query, BooleanClause.Occur.SHOULD);
|
||||
|
||||
// Prevent ParseException here when adding * after a space.
|
||||
// If there's a space at the end, we don't need the wildcard query.
|
||||
if (! querystr.endsWith(" ")) {
|
||||
log.debug("Adding wildcard query for " + querystr);
|
||||
Query wildcardQuery = parser.parse(querystr + "*");
|
||||
boolQuery.add(wildcardQuery, BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
||||
log.debug("Name query is: " + boolQuery.toString());
|
||||
} catch (ParseException e) {
|
||||
log.warn(e, e);
|
||||
}
|
||||
|
||||
|
||||
return boolQuery;
|
||||
}
|
||||
|
||||
private Query makeUntokenizedNameQuery(String querystr) {
|
||||
|
||||
querystr = querystr.toLowerCase();
|
||||
String termName = VitroLuceneTermNames.NAME_LOWERCASE;
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
log.debug("Adding wildcard query on unanalyzed name");
|
||||
query.add(
|
||||
new WildcardQuery(new Term(termName, querystr + "*")),
|
||||
BooleanClause.Occur.MUST);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private QueryParser getQueryParser(String searchField, Analyzer analyzer){
|
||||
// searchField indicates which field to search against when there is no term
|
||||
// indicated in the query string.
|
||||
// The analyzer is needed so that we use the same analyzer on the search queries as
|
||||
// was used on the text that was indexed.
|
||||
QueryParser qp = new QueryParser(searchField,analyzer);
|
||||
//this sets the query parser to AND all of the query terms it finds.
|
||||
qp.setDefaultOperator(QueryParser.AND_OPERATOR);
|
||||
return qp;
|
||||
}
|
||||
|
||||
private Query getReconcileQuery(VitroRequest request, Analyzer analyzer,
|
||||
String querystr, String typeParam, ArrayList<String[]> propertiesList) throws SearchException{
|
||||
|
||||
Query query = null;
|
||||
try {
|
||||
if( querystr == null){
|
||||
log.error("There was no Parameter '"+ QUERY_PARAMETER_NAME
|
||||
+"' in the request.");
|
||||
return null;
|
||||
}else if( querystr.length() > MAX_QUERY_LENGTH ){
|
||||
log.debug("The search was too long. The maximum " +
|
||||
"query length is " + MAX_QUERY_LENGTH );
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
query = makeReconcileNameQuery(querystr, analyzer, request);
|
||||
|
||||
|
||||
// filter by type
|
||||
if (typeParam != null) {
|
||||
BooleanQuery boolQuery = new BooleanQuery();
|
||||
boolQuery.add( new TermQuery(
|
||||
new Term(VitroLuceneTermNames.RDFTYPE,
|
||||
typeParam)),
|
||||
BooleanClause.Occur.MUST);
|
||||
boolQuery.add(query, BooleanClause.Occur.MUST);
|
||||
query = boolQuery;
|
||||
}
|
||||
|
||||
// if propertiesList has elements, add extra queries to query
|
||||
Iterator<String[]> it = propertiesList.iterator();
|
||||
while (it.hasNext()) {
|
||||
String[] pvPair = it.next();
|
||||
Query extraQuery = makeReconcileNameQuery(pvPair[1], analyzer, request);
|
||||
if (!"".equals(pvPair[0]) && pvPair[0] != null) {
|
||||
BooleanQuery boolQuery = new BooleanQuery();
|
||||
boolQuery.add(new TermQuery(new Term(
|
||||
VitroLuceneTermNames.RDFTYPE, pvPair[0])),
|
||||
BooleanClause.Occur.MUST);
|
||||
boolQuery.add(extraQuery, BooleanClause.Occur.MUST);
|
||||
extraQuery = boolQuery;
|
||||
}
|
||||
((BooleanQuery)query).add(extraQuery, BooleanClause.Occur.MUST);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new SearchException(ex.getMessage());
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import javax.servlet.ServletOutputStream;
|
|||
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 org.apache.lucene.analysis.Analyzer;
|
||||
|
@ -53,7 +54,8 @@ import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup;
|
|||
*/
|
||||
public class JSONReconcileServlet extends VitroHttpServlet {
|
||||
|
||||
private static String QUERY_PARAMETER_NAME = "term";
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static String QUERY_PARAMETER_NAME = "term";
|
||||
public static final int MAX_QUERY_LENGTH = 500;
|
||||
private static final Log log = LogFactory.getLog(JSONReconcileServlet.class.getName());
|
||||
|
||||
|
@ -70,14 +72,14 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
super.doGet(req, resp);
|
||||
resp.setContentType("application/json");
|
||||
VitroRequest vreq = new VitroRequest(req);
|
||||
System.out.println("vreq");
|
||||
System.out.println(vreq.getWebappDaoFactory());
|
||||
//log.debug("vreq");
|
||||
//log.debug(vreq.getWebappDaoFactory());
|
||||
|
||||
try {
|
||||
if (vreq.getParameter("query") != null
|
||||
|| vreq.getParameter("queries") != null) {
|
||||
JSONObject qJson = getResult(vreq, req, resp);
|
||||
System.out.println("result: " + qJson.toString());
|
||||
log.debug("result: " + qJson.toString());
|
||||
String responseStr = (vreq.getParameter("callback") == null) ? qJson
|
||||
.toString() : vreq.getParameter("callback") + "("
|
||||
+ qJson.toString() + ")";
|
||||
|
@ -124,8 +126,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
// "q2":{"query":"Dina","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"}}
|
||||
String qStr = (String) qObj;
|
||||
queries.add(qStr);
|
||||
System.out.println();
|
||||
System.out.println("query: " + qStr + "\n");
|
||||
log.debug("\nquery: " + qStr + "\n");
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -158,7 +159,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
||||
log.error("JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||
+ ex);
|
||||
}
|
||||
|
@ -327,15 +328,15 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
} catch (JSONException ex) {
|
||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
||||
log.error("JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||
+ ex);
|
||||
} catch (SearchException ex) {
|
||||
System.err.println("JSONReconcileServlet SearchException: " + ex);
|
||||
log.error("SearchException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet SearchException: "
|
||||
+ ex);
|
||||
} catch (IOException ex) {
|
||||
System.err.println("JSONReconcileServlet IOException: " + ex);
|
||||
log.error("IOException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet IOException: "
|
||||
+ ex);
|
||||
}
|
||||
|
@ -354,30 +355,12 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
|
||||
private Query makeReconcileNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||
|
||||
/* Original code
|
||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||
boolean tokenize = "true".equals(tokenizeParam);
|
||||
|
||||
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
||||
// query will not be stemmed. So we don't look at the stem parameter until we get to
|
||||
// makeTokenizedNameQuery().
|
||||
if (tokenize) {
|
||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||
} else {
|
||||
return makeUntokenizedNameQuery(querystr);
|
||||
}
|
||||
*/
|
||||
|
||||
// modified code for reconciliation service
|
||||
request.setAttribute("stem", true);
|
||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||
}
|
||||
|
||||
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||
|
||||
String stemParam = (String) request.getParameter("stem");
|
||||
boolean stem = "true".equals(stemParam);
|
||||
String termName = stem ? VitroLuceneTermNames.NAME_STEMMED : VitroLuceneTermNames.NAME_UNSTEMMED;
|
||||
|
||||
String termName = VitroLuceneTermNames.NAME_STEMMED;
|
||||
|
||||
BooleanQuery boolQuery = new BooleanQuery();
|
||||
|
||||
|
@ -407,23 +390,9 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
} catch (ParseException e) {
|
||||
log.warn(e, e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return boolQuery;
|
||||
}
|
||||
|
||||
private Query makeUntokenizedNameQuery(String querystr) {
|
||||
|
||||
querystr = querystr.toLowerCase();
|
||||
String termName = VitroLuceneTermNames.NAME_LOWERCASE;
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
log.debug("Adding wildcard query on unanalyzed name");
|
||||
query.add(
|
||||
new WildcardQuery(new Term(termName, querystr + "*")),
|
||||
BooleanClause.Occur.MUST);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private QueryParser getQueryParser(String searchField, Analyzer analyzer){
|
||||
// searchField indicates which field to search against when there is no term
|
||||
|
@ -450,10 +419,8 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
"query length is " + MAX_QUERY_LENGTH );
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
query = makeReconcileNameQuery(querystr, analyzer, request);
|
||||
|
||||
|
||||
// filter by type
|
||||
if (typeParam != null) {
|
||||
|
@ -471,7 +438,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
while (it.hasNext()) {
|
||||
String[] pvPair = it.next();
|
||||
Query extraQuery = makeReconcileNameQuery(pvPair[1], analyzer, request);
|
||||
if (!"".equals(pvPair[0]) && pvPair[0] != null) {
|
||||
if ( ! StringUtils.isEmpty(pvPair[0]) ) {
|
||||
BooleanQuery boolQuery = new BooleanQuery();
|
||||
boolQuery.add(new TermQuery(new Term(
|
||||
VitroLuceneTermNames.RDFTYPE, pvPair[0])),
|
||||
|
@ -489,3 +456,4 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class UserAccountsSelector {
|
|||
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
||||
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n";
|
||||
|
||||
private static final String ALL_VARIABLES = "?uri ?email ?firstName ?lastName ?pwd ?expire ?count ?status";
|
||||
private static final String ALL_VARIABLES = "?uri ?email ?firstName ?lastName ?pwd ?expire ?count ?status ?isRoot";
|
||||
|
||||
private static final String COUNT_VARIABLE = "?uri";
|
||||
|
||||
|
@ -169,7 +169,8 @@ public class UserAccountsSelector {
|
|||
+ " OPTIONAL { ?uri auth:md5password ?pwd } \n"
|
||||
+ " OPTIONAL { ?uri auth:passwordChangeExpires ?expire } \n"
|
||||
+ " OPTIONAL { ?uri auth:loginCount ?count } \n"
|
||||
+ " OPTIONAL { ?uri auth:status ?status }";
|
||||
+ " OPTIONAL { ?uri auth:status ?status } \n"
|
||||
+ " OPTIONAL { ?uri ?isRoot auth:RootUserAccount }";
|
||||
}
|
||||
|
||||
private String filterClauses() {
|
||||
|
@ -201,11 +202,10 @@ public class UserAccountsSelector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Escape any regex special characters in the string.
|
||||
* Escape any regex special characters in the string.
|
||||
*
|
||||
* Note that the SPARQL
|
||||
* parser requires two backslashes, in order to pass a single backslash to
|
||||
* the REGEX function.
|
||||
* Note that the SPARQL parser requires two backslashes, in order to pass a
|
||||
* single backslash to the REGEX function.
|
||||
*/
|
||||
private String escapeForRegex(String raw) {
|
||||
StringBuilder clean = new StringBuilder();
|
||||
|
@ -327,6 +327,7 @@ public class UserAccountsSelector {
|
|||
user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L));
|
||||
user.setLoginCount(ifIntPresent(solution, "count", 0));
|
||||
user.setStatus(parseStatus(solution, "status", null));
|
||||
user.setRootUser(solution.contains("isRoot"));
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
|||
public class UserAccountsAddPage extends UserAccountsPage {
|
||||
private static final String PARAMETER_SUBMIT = "submitAdd";
|
||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||
private static final String PARAMETER_ROLE = "role";
|
||||
|
@ -30,6 +31,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
|
||||
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
|
||||
private static final String ERROR_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
|
||||
private static final String ERROR_EXTERNAL_AUTH_ID_IN_USE = "errorExternalAuthIdInUse";
|
||||
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
|
||||
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
|
||||
private static final String ERROR_NO_ROLE = "errorNoRoleSelected";
|
||||
|
@ -41,6 +43,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
/* The request parameters */
|
||||
private boolean submit;
|
||||
private String emailAddress = "";
|
||||
private String externalAuthId = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
private String selectedRoleUri = "";
|
||||
|
@ -68,6 +71,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||
|
@ -88,6 +92,8 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
errorCode = ERROR_EMAIL_IN_USE;
|
||||
} else if (!isEmailValidFormat()) {
|
||||
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
||||
} else if (isExternalAuthIdInUse()) {
|
||||
errorCode = ERROR_EXTERNAL_AUTH_ID_IN_USE;
|
||||
} else if (firstName.isEmpty()) {
|
||||
errorCode = ERROR_NO_FIRST_NAME;
|
||||
} else if (lastName.isEmpty()) {
|
||||
|
@ -103,10 +109,17 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
|
||||
}
|
||||
|
||||
private boolean isExternalAuthIdInUse() {
|
||||
if (externalAuthId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId) != null;
|
||||
}
|
||||
|
||||
private boolean isEmailValidFormat() {
|
||||
return Authenticator.isValidEmailAddress(emailAddress);
|
||||
}
|
||||
|
||||
|
||||
public boolean isValid() {
|
||||
return errorCode.isEmpty();
|
||||
}
|
||||
|
@ -116,7 +129,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
u.setEmailAddress(emailAddress);
|
||||
u.setFirstName(firstName);
|
||||
u.setLastName(lastName);
|
||||
u.setExternalAuthId("");
|
||||
u.setExternalAuthId(externalAuthId);
|
||||
|
||||
u.setMd5Password("");
|
||||
u.setOldPassword("");
|
||||
|
@ -139,6 +152,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("emailAddress", emailAddress);
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("firstName", firstName);
|
||||
body.put("lastName", lastName);
|
||||
body.put("selectedRole", selectedRoleUri);
|
||||
|
|
|
@ -57,6 +57,7 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
|
||||
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
||||
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-acctCreatedEmail.ftl";
|
||||
|
||||
private boolean sentEmail;
|
||||
|
||||
|
@ -91,15 +92,14 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", page.getAddedAccount());
|
||||
body.put("passwordLink", buildCreatePasswordLink());
|
||||
body.put("subjectLine", "Your VIVO account has been created.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
|
||||
email.setSubject("Your VIVO account has been created.");
|
||||
email.setHtmlTemplate("userAccounts-acctCreatedEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-acctCreatedEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
|
||||
sentEmail = true;
|
||||
|
|
|
@ -57,9 +57,9 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
if (page.isSubmit() && page.isValid()) {
|
||||
page.createNewAccount();
|
||||
|
||||
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
|
||||
return listPage.showPageWithNewAccount(page.getAddedAccount(),
|
||||
page.wasPasswordEmailSent());
|
||||
UserAccountsListPage.Message.showNewAccount(vreq,
|
||||
page.getAddedAccount(), page.wasPasswordEmailSent());
|
||||
return redirectToList();
|
||||
} else {
|
||||
return page.showPage();
|
||||
}
|
||||
|
@ -71,9 +71,10 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
return showHomePage(vreq, page.getBogusMessage());
|
||||
} else if (page.isSubmit() && page.isValid()) {
|
||||
page.updateAccount();
|
||||
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
|
||||
return listPage.showPageWithUpdatedAccount(
|
||||
|
||||
UserAccountsListPage.Message.showUpdatedAccount(vreq,
|
||||
page.getUpdatedAccount(), page.wasPasswordEmailSent());
|
||||
return redirectToList();
|
||||
} else {
|
||||
return page.showPage();
|
||||
}
|
||||
|
@ -83,8 +84,8 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
UserAccountsDeleter deleter = new UserAccountsDeleter(vreq);
|
||||
Collection<String> deletedUris = deleter.delete();
|
||||
|
||||
return new UserAccountsListPage(vreq)
|
||||
.showPageWithDeletions(deletedUris);
|
||||
UserAccountsListPage.Message.showDeletions(vreq, deletedUris);
|
||||
return redirectToList();
|
||||
}
|
||||
|
||||
private ResponseValues handleListRequest(VitroRequest vreq) {
|
||||
|
@ -92,6 +93,14 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
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("/accountsAdmin/list");
|
||||
}
|
||||
|
||||
private ResponseValues showHomePage(VitroRequest vreq, String message) {
|
||||
DisplayMessage.setMessage(vreq, message);
|
||||
return new RedirectResponseValues("/");
|
||||
|
|
|
@ -28,6 +28,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
private static final String PARAMETER_SUBMIT = "submitEdit";
|
||||
private static final String PARAMETER_USER_URI = "editAccount";
|
||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||
private static final String PARAMETER_ROLE = "role";
|
||||
|
@ -36,6 +37,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
|
||||
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
|
||||
private static final String ERROR_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
|
||||
private static final String ERROR_EXTERNAL_AUTH_ID_IN_USE = "errorExternalAuthIdInUse";
|
||||
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
|
||||
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
|
||||
private static final String ERROR_NO_ROLE = "errorNoRoleSelected";
|
||||
|
@ -48,6 +50,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
private boolean submit;
|
||||
private String userUri = "";
|
||||
private String emailAddress = "";
|
||||
private String externalAuthId = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
private String selectedRoleUri = "";
|
||||
|
@ -79,6 +82,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
userUri = getStringParameter(PARAMETER_USER_URI, "");
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||
|
@ -117,11 +121,13 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
errorCode = ERROR_EMAIL_IN_USE;
|
||||
} else if (!isEmailValidFormat()) {
|
||||
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
||||
} else if (externalAuthIdIsChanged() && isExternalAuthIdInUse()) {
|
||||
errorCode = ERROR_EXTERNAL_AUTH_ID_IN_USE;
|
||||
} else if (firstName.isEmpty()) {
|
||||
errorCode = ERROR_NO_FIRST_NAME;
|
||||
} else if (lastName.isEmpty()) {
|
||||
errorCode = ERROR_NO_LAST_NAME;
|
||||
} else if (selectedRoleUri.isEmpty()) {
|
||||
} else if (!isRootUser() && selectedRoleUri.isEmpty()) {
|
||||
errorCode = ERROR_NO_ROLE;
|
||||
} else {
|
||||
errorCode = strategy.additionalValidations();
|
||||
|
@ -139,7 +145,22 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
private boolean isEmailValidFormat() {
|
||||
return Authenticator.isValidEmailAddress(emailAddress);
|
||||
}
|
||||
|
||||
|
||||
private boolean externalAuthIdIsChanged() {
|
||||
return !externalAuthId.equals(userAccount.getExternalAuthId());
|
||||
}
|
||||
|
||||
private boolean isExternalAuthIdInUse() {
|
||||
if (externalAuthId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId) != null;
|
||||
}
|
||||
|
||||
private boolean isRootUser() {
|
||||
return ((userAccount != null) && userAccount.isRootUser());
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return errorCode.isEmpty();
|
||||
}
|
||||
|
@ -149,16 +170,22 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
|
||||
if (isSubmit()) {
|
||||
body.put("emailAddress", emailAddress);
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("firstName", firstName);
|
||||
body.put("lastName", lastName);
|
||||
body.put("selectedRole", selectedRoleUri);
|
||||
} else {
|
||||
body.put("emailAddress", userAccount.getEmailAddress());
|
||||
body.put("externalAuthId", userAccount.getExternalAuthId());
|
||||
body.put("firstName", userAccount.getFirstName());
|
||||
body.put("lastName", userAccount.getLastName());
|
||||
body.put("selectedRole", getExistingRoleUri());
|
||||
}
|
||||
body.put("roles", buildRolesList());
|
||||
|
||||
if (!isRootUser()) {
|
||||
body.put("roles", buildRolesList());
|
||||
}
|
||||
|
||||
if (associateWithProfile) {
|
||||
body.put("associate", Boolean.TRUE);
|
||||
}
|
||||
|
@ -192,9 +219,14 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
userAccount.setEmailAddress(emailAddress);
|
||||
userAccount.setFirstName(firstName);
|
||||
userAccount.setLastName(lastName);
|
||||
userAccount.setExternalAuthId(externalAuthId);
|
||||
|
||||
userAccount
|
||||
.setPermissionSetUris(Collections.singleton(selectedRoleUri));
|
||||
if (isRootUser()) {
|
||||
userAccount.setPermissionSetUris(Collections.<String> emptySet());
|
||||
} else {
|
||||
userAccount.setPermissionSetUris(Collections
|
||||
.singleton(selectedRoleUri));
|
||||
}
|
||||
|
||||
strategy.setAdditionalProperties(userAccount);
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import java.net.URL;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||
|
@ -57,7 +57,8 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
|||
|
||||
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
||||
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
||||
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-resetPasswordEmail.ftl";
|
||||
|
||||
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
||||
|
||||
private boolean resetPassword;
|
||||
|
@ -102,19 +103,23 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
|||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", page.getUpdatedAccount());
|
||||
body.put("passwordLink", buildResetPasswordLink());
|
||||
body.put("subjectLine", "Reset password request");
|
||||
body.put("siteName", getSiteName());
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
||||
email.setSubject("Reset password request");
|
||||
email.setHtmlTemplate("userAccounts-resetPasswordEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-resetPasswordEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
|
||||
sentEmail = true;
|
||||
}
|
||||
|
||||
private String getSiteName() {
|
||||
ApplicationBean appBean = vreq.getAppBean();
|
||||
return appBean.getApplicationName();
|
||||
}
|
||||
|
||||
private String buildResetPasswordLink() {
|
||||
try {
|
||||
|
|
|
@ -11,6 +11,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
@ -19,12 +22,12 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
|||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Direction;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelection;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelectionCriteria;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Direction;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
|
||||
|
@ -91,55 +94,7 @@ public class UserAccountsListPage extends UserAccountsPage {
|
|||
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||
userAccountsModel, criteria);
|
||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* We just came from adding a new account. Show the list with a message.
|
||||
*/
|
||||
public ResponseValues showPageWithNewAccount(UserAccount userAccount,
|
||||
boolean emailWasSent) {
|
||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||
userAccountsModel, criteria);
|
||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||
|
||||
body.put("newUserAccount", new UserAccountWrapper(userAccount,
|
||||
Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* We just came from editing an account. Show the list with a message.
|
||||
*/
|
||||
public ResponseValues showPageWithUpdatedAccount(UserAccount userAccount,
|
||||
boolean emailWasSent) {
|
||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||
userAccountsModel, criteria);
|
||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||
|
||||
body.put("updatedUserAccount", new UserAccountWrapper(userAccount,
|
||||
Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* We just came from deleting accounts. Show the list with a message.
|
||||
*/
|
||||
public ResponseValues showPageWithDeletions(Collection<String> deletedUris) {
|
||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||
userAccountsModel, criteria);
|
||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||
|
||||
body.put("deletedAccountCount", deletedUris.size());
|
||||
|
||||
Message.applyToBodyMap(vreq, body);
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
|
@ -238,10 +193,15 @@ public class UserAccountsListPage extends UserAccountsPage {
|
|||
|
||||
private List<String> findPermissionSetLabels(UserAccount account) {
|
||||
List<String> labels = new ArrayList<String>();
|
||||
for (String uri : account.getPermissionSetUris()) {
|
||||
PermissionSet pSet = userAccountsDao.getPermissionSetByUri(uri);
|
||||
if (pSet != null) {
|
||||
labels.add(pSet.getLabel());
|
||||
|
||||
if (account.isRootUser()) {
|
||||
labels.add("ROOT");
|
||||
} else {
|
||||
for (String uri : account.getPermissionSetUris()) {
|
||||
PermissionSet pSet = userAccountsDao.getPermissionSetByUri(uri);
|
||||
if (pSet != null) {
|
||||
labels.add(pSet.getLabel());
|
||||
}
|
||||
}
|
||||
}
|
||||
return labels;
|
||||
|
@ -301,4 +261,84 @@ public class UserAccountsListPage extends UserAccountsPage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Message info that lives in the session. Another request can store this,
|
||||
* and it will be displayed (once) by the list page.
|
||||
*/
|
||||
public static class Message {
|
||||
private static final String ATTRIBUTE = Message.class.getName();
|
||||
private static final Collection<String> EMPTY = Collections.emptySet();
|
||||
|
||||
public static void showNewAccount(HttpServletRequest req,
|
||||
UserAccount userAccount, boolean emailWasSent) {
|
||||
Message message = new Message(Type.NEW_ACCOUNT, userAccount,
|
||||
emailWasSent, EMPTY);
|
||||
setMessage(req, message);
|
||||
}
|
||||
|
||||
public static void showUpdatedAccount(HttpServletRequest req,
|
||||
UserAccount userAccount, boolean emailWasSent) {
|
||||
Message message = new Message(Type.UPDATED_ACCOUNT, userAccount,
|
||||
emailWasSent, EMPTY);
|
||||
setMessage(req, message);
|
||||
}
|
||||
|
||||
public static void showDeletions(HttpServletRequest req,
|
||||
Collection<String> deletedUris) {
|
||||
Message message = new Message(Type.DELETIONS, null, false,
|
||||
deletedUris);
|
||||
setMessage(req, message);
|
||||
}
|
||||
|
||||
private static void setMessage(HttpServletRequest req, Message message) {
|
||||
req.getSession().setAttribute(ATTRIBUTE, message);
|
||||
}
|
||||
|
||||
public static void applyToBodyMap(HttpServletRequest req,
|
||||
Map<String, Object> body) {
|
||||
HttpSession session = req.getSession();
|
||||
Object o = session.getAttribute(ATTRIBUTE);
|
||||
session.removeAttribute(ATTRIBUTE);
|
||||
|
||||
if (o instanceof Message) {
|
||||
((Message) o).applyToBodyMap(body);
|
||||
}
|
||||
}
|
||||
|
||||
enum Type {
|
||||
NEW_ACCOUNT, UPDATED_ACCOUNT, DELETIONS
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
private final UserAccount userAccount;
|
||||
private final boolean emailWasSent;
|
||||
private final Collection<String> deletedUris;
|
||||
|
||||
public Message(Type type, UserAccount userAccount,
|
||||
boolean emailWasSent, Collection<String> deletedUris) {
|
||||
this.type = type;
|
||||
this.userAccount = userAccount;
|
||||
this.emailWasSent = emailWasSent;
|
||||
this.deletedUris = deletedUris;
|
||||
}
|
||||
|
||||
private void applyToBodyMap(Map<String, Object> body) {
|
||||
if (type == Type.NEW_ACCOUNT) {
|
||||
body.put("newUserAccount", new UserAccountWrapper(userAccount,
|
||||
Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
} else if (type == Type.UPDATED_ACCOUNT) {
|
||||
body.put("updatedUserAccount", new UserAccountWrapper(
|
||||
userAccount, Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
} else {
|
||||
body.put("deletedAccountCount", deletedUris.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public class UserAccountsCreatePasswordPage extends
|
|||
.getLog(UserAccountsCreatePasswordPage.class);
|
||||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-passwordCreatedEmail.ftl";
|
||||
|
||||
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
|
@ -39,7 +40,7 @@ public class UserAccountsCreatePasswordPage extends
|
|||
userAccountsDao.updateUserAccount(userAccount);
|
||||
log.debug("Set password on '" + userAccount.getEmailAddress()
|
||||
+ "' to '" + newPassword + "'");
|
||||
|
||||
|
||||
notifyUser();
|
||||
}
|
||||
|
||||
|
@ -56,15 +57,14 @@ public class UserAccountsCreatePasswordPage extends
|
|||
private void notifyUser() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", userAccount);
|
||||
body.put("subjectLine", "Password successfully created.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||
email.setSubject("Password successfully created.");
|
||||
email.setHtmlTemplate("userAccounts-passwordCreatedEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-passwordCreatedEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Map;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
|
@ -22,13 +24,14 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
|||
* Handle the first-time login of an Externally Authenticated user who has no
|
||||
* UserAccount - let's create one!
|
||||
*
|
||||
* If they get here from the login, there should an externalAuthId waiting in
|
||||
* the session. Otherwise, they should get here by submitting the form, which
|
||||
* will have the externalAuthId as a hidden field.
|
||||
* If they get here from the login, there should be an ExternalLoginInfo waiting
|
||||
* in the session. Otherwise, they should get here by submitting the form, which
|
||||
* will have the info in hidden fields.
|
||||
*/
|
||||
public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||
private static final String PARAMETER_SUBMIT = "submit";
|
||||
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||
private static final String PARAMETER_AFTER_LOGIN_URL = "afterLoginUrl";
|
||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||
|
@ -41,23 +44,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-firstTimeExternal.ftl";
|
||||
|
||||
private static final String ATTRIBUTE_EXTERNAL_AUTH_ID = UserAccountsFirstTimeExternalPage.class
|
||||
private static final String ATTRIBUTE_EXTERNAL_LOGIN_INFO = UserAccountsFirstTimeExternalPage.class
|
||||
.getName();
|
||||
|
||||
/**
|
||||
* Let some other request set the External Auth ID before redirecting to
|
||||
* here.
|
||||
* Let some other request set the External Auth ID and the afterLogin URL
|
||||
* before redirecting to here.
|
||||
*/
|
||||
public static void setExternalAuthId(HttpServletRequest req,
|
||||
String externalAuthId) {
|
||||
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID,
|
||||
externalAuthId);
|
||||
public static void setExternalLoginInfo(HttpServletRequest req,
|
||||
String externalAuthId, String afterLoginUrl) {
|
||||
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO,
|
||||
new ExternalLoginInfo(externalAuthId, afterLoginUrl));
|
||||
}
|
||||
|
||||
private final UserAccountsFirstTimeExternalPageStrategy strategy;
|
||||
|
||||
private boolean submit = false;
|
||||
private String externalAuthId = "";
|
||||
private String afterLoginUrl = "";
|
||||
|
||||
private boolean submit = false;
|
||||
private String emailAddress = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
|
@ -71,7 +76,7 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
this.strategy = UserAccountsFirstTimeExternalPageStrategy.getInstance(
|
||||
vreq, this, isEmailEnabled());
|
||||
|
||||
checkSessionForExternalAuthId();
|
||||
checkSessionForExternalLoginInfo();
|
||||
if (externalAuthId.isEmpty()) {
|
||||
parseRequestParameters();
|
||||
}
|
||||
|
@ -83,20 +88,26 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkSessionForExternalAuthId() {
|
||||
private void checkSessionForExternalLoginInfo() {
|
||||
HttpSession session = vreq.getSession();
|
||||
|
||||
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
||||
session.removeAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
||||
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||
session.removeAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||
|
||||
if (o instanceof String) {
|
||||
externalAuthId = (String) o;
|
||||
if (o instanceof ExternalLoginInfo) {
|
||||
externalAuthId = ((ExternalLoginInfo) o).externalAuthId;
|
||||
afterLoginUrl = ((ExternalLoginInfo) o).afterLoginUrl;
|
||||
if (afterLoginUrl == null) {
|
||||
afterLoginUrl = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||
afterLoginUrl = getStringParameter(PARAMETER_AFTER_LOGIN_URL, "");
|
||||
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
|
@ -156,10 +167,12 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
public final ResponseValues showPage() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("afterLoginUrl", afterLoginUrl);
|
||||
|
||||
body.put("emailAddress", emailAddress);
|
||||
body.put("firstName", firstName);
|
||||
body.put("lastName", lastName);
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("formUrls", buildUrlsMap());
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
|
@ -191,4 +204,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
return u;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the afterLoginUrl is missing, go to the home page. If it is relative,
|
||||
* make sure it doesn't start with the cotext path.
|
||||
*/
|
||||
public String getAfterLoginUrl() {
|
||||
if (StringUtils.isEmpty(afterLoginUrl)) {
|
||||
return null;
|
||||
}
|
||||
return afterLoginUrl;
|
||||
}
|
||||
|
||||
private static class ExternalLoginInfo {
|
||||
final String externalAuthId;
|
||||
final String afterLoginUrl;
|
||||
|
||||
public ExternalLoginInfo(String externalAuthId, String afterLoginUrl) {
|
||||
this.externalAuthId = externalAuthId;
|
||||
this.afterLoginUrl = afterLoginUrl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
|||
public static class EmailStrategy extends
|
||||
UserAccountsFirstTimeExternalPageStrategy {
|
||||
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-firstTimeExternalEmail.ftl";
|
||||
|
||||
public EmailStrategy(VitroRequest vreq,
|
||||
UserAccountsFirstTimeExternalPage page) {
|
||||
super(vreq, page);
|
||||
|
@ -66,15 +68,14 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
|||
public void notifyUser(UserAccount ua) {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", ua);
|
||||
body.put("subjectLine", "Your VIVO account has been created.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, ua.getEmailAddress());
|
||||
email.setSubject("Your VIVO account has been created.");
|
||||
email.setHtmlTemplate("userAccounts-firstTimeExternalEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-firstTimeExternalEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,8 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
|||
|
||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-confirmEmailChangedEmail.ftl";
|
||||
|
||||
private final String originalEmail;
|
||||
|
||||
|
@ -167,15 +169,14 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
|||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", page.getUserAccount());
|
||||
body.put("subjectLine", "Your VIVO email account has been changed.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
||||
email.setSubject("Your VIVO email account has been changed.");
|
||||
email.setHtmlTemplate("userAccounts-confirmEmailChangedEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-confirmEmailChangedEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
|
||||
emailSent = true;
|
||||
|
|
|
@ -26,6 +26,8 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
|||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
||||
|
||||
private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetEmail.ftl";
|
||||
|
||||
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
@ -38,7 +40,7 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
|||
userAccountsDao.updateUserAccount(userAccount);
|
||||
log.debug("Set password on '" + userAccount.getEmailAddress()
|
||||
+ "' to '" + newPassword + "'");
|
||||
|
||||
|
||||
notifyUser();
|
||||
}
|
||||
|
||||
|
@ -55,15 +57,14 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
|||
private void notifyUser() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", userAccount);
|
||||
body.put("subjectLine", "Password changed.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||
email.setSubject("Password changed.");
|
||||
email.setHtmlTemplate("userAccounts-passwordResetEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-passwordResetEmail-text.ftl");
|
||||
email.setTemplate(EMAIL_TEMPLATE);
|
||||
email.setBodyMap(body);
|
||||
email.processTemplate();
|
||||
email.send();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
|||
|
||||
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||
|
@ -115,9 +115,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
UserAccount userAccount = page.createAccount();
|
||||
Authenticator auth = Authenticator.getInstance(vreq);
|
||||
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
||||
LoginProcessBean.removeBean(vreq);
|
||||
|
||||
return showLoginRedirection(vreq);
|
||||
return showLoginRedirection(vreq, page.getAfterLoginUrl());
|
||||
} else {
|
||||
return page.showPage();
|
||||
}
|
||||
|
@ -132,10 +130,31 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
return new RedirectResponseValues("/");
|
||||
}
|
||||
|
||||
private ResponseValues showLoginRedirection(VitroRequest vreq) {
|
||||
LoginRedirector lr = new LoginRedirector(vreq);
|
||||
private ResponseValues showLoginRedirection(VitroRequest vreq,
|
||||
String afterLoginUrl) {
|
||||
LoginRedirector lr = new LoginRedirector(vreq, afterLoginUrl);
|
||||
DisplayMessage.setMessage(vreq, lr.assembleWelcomeMessage());
|
||||
String uri = lr.getRedirectionUriForLoggedInUser();
|
||||
return new RedirectResponseValues(uri);
|
||||
return new RedirectResponseValues(stripContextPath(vreq, uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO The LoginRedirector gives a URI that includes the context path. But
|
||||
* the RedirectResponseValues wants a URI that does not include the context
|
||||
* path.
|
||||
*
|
||||
* Bridge the gap.
|
||||
*/
|
||||
private String stripContextPath(VitroRequest vreq, String uri) {
|
||||
if ((uri == null) || uri.isEmpty() || uri.equals(vreq.getContextPath())) {
|
||||
return "/";
|
||||
}
|
||||
if (uri.contains("://")) {
|
||||
return uri;
|
||||
}
|
||||
if (uri.startsWith(vreq.getContextPath() + '/')) {
|
||||
return uri.substring(vreq.getContextPath().length());
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,10 @@ public abstract class Authenticator {
|
|||
// ----------------------------------------------------------------------
|
||||
|
||||
/** Maximum inactive interval for a ordinary logged-in session, in seconds. */
|
||||
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 300;
|
||||
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 60 * 60;
|
||||
|
||||
/** Maximum inactive interval for a editor (or better) session, in seconds. */
|
||||
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000;
|
||||
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 60 * 60 * 8;
|
||||
|
||||
/**
|
||||
* Get the UserAccount for this external ID, or null if there is none.
|
||||
|
@ -96,8 +96,9 @@ public abstract class Authenticator {
|
|||
* <pre>
|
||||
* Record that the user has logged in, with all of the housekeeping that
|
||||
* goes with it:
|
||||
* - updating the user record
|
||||
* - setting login status and timeout limit in the session
|
||||
* - update the user record
|
||||
* - set login status and timeout limit in the session
|
||||
* - refresh the Identifiers on the request
|
||||
* - record the user in the session map
|
||||
* - notify other users of the model
|
||||
* </pre>
|
||||
|
@ -105,17 +106,6 @@ public abstract class Authenticator {
|
|||
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
||||
AuthenticationSource authSource);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Record that the user has logged in but with only external authentication
|
||||
* info, so no internal user account.
|
||||
* - this involves everything except updating the user record.
|
||||
* </pre>
|
||||
*
|
||||
* TODO JB This goes away.
|
||||
*/
|
||||
public abstract void recordLoginWithoutUserAccount(String individualUri);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Record that the current user has logged out: - notify other users of the
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -16,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
|
||||
|
@ -123,24 +123,13 @@ public class BasicAuthenticator extends Authenticator {
|
|||
}
|
||||
|
||||
recordLoginOnUserRecord(userAccount);
|
||||
recordLoginWithOrWithoutUserAccount(userAccount.getUri(), authSource);
|
||||
}
|
||||
|
||||
// TODO JB This goes away.
|
||||
@Override
|
||||
public void recordLoginWithoutUserAccount(String individualUri) {
|
||||
recordLoginWithOrWithoutUserAccount(individualUri,
|
||||
AuthenticationSource.EXTERNAL);
|
||||
}
|
||||
|
||||
/** This much is in common on login, whether or not you have a user account. */
|
||||
private void recordLoginWithOrWithoutUserAccount(String userUri,
|
||||
AuthenticationSource authSource) {
|
||||
HttpSession session = request.getSession();
|
||||
createLoginStatusBean(userUri, authSource, session);
|
||||
setSessionTimeoutLimit(session);
|
||||
recordInUserSessionMap(userUri, session);
|
||||
notifyOtherUsers(userUri, session);
|
||||
createLoginStatusBean(userAccount.getUri(), authSource, session);
|
||||
RequestIdentifiers.resetIdentifiers(request);
|
||||
setSessionTimeoutLimit(userAccount, session);
|
||||
recordInUserSessionMap(userAccount.getUri(), session);
|
||||
notifyOtherUsers(userAccount.getUri(), session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,11 +153,14 @@ public class BasicAuthenticator extends Authenticator {
|
|||
/**
|
||||
* Editors and other privileged users get a longer timeout interval.
|
||||
*/
|
||||
private void setSessionTimeoutLimit(HttpSession session) {
|
||||
private void setSessionTimeoutLimit(UserAccount userAccount,
|
||||
HttpSession session) {
|
||||
RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
|
||||
if (role == RoleLevel.EDITOR || role == RoleLevel.CURATOR
|
||||
|| role == RoleLevel.DB_ADMIN) {
|
||||
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||
} else if (userAccount.isRootUser()) {
|
||||
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||
} else {
|
||||
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
|||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginExternalAuthSetup.ATTRIBUTE_REFERRER;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -16,6 +15,9 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsFirstTimeExternalPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||
|
||||
/**
|
||||
* Handle the return from the external authorization login server. If we are
|
||||
|
@ -36,6 +38,13 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
|||
* - User corresponds to a User acocunt. Record the login.
|
||||
* - User corresponds to an Individual (self-editor).
|
||||
* - User is not recognized.
|
||||
*
|
||||
* On entry, we expect to find:
|
||||
* - A LoginProcessBean, which will give us the afterLoginUrl if the login
|
||||
* succeeds.
|
||||
* - A referrer URL, to which we will redirect if the login fails.
|
||||
* TODO: is this equal to LoginProcessBean.getLoginPageUrl()?
|
||||
* These are removed on exit.
|
||||
* </pre>
|
||||
*/
|
||||
@Override
|
||||
|
@ -50,39 +59,30 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
|||
return;
|
||||
}
|
||||
|
||||
String afterLoginUrl = LoginProcessBean.getBean(req).getAfterLoginUrl();
|
||||
removeLoginProcessArtifacts(req);
|
||||
|
||||
UserAccount userAccount = getAuthenticator(req)
|
||||
.getAccountForExternalAuth(externalAuthId);
|
||||
if (userAccount != null) {
|
||||
if (userAccount == null) {
|
||||
log.debug("Creating new account for " + externalAuthId
|
||||
+ ", return to '" + afterLoginUrl + "'");
|
||||
UserAccountsFirstTimeExternalPage.setExternalLoginInfo(req,
|
||||
externalAuthId, afterLoginUrl);
|
||||
resp.sendRedirect(UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
||||
return;
|
||||
} else {
|
||||
log.debug("Logging in as " + userAccount.getUri());
|
||||
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
||||
AuthenticationSource.EXTERNAL);
|
||||
removeLoginProcessArtifacts(req);
|
||||
new LoginRedirector(req).redirectLoggedInUser(resp);
|
||||
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> associatedUris = getAuthenticator(req)
|
||||
.getAssociatedIndividualUris(userAccount);
|
||||
// TODO JB - this case should lead to creating a new account.
|
||||
if (!associatedUris.isEmpty()) {
|
||||
log.debug("Recognize '" + externalAuthId + "' as self-editor for "
|
||||
+ associatedUris);
|
||||
String uri = associatedUris.get(0);
|
||||
|
||||
getAuthenticator(req).recordLoginWithoutUserAccount(uri);
|
||||
removeLoginProcessArtifacts(req);
|
||||
new LoginRedirector(req).redirectLoggedInUser(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("User is not recognized: " + externalAuthId);
|
||||
removeLoginProcessArtifacts(req);
|
||||
new LoginRedirector(req).redirectUnrecognizedExternalUser(resp,
|
||||
externalAuthId);
|
||||
}
|
||||
|
||||
private void removeLoginProcessArtifacts(HttpServletRequest req) {
|
||||
req.getSession().removeAttribute(ATTRIBUTE_REFERRER);
|
||||
LoginProcessBean.removeBean(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,11 +16,14 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||
|
||||
/**
|
||||
* A user has just completed the login process. What page do we direct them to?
|
||||
|
@ -34,15 +37,12 @@ public class LoginRedirector {
|
|||
private final String uriOfAssociatedIndividual;
|
||||
private final String afterLoginPage;
|
||||
|
||||
public LoginRedirector(HttpServletRequest request) {
|
||||
public LoginRedirector(HttpServletRequest request, String afterLoginPage) {
|
||||
this.request = request;
|
||||
this.session = request.getSession();
|
||||
this.afterLoginPage = afterLoginPage;
|
||||
|
||||
uriOfAssociatedIndividual = getAssociatedIndividualUri();
|
||||
|
||||
LoginProcessBean processBean = LoginProcessBean.getBean(request);
|
||||
log.debug("process bean is: " + processBean);
|
||||
afterLoginPage = processBean.getAfterLoginUrl();
|
||||
}
|
||||
|
||||
/** Is there an Individual associated with this user? */
|
||||
|
@ -106,7 +106,6 @@ public class LoginRedirector {
|
|||
try {
|
||||
DisplayMessage.setMessage(request, assembleWelcomeMessage());
|
||||
response.sendRedirect(getRedirectionUriForLoggedInUser());
|
||||
LoginProcessBean.removeBean(request);
|
||||
} catch (IOException e) {
|
||||
log.debug("Problem with re-direction", e);
|
||||
response.sendRedirect(getApplicationHomePageUrl());
|
||||
|
@ -142,7 +141,6 @@ public class LoginRedirector {
|
|||
throws IOException {
|
||||
try {
|
||||
response.sendRedirect(getRedirectionUriForCancellingUser());
|
||||
LoginProcessBean.removeBean(request);
|
||||
} catch (IOException e) {
|
||||
log.debug("Problem with re-direction", e);
|
||||
response.sendRedirect(getApplicationHomePageUrl());
|
||||
|
@ -158,7 +156,12 @@ public class LoginRedirector {
|
|||
}
|
||||
|
||||
private boolean isMerelySelfEditor() {
|
||||
RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
|
||||
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(request);
|
||||
if (IsRootUser.isRootUser(ids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RoleLevel role = HasRoleLevel.getUsersRoleLevel(ids);
|
||||
return role == RoleLevel.PUBLIC || role == RoleLevel.SELF;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ public class Authenticate extends VitroHttpServlet {
|
|||
// Send them on their way.
|
||||
switch (exitState) {
|
||||
case NOWHERE:
|
||||
new LoginRedirector(vreq).redirectCancellingUser(response);
|
||||
showLoginCanceled(response, vreq);
|
||||
break;
|
||||
case LOGGING_IN:
|
||||
showLoginScreen(vreq, response);
|
||||
|
@ -133,7 +133,7 @@ public class Authenticate extends VitroHttpServlet {
|
|||
showLoginScreen(vreq, response);
|
||||
break;
|
||||
default: // LOGGED_IN:
|
||||
new LoginRedirector(vreq).redirectLoggedInUser(response);
|
||||
showLoginComplete(response, vreq);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -477,6 +477,31 @@ public class Authenticate extends VitroHttpServlet {
|
|||
response.sendRedirect(loginProcessPage);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit: user has completed the login. Redirect appropriately and clear the bean.
|
||||
*/
|
||||
private void showLoginComplete(HttpServletResponse response,
|
||||
VitroRequest vreq) throws IOException {
|
||||
getLoginRedirector(vreq).redirectLoggedInUser(response);
|
||||
LoginProcessBean.removeBean(vreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit: user has canceled. Redirect and clear the bean.
|
||||
*/
|
||||
private void showLoginCanceled(HttpServletResponse response,
|
||||
VitroRequest vreq) throws IOException {
|
||||
getLoginRedirector(vreq).redirectCancellingUser(response);
|
||||
LoginProcessBean.removeBean(vreq);
|
||||
}
|
||||
|
||||
private LoginRedirector getLoginRedirector(VitroRequest vreq) {
|
||||
String afterLoginUrl = LoginProcessBean.getBean(vreq).getAfterLoginUrl();
|
||||
return new LoginRedirector(vreq, afterLoginUrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Get a reference to the Authenticator. */
|
||||
private Authenticator getAuthenticator(HttpServletRequest request) {
|
||||
|
|
|
@ -184,16 +184,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
templateDataModel.put("body", bodyString);
|
||||
|
||||
// Tell the template and any directives it uses that we're processing a page template.
|
||||
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE);
|
||||
writePage(templateDataModel, config, vreq, response);
|
||||
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE);
|
||||
|
||||
writePage(templateDataModel, config, vreq, response, values.getStatusCode());
|
||||
}
|
||||
|
||||
protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
||||
throws ServletException, IOException {
|
||||
String redirectUrl = values.getRedirectUrl();
|
||||
setResponseStatus(response, values.getStatusCode());
|
||||
response.sendRedirect(redirectUrl);
|
||||
}
|
||||
|
||||
private void setResponseStatus(HttpServletResponse response, int statusCode) {
|
||||
if (statusCode > 0) {
|
||||
response.setStatus(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doForward(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
||||
throws ServletException, IOException {
|
||||
String forwardUrl = values.getForwardUrl();
|
||||
|
@ -306,11 +314,18 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
*/
|
||||
public static Map<String, Object> getDirectives() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("dump", new freemarker.ext.dump.DumpDirective());
|
||||
map.put("dumpAll", new freemarker.ext.dump.DumpAllDirective());
|
||||
map.put("help", new freemarker.ext.dump.HelpDirective());
|
||||
map.putAll(getDirectivesForAllEnvironments());
|
||||
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
|
||||
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, Object> getDirectivesForAllEnvironments() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("dump", new freemarker.ext.dump.DumpDirective());
|
||||
map.put("dumpAll", new freemarker.ext.dump.DumpAllDirective());
|
||||
map.put("help", new freemarker.ext.dump.HelpDirective());
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -330,9 +345,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
ApplicationBean appBean = vreq.getAppBean();
|
||||
// Ideally, templates wouldn't need portal id. Currently used as a hidden input value
|
||||
// in the site search box, so needed for now.
|
||||
|
||||
String siteName = appBean.getApplicationName();
|
||||
map.put("siteName", siteName);
|
||||
|
||||
|
@ -365,11 +377,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
// This value is used only in stylesheets.ftl and already contains the context path.
|
||||
map.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css"));
|
||||
|
||||
// String bannerImage = portal.getBannerImage();
|
||||
// if ( ! StringUtils.isEmpty(bannerImage)) {
|
||||
// map.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
|
||||
// }
|
||||
|
||||
String flashMessage = DisplayMessage.getMessageAndClear(vreq);
|
||||
if (! flashMessage.isEmpty()) {
|
||||
map.put("flash", flashMessage);
|
||||
|
@ -448,18 +455,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
protected void writePage(Map<String, Object> root, Configuration config,
|
||||
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
||||
writeTemplate(getPageTemplateName(), root, config, request, response);
|
||||
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
|
||||
writeTemplate(getPageTemplateName(), root, config, request, response, statusCode);
|
||||
}
|
||||
|
||||
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
|
||||
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
||||
StringWriter sw = processTemplate(templateName, map, config, request);
|
||||
write(sw, response);
|
||||
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
||||
writeTemplate(templateName, map, config, request, response, 0);
|
||||
}
|
||||
|
||||
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
|
||||
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
|
||||
StringWriter sw = processTemplate(templateName, map, config, request);
|
||||
write(sw, response, statusCode);
|
||||
}
|
||||
|
||||
protected void write(StringWriter sw, HttpServletResponse response) {
|
||||
protected void write(StringWriter sw, HttpServletResponse response, int statusCode) {
|
||||
try {
|
||||
setResponseStatus(response, statusCode);
|
||||
PrintWriter out = response.getWriter();
|
||||
out.print(sw);
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -100,7 +100,7 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
// Check to see if the request is for a non-information resource, redirect if it is.
|
||||
String redirectURL = checkForRedirect ( url, vreq );
|
||||
if( redirectURL != null ){
|
||||
return new RedirectResponseValues(redirectURL);
|
||||
return new RedirectResponseValues(redirectURL, HttpServletResponse.SC_SEE_OTHER);
|
||||
}
|
||||
|
||||
Individual individual = null;
|
||||
|
@ -463,12 +463,19 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
|
||||
//Redirect if the request is for http://hostname/individual/localname
|
||||
// if accept is nothing or text/html redirect to ???
|
||||
// if accept is some RDF thing redirect to the URL for RDF
|
||||
/*
|
||||
* Following recipe 3 from "Best Practice Recipes for Publishing RDF Vocabularies."
|
||||
* See http://www.w3.org/TR/swbp-vocab-pub/#recipe3.
|
||||
* The basic idea is that a URI like http://vivo.cornell.edu/individual/n1234
|
||||
* identifies a real world individual. HTTP cannot send that as the response
|
||||
* to a GET request because it can only send bytes and not things. The server
|
||||
* sends a 303, to mean "you asked for something I cannot send you, but I can
|
||||
* send you this other stream of bytes about that thing."
|
||||
* In the case of a request like http://vivo.cornell.edu/individual/n1234/n1234.rdf,
|
||||
* the request is for a set of bytes rather than an individual, so no 303 is needed.
|
||||
*/
|
||||
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
|
||||
private String checkForRedirect(String url, VitroRequest vreq) {
|
||||
Matcher m = URI_PATTERN.matcher(url);
|
||||
if( m.matches() && m.groupCount() == 1 ){
|
||||
|
@ -506,7 +513,11 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) {
|
||||
try {
|
||||
Matcher m;
|
||||
// Check for url param specifying format
|
||||
/*
|
||||
* Check for url param specifying format.
|
||||
* Example: http://vivo.cornell.edu/individual/n23?format=rdfxml
|
||||
* This request will trigger a redirect with a 303.
|
||||
*/
|
||||
String formatParam = (String) vreq.getParameter("format");
|
||||
if (formatParam != null) {
|
||||
m = RDFXML_FORMAT.matcher(formatParam);
|
||||
|
@ -523,7 +534,11 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
//check the accept header
|
||||
/*
|
||||
* Check the accept header. This request will trigger a
|
||||
* redirect with a 303, because the request is for an individual
|
||||
* but the server can only provide a set of bytes.
|
||||
*/
|
||||
String acceptHeader = vreq.getHeader("accept");
|
||||
if (acceptHeader != null) {
|
||||
String ctStr = ContentType.getBestContentType(
|
||||
|
@ -538,10 +553,12 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
}
|
||||
|
||||
/*
|
||||
* check for parts of URL that indicate request for RDF
|
||||
http://vivo.cornell.edu/individual/n23/n23.rdf
|
||||
http://vivo.cornell.edu/individual/n23/n23.n3
|
||||
http://vivo.cornell.edu/individual/n23/n23.ttl
|
||||
* Check for parts of URL that indicate request for RDF
|
||||
* http://vivo.cornell.edu/individual/n23/n23.rdf
|
||||
* http://vivo.cornell.edu/individual/n23/n23.n3
|
||||
* http://vivo.cornell.edu/individual/n23/n23.ttl
|
||||
* This request will not trigger a redirect and 303, because
|
||||
* the request is for a set of bytes rather than an individual.
|
||||
*/
|
||||
m = RDF_REQUEST.matcher(url);
|
||||
if( m.matches() ) {
|
||||
|
@ -555,8 +572,7 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
if( m.matches() ) {
|
||||
return ContentType.TURTLE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch (Throwable th) {
|
||||
log.error("problem while checking accept header " , th);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ public abstract class BaseResponseValues implements ResponseValues {
|
|||
BaseResponseValues(ContentType contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
BaseResponseValues(ContentType contentType, int statusCode) {
|
||||
this.contentType = contentType;
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
|
@ -38,6 +43,7 @@ public abstract class BaseResponseValues implements ResponseValues {
|
|||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(ContentType contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ public class RdfResponseValues extends BaseResponseValues {
|
|||
this.model = model;
|
||||
}
|
||||
|
||||
public RdfResponseValues(ContentType contentType, Model model, int statusCode) {
|
||||
super(contentType, statusCode);
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel() {
|
||||
return model;
|
||||
|
|
|
@ -28,6 +28,8 @@ public interface ResponseValues {
|
|||
|
||||
public ContentType getContentType();
|
||||
|
||||
public void setContentType(ContentType contentType);
|
||||
|
||||
public Model getModel();
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,9 @@ public class TemplateResponseValues extends BaseResponseValues {
|
|||
}
|
||||
|
||||
public static TemplateResponseValues getTemplateResponseValuesFromException(ExceptionResponseValues responseValues) {
|
||||
return new TemplateResponseValues(responseValues.getTemplateName(), responseValues.getMap());
|
||||
return new TemplateResponseValues(responseValues.getTemplateName(),
|
||||
responseValues.getMap(),
|
||||
responseValues.getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,14 @@ import org.apache.commons.logging.LogFactory;
|
|||
/**
|
||||
* Where are we in the process of logging on? What message should we show to the
|
||||
* user?
|
||||
*
|
||||
* TODO: the contents loginPageUrl is not explicitly defined, but it is assumed
|
||||
* to be either null, absolute, or relative to the host. It would be better if
|
||||
* it were explicitly defined, and either null, absolute or relative to the
|
||||
* context path. Then, the context path could be applied when the URL is used.
|
||||
* Later for that.
|
||||
*
|
||||
* TODO: similar for afterLoginUrl, I presume.
|
||||
*/
|
||||
public class LoginProcessBean {
|
||||
private static final Log log = LogFactory.getLog(LoginProcessBean.class);
|
||||
|
|
|
@ -40,11 +40,6 @@ public interface UserAccountsDao {
|
|||
*/
|
||||
UserAccount getUserAccountByExternalAuthId(String externalAuthId);
|
||||
|
||||
/**
|
||||
* Is this UserAccount a root user?
|
||||
*/
|
||||
boolean isRootUser(UserAccount userAccount);
|
||||
|
||||
/**
|
||||
* Create a new UserAccount in the model.
|
||||
*
|
||||
|
|
|
@ -47,11 +47,6 @@ public class UserAccountsDaoFiltering extends BaseFiltering implements
|
|||
return innerDao.getUserAccountByExternalAuthId(externalAuthId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRootUser(UserAccount userAccount) {
|
||||
return innerDao.isRootUser(userAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String insertUserAccount(UserAccount userAccount) {
|
||||
return innerDao.insertUserAccount(userAccount);
|
||||
|
|
|
@ -57,15 +57,13 @@ public class DataPropertyStatementDaoSDB extends DataPropertyStatementDaoJena
|
|||
}
|
||||
else
|
||||
{
|
||||
String[] graphVars = { "?g" };
|
||||
String query =
|
||||
"CONSTRUCT { \n" +
|
||||
" <" + entity.getURI() + "> ?p ?o . \n" +
|
||||
"} WHERE { GRAPH ?g { \n" +
|
||||
"} WHERE { \n" +
|
||||
" <" + entity.getURI() + "> ?p ?o . \n" +
|
||||
" FILTER(isLiteral(?o)) \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"} }" ;
|
||||
"}" ;
|
||||
Model results = null;
|
||||
DatasetWrapper w = dwf.getDatasetWrapper();
|
||||
Dataset dataset = w.getDataset();
|
||||
|
|
|
@ -781,7 +781,7 @@ public class IndividualJena extends IndividualImpl implements Individual {
|
|||
if (stmt.getObject().isURIResource()) {
|
||||
String typeURI = ((Resource)stmt.getObject()).getURI();
|
||||
if (pfs.isClassProhibitedFromSearch(typeURI)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,8 +395,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
String[] graphVars = { "?g" };
|
||||
String queryStr =
|
||||
"CONSTRUCT { <"+ind.getURI()+"> <" + propertyURI + "> ?value } \n" +
|
||||
"WHERE { GRAPH ?g { \n" +
|
||||
"<" + ind.getURI() +"> <" + propertyURI + "> ?value } \n" +
|
||||
"WHERE { \n" +
|
||||
"<" + ind.getURI() +"> <" + propertyURI + "> ?value \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"\n} ";
|
||||
Query query = QueryFactory.create(queryStr);
|
||||
|
@ -456,13 +456,13 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
if (this.mainImageUri != NOT_INITIALIZED) {
|
||||
return mainImageUri;
|
||||
} else {
|
||||
for (ObjectPropertyStatement stmt : getObjectPropertyStatements()) {
|
||||
if (stmt.getPropertyURI()
|
||||
.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
|
||||
mainImageUri = stmt.getObjectURI();
|
||||
return mainImageUri;
|
||||
}
|
||||
}
|
||||
List<ObjectPropertyStatement> mainImgStmts =
|
||||
getObjectPropertyStatements(VitroVocabulary.IND_MAIN_IMAGE);
|
||||
if (mainImgStmts != null && mainImgStmts.size() > 0) {
|
||||
// arbitrarily return the first value in the list
|
||||
mainImageUri = mainImgStmts.get(0).getObjectURI();
|
||||
return mainImageUri;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -502,14 +502,11 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
if( _hasThumb != null ){
|
||||
return _hasThumb;
|
||||
}else{
|
||||
String[] graphVars = { "?g" };
|
||||
String ask =
|
||||
"ASK { GRAPH ?g " +
|
||||
" { <" + individualURI + "> <http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage> ?mainImage . \n" +
|
||||
" ?mainImage <http://vitro.mannlib.cornell.edu/ns/vitro/public#thumbnailImage> ?thumbImage . }\n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
DatasetWrapper w = getDatasetWrapper();
|
||||
"ASK { " +
|
||||
" <" + individualURI + "> <http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage> ?mainImage . \n" +
|
||||
" ?mainImage <http://vitro.mannlib.cornell.edu/ns/vitro/public#thumbnailImage> ?thumbImage . }\n" ;
|
||||
DatasetWrapper w = getDatasetWrapper();
|
||||
Dataset dataset = w.getDataset();
|
||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||
try{
|
||||
|
@ -552,10 +549,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
Dataset dataset = w.getDataset();
|
||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
String graphVars[] = { "?g" };
|
||||
StringBuffer selectPrimaryLinkQueryBuff = new StringBuffer().append(
|
||||
"SELECT ?url ?anchor \n" ).append(
|
||||
"WHERE{ GRAPH ?g { \n " ).append(
|
||||
"SELECT ?url ?anchor \n" ).append(" WHERE { \n").append(
|
||||
" <" + this.individualURI + "> ").append(
|
||||
"<" + VitroVocabulary.PRIMARY_LINK + "> " ).append(
|
||||
"?link . \n").append(
|
||||
|
@ -563,9 +558,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
).append(
|
||||
" ?link <" + VitroVocabulary.LINK_ANCHOR + "> ?anchor . \n"
|
||||
).append(
|
||||
"} \n")
|
||||
.append(WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode))
|
||||
.append("}");
|
||||
"} \n");
|
||||
QueryExecution qexec = QueryExecutionFactory.create(
|
||||
QueryFactory.create(selectPrimaryLinkQueryBuff.toString())
|
||||
, dataset);
|
||||
|
@ -678,12 +671,9 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
Dataset dataset = w.getDataset();
|
||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
String[] graphVars = { "?g" };
|
||||
String valuesOfProperty =
|
||||
"CONSTRUCT{<" + this.individualURI + "> <" + propertyURI + "> ?object}" +
|
||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" + propertyURI + "> ?object} \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
"CONSTRUCT{ <" + this.individualURI + "> <" + propertyURI + "> ?object }" +
|
||||
"WHERE{ <" + this.individualURI + "> <" + propertyURI + "> ?object } \n";
|
||||
tempModel = QueryExecutionFactory.create(QueryFactory.create(valuesOfProperty), dataset).execConstruct();
|
||||
ontModel.add(tempModel.listStatements());
|
||||
Resource ontRes = ontModel.getResource(this.individualURI);
|
||||
|
@ -727,13 +717,10 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
Dataset dataset = w.getDataset();
|
||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
String[] graphVars = { "?g" };
|
||||
String valuesOfProperty =
|
||||
"SELECT ?object" +
|
||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
||||
propertyURI + "> ?object} \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
"WHERE{ <" + this.individualURI + "> <" +
|
||||
propertyURI + "> ?object } \n";
|
||||
ResultSet values = QueryExecutionFactory.create(
|
||||
QueryFactory.create(valuesOfProperty), dataset)
|
||||
.execSelect();
|
||||
|
@ -767,13 +754,10 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
Dataset dataset = w.getDataset();
|
||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
String[] graphVars = { "?g" };
|
||||
String valueOfProperty =
|
||||
"SELECT ?object " +
|
||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
||||
propertyURI + "> ?object} \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
"WHERE{ <" + this.individualURI + "> <" +
|
||||
propertyURI + "> ?object } \n";
|
||||
QueryExecution qe = QueryExecutionFactory.create(
|
||||
QueryFactory.create(valueOfProperty), dataset);
|
||||
try {
|
||||
|
|
|
@ -103,6 +103,7 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
USERACCOUNT_EXTERNAL_AUTH_ID));
|
||||
u.setPermissionSetUris(getPropertyResourceURIValues(r,
|
||||
USERACCOUNT_HAS_PERMISSION_SET));
|
||||
u.setRootUser(isResourceOfType(r, USERACCOUNT_ROOT_USER));
|
||||
return u;
|
||||
} finally {
|
||||
getOntModel().leaveCriticalSection();
|
||||
|
@ -157,21 +158,6 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
return getUserAccountByUri(userUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRootUser(UserAccount userAccount) {
|
||||
if (userAccount == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getOntModel().enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
OntResource r = getOntModel().getOntResource(userAccount.getUri());
|
||||
return isResourceOfType(r, USERACCOUNT_ROOT_USER);
|
||||
} finally {
|
||||
getOntModel().leaveCriticalSection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String insertUserAccount(UserAccount userAccount) {
|
||||
if (userAccount == null) {
|
||||
|
@ -214,6 +200,10 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
USERACCOUNT_HAS_PERMISSION_SET,
|
||||
userAccount.getPermissionSetUris(), model);
|
||||
|
||||
if (userAccount.isRootUser()) {
|
||||
model.add(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||
}
|
||||
|
||||
userAccount.setUri(userUri);
|
||||
return userUri;
|
||||
} catch (InsertException e) {
|
||||
|
@ -268,6 +258,13 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
updatePropertyResourceURIValues(res,
|
||||
USERACCOUNT_HAS_PERMISSION_SET,
|
||||
userAccount.getPermissionSetUris(), model);
|
||||
|
||||
if (userAccount.isRootUser()) {
|
||||
model.add(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||
} else {
|
||||
model.remove(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||
}
|
||||
|
||||
} finally {
|
||||
model.leaveCriticalSection();
|
||||
}
|
||||
|
@ -367,7 +364,7 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
throw new InsertException("Could not create URI for individual: "
|
||||
+ errMsg);
|
||||
}
|
||||
|
||||
|
||||
private boolean isUriUsed(String uri) {
|
||||
return (getOntModel().getOntResource(uri) != null);
|
||||
}
|
||||
|
@ -385,7 +382,7 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
|||
if (type == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
StmtIterator stmts = getOntModel().listStatements(r, RDF.type, type);
|
||||
if (stmts.hasNext()) {
|
||||
stmts.close();
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.email;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -21,22 +23,30 @@ import javax.mail.internet.InternetAddress;
|
|||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
/**
|
||||
* A framework that makes it simpler to send email messages with a body built
|
||||
* from a Freemarker template.
|
||||
*
|
||||
* In fact, the body can be plain text from a template, HTML from a template, or
|
||||
* both.
|
||||
* The template must contain the @email directive, which may provide the subject
|
||||
* line, the HTML content, and the plain text content. If these values are not
|
||||
* provided by the directive, they default to empty strings, or to values that
|
||||
* were set by the controller.
|
||||
*
|
||||
* The directive also calls the send() method here.
|
||||
*
|
||||
* @see EmailDirective
|
||||
*/
|
||||
public class FreemarkerEmailMessage {
|
||||
private static final Log log = LogFactory
|
||||
|
@ -47,15 +57,15 @@ public class FreemarkerEmailMessage {
|
|||
private final HttpServletRequest req;
|
||||
private final Session session;
|
||||
private final Configuration config;
|
||||
private final ServletContext ctx;
|
||||
|
||||
private final List<Recipient> recipients = new ArrayList<Recipient>();
|
||||
private final InternetAddress replyToAddress;
|
||||
|
||||
private InternetAddress fromAddress = null;
|
||||
private String subject = "";
|
||||
private String htmlTemplateName;
|
||||
private String textTemplateName;
|
||||
private String templateName = "";
|
||||
private String htmlContent = "";
|
||||
private String textContent = "";
|
||||
private Map<String, Object> bodyMap = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
|
@ -67,8 +77,6 @@ public class FreemarkerEmailMessage {
|
|||
this.session = session;
|
||||
this.replyToAddress = replyToAddress;
|
||||
|
||||
this.ctx = req.getSession().getServletContext();
|
||||
|
||||
Object o = req.getAttribute(ATTRIBUTE_NAME);
|
||||
if (!(o instanceof Configuration)) {
|
||||
String oClass = (o == null) ? "null" : o.getClass().getName();
|
||||
|
@ -115,10 +123,6 @@ public class FreemarkerEmailMessage {
|
|||
|
||||
try {
|
||||
recipients.add(new Recipient(type, emailAddress, personalName));
|
||||
} catch (AddressException e) {
|
||||
log.warn("invalid recipient address: " + type + ", '"
|
||||
+ emailAddress + "', personal name '" + personalName + "'");
|
||||
return;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.warn("invalid recipient address: " + type + ", '"
|
||||
+ emailAddress + "', personal name '" + personalName + "'");
|
||||
|
@ -130,27 +134,41 @@ public class FreemarkerEmailMessage {
|
|||
this.subject = nonNull(subject, "");
|
||||
}
|
||||
|
||||
public void setHtmlTemplate(String templateName) {
|
||||
this.htmlTemplateName = nonNull(templateName, "");
|
||||
public void setHtmlContent(String htmlContent) {
|
||||
this.htmlContent = nonNull(htmlContent, "");
|
||||
}
|
||||
|
||||
public void setTextTemplate(String templateName) {
|
||||
this.textTemplateName = nonNull(templateName, "");
|
||||
public void setTextContent(String textContent) {
|
||||
this.textContent = nonNull(textContent, "");
|
||||
}
|
||||
|
||||
public void setTemplate(String templateName) {
|
||||
this.templateName = nonNull(templateName, "");
|
||||
}
|
||||
|
||||
public void setBodyMap(Map<String, Object> body) {
|
||||
if (body == null) {
|
||||
this.bodyMap = Collections.emptyMap();
|
||||
} else {
|
||||
this.bodyMap = Collections
|
||||
.unmodifiableMap(new HashMap<String, Object>(body));
|
||||
this.bodyMap = new HashMap<String, Object>(body);
|
||||
}
|
||||
}
|
||||
|
||||
public void processTemplate() {
|
||||
bodyMap.putAll(FreemarkerHttpServlet.getDirectivesForAllEnvironments());
|
||||
bodyMap.put("email", new EmailDirective(this));
|
||||
|
||||
try {
|
||||
Template template = config.getTemplate(templateName);
|
||||
template.process(bodyMap, new StringWriter());
|
||||
} catch (TemplateException e) {
|
||||
log.error(e, e);
|
||||
} catch (IOException e) {
|
||||
log.error(e, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void send() {
|
||||
String textBody = figureMessageBody(textTemplateName);
|
||||
String htmlBody = figureMessageBody(htmlTemplateName);
|
||||
|
||||
try {
|
||||
MimeMessage msg = new MimeMessage(session);
|
||||
msg.setReplyTo(new Address[] { replyToAddress });
|
||||
|
@ -167,19 +185,19 @@ public class FreemarkerEmailMessage {
|
|||
|
||||
msg.setSubject(subject);
|
||||
|
||||
if (textBody.isEmpty()) {
|
||||
if (htmlBody.isEmpty()) {
|
||||
if (textContent.isEmpty()) {
|
||||
if (htmlContent.isEmpty()) {
|
||||
log.error("Message has neither text body nor HTML body");
|
||||
} else {
|
||||
msg.setContent(htmlBody, "text/html");
|
||||
msg.setContent(htmlContent, "text/html");
|
||||
}
|
||||
} else {
|
||||
if (htmlBody.isEmpty()) {
|
||||
msg.setContent(textBody, "text/plain");
|
||||
if (htmlContent.isEmpty()) {
|
||||
msg.setContent(textContent, "text/plain");
|
||||
} else {
|
||||
MimeMultipart content = new MimeMultipart("alternative");
|
||||
addBodyPart(content, textBody, "text/plain");
|
||||
addBodyPart(content, htmlBody, "text/html");
|
||||
addBodyPart(content, textContent, "text/plain");
|
||||
addBodyPart(content, htmlContent, "text/html");
|
||||
msg.setContent(content);
|
||||
}
|
||||
}
|
||||
|
@ -193,26 +211,6 @@ public class FreemarkerEmailMessage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the template. If there is no template name or if there is a
|
||||
* problem with the process, return an empty string.
|
||||
*/
|
||||
private String figureMessageBody(String templateName) {
|
||||
if (templateName.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
TemplateProcessingHelper helper = new TemplateProcessingHelper(
|
||||
config, req, ctx);
|
||||
return helper.processTemplate(templateName, bodyMap).toString();
|
||||
} catch (TemplateProcessingException e) {
|
||||
log.warn("Exception while processing email template '"
|
||||
+ templateName + "'", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private void addBodyPart(MimeMultipart content, String textBody, String type)
|
||||
throws MessagingException {
|
||||
MimeBodyPart bodyPart = new MimeBodyPart();
|
||||
|
@ -235,7 +233,7 @@ public class FreemarkerEmailMessage {
|
|||
}
|
||||
|
||||
public Recipient(RecipientType type, String address, String personalName)
|
||||
throws AddressException, UnsupportedEncodingException {
|
||||
throws UnsupportedEncodingException {
|
||||
this.type = type;
|
||||
this.address = new InternetAddress(address, personalName);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.directives;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.SimpleScalar;
|
||||
import freemarker.template.TemplateDirectiveBody;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
/**
|
||||
* Process the inputs for a FreemarkerEmailMessage.
|
||||
*
|
||||
* @see FreemarkerEmailMessage
|
||||
*/
|
||||
public class EmailDirective extends BaseTemplateDirectiveModel {
|
||||
|
||||
private static final Log log = LogFactory.getLog(EmailDirective.class);
|
||||
|
||||
private final FreemarkerEmailMessage message;
|
||||
|
||||
public EmailDirective(FreemarkerEmailMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars,
|
||||
TemplateDirectiveBody body) throws TemplateException, IOException {
|
||||
|
||||
String subject = getOptionalSimpleScalarParameter(params, "subject");
|
||||
if (subject != null) {
|
||||
message.setSubject(subject);
|
||||
}
|
||||
|
||||
String htmlContent = getOptionalSimpleScalarParameter(params, "html");
|
||||
if (htmlContent != null) {
|
||||
message.setHtmlContent(htmlContent);
|
||||
}
|
||||
|
||||
String textContent = getOptionalSimpleScalarParameter(params, "text");
|
||||
if (textContent != null) {
|
||||
message.setTextContent(textContent);
|
||||
}
|
||||
|
||||
if ((htmlContent == null) && (textContent == null)) {
|
||||
throw new TemplateModelException("The email directive must have "
|
||||
+ "either a 'html' parameter or a 'text' parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
private String getOptionalSimpleScalarParameter(Map<?, ?> params,
|
||||
String name) throws TemplateModelException {
|
||||
Object o = params.get(name);
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(o instanceof SimpleScalar)) {
|
||||
throw new TemplateModelException("The '" + name + "' parameter "
|
||||
+ "for the email directive must be a string value.");
|
||||
}
|
||||
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> help(String name) {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
map.put("effect",
|
||||
"Create an email message from the parameters set in the invoking template.");
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("subject", "email subject (optional)");
|
||||
params.put("html", "HTML version of email message (optional)");
|
||||
params.put("text", "Plain text version of email message (optional)");
|
||||
map.put("parameters", params);
|
||||
|
||||
List<String> examples = new ArrayList<String>();
|
||||
examples.add("<email subject=\"Password reset confirmation\" html=html text=text>");
|
||||
examples.add("<email html=html text=text>");
|
||||
map.put("examples", examples);
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.SimpleScalar;
|
||||
import freemarker.template.TemplateDirectiveBody;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateModel;
|
||||
|
@ -44,12 +45,19 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
|||
"The url directive doesn't allow nested content.");
|
||||
}
|
||||
|
||||
String path = params.get("path").toString();
|
||||
if (path == null) {
|
||||
Object o = params.get("path");
|
||||
if (o == null) {
|
||||
throw new TemplateModelException(
|
||||
"The url directive requires a value for parameter 'path'.");
|
||||
}
|
||||
|
||||
if (! ( o instanceof SimpleScalar)) {
|
||||
throw new TemplateModelException(
|
||||
"The url directive requires a string value for parameter 'path'.");
|
||||
}
|
||||
|
||||
String path = o.toString();
|
||||
|
||||
if (!path.startsWith("/")) {
|
||||
throw new TemplateModelException(
|
||||
"The url directive requires that the value of parameter 'path' is an absolute path starting with '/'.");
|
||||
|
@ -60,6 +68,7 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
|||
out.write(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> help(String name) {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
|
@ -77,6 +86,5 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
|||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ public class WidgetDirective extends BaseTemplateDirectiveModel {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> help(String name) {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
|
|
|
@ -32,13 +32,27 @@ public class User extends BaseTemplateModel {
|
|||
return "";
|
||||
}
|
||||
|
||||
String firstName = currentUser.getFirstName();
|
||||
String lastName = currentUser.getLastName();
|
||||
if (firstName.isEmpty() && lastName.isEmpty()) {
|
||||
return currentUser.getEmailAddress();
|
||||
}
|
||||
|
||||
return firstName + " " + lastName;
|
||||
if (currentUser.getFirstName().isEmpty()) {
|
||||
return currentUser.getEmailAddress();
|
||||
}
|
||||
|
||||
return currentUser.getFirstName();
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
if (currentUser == null) {
|
||||
return "";
|
||||
} else {
|
||||
return currentUser.getFirstName();
|
||||
}
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
if (currentUser == null) {
|
||||
return "";
|
||||
} else {
|
||||
return currentUser.getLastName();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getHasSiteAdminAccess() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||
|
||||
|
@ -36,7 +37,8 @@ public class VClassTemplateModel extends BaseTemplateModel {
|
|||
return vclass.getEntityCount();
|
||||
}
|
||||
|
||||
public VClassGroupTemplateModel getGroup(){
|
||||
return new VClassGroupTemplateModel(vclass.getGroup());
|
||||
public VClassGroupTemplateModel getGroup() {
|
||||
VClassGroup group = vclass.getGroup();
|
||||
return (group == null) ? null : new VClassGroupTemplateModel(vclass.getGroup());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,26 +2,19 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.openrdf.model.URI;
|
||||
import org.openrdf.model.impl.URIImpl;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue