Merge revisions 4706 4715 4724 4726 4731 4733 4734 4735 4739 to the trunk. For bjl23 and bdc34. Also web.xml from 4719, but not EntityController.java, which causes SVN to barf.

This commit is contained in:
jeb228 2010-04-13 19:51:58 +00:00
parent 10bf357d5e
commit b88ed19ed0
6 changed files with 292 additions and 193 deletions

View file

@ -1044,6 +1044,10 @@
<servlet-name>entity</servlet-name> <servlet-name>entity</servlet-name>
<url-pattern>/individual/*</url-pattern> <url-pattern>/individual/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>entity</servlet-name>
<url-pattern>/display/*</url-pattern>
</servlet-mapping>
<servlet-mapping> <servlet-mapping>
<servlet-name>updateEntityFlags</servlet-name> <servlet-name>updateEntityFlags</servlet-name>
<url-pattern>/updateEntityFlags</url-pattern> <url-pattern>/updateEntityFlags</url-pattern>

View file

@ -22,21 +22,24 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
public class ContactMailServlet extends VitroHttpServlet { public class ContactMailServlet extends VitroHttpServlet {
private static final Logger LOG = Logger.getLogger(ContactMailServlet.class); private static final Logger LOG = Logger.getLogger(ContactMailServlet.class);
public static HttpServletRequest request; private final static String CONFIRM_PAGE = "/thankyou.jsp";
public static HttpServletRequest response; private final static String ERR_PAGE = "/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";
private static String smtpHost = null; private static String smtpHost = null;
private static final Log log = LogFactory.getLog(ContactMailServlet.class.getName());
public void init(ServletConfig servletConfig) throws javax.servlet.ServletException { public void init(ServletConfig servletConfig) throws javax.servlet.ServletException {
super.init(servletConfig); super.init(servletConfig);
@ -62,39 +65,57 @@ public class ContactMailServlet extends VitroHttpServlet {
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException { throws ServletException, IOException {
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
Portal portal = vreq.getPortal(); Portal portal = vreq.getPortal();
String statusMsg = null; // holds the error status
String confirmpage = "/thankyou.jsp";
String errpage = "/contact_err.jsp";
String status = null; // holds the error status
if (smtpHost==null || smtpHost.equals("")){ if (smtpHost==null || smtpHost.equals("")){
status = "This application has not yet been configured to send mail " + statusMsg = "This application has not yet been configured to send mail " +
"-- smtp host has not been identified in the Configuration Properties file."; "-- smtp host has not been identified in the Configuration Properties file.";
response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status + "&home=" + portal.getPortalId() ); redirectToError(response, statusMsg, portal);
return; return;
} }
String SPAM_MESSAGE = "Your message was flagged as spam."; String webusername = vreq.getParameter(WEB_USERNAME_PARAM);
String webuseremail = vreq.getParameter(WEB_USEREMAIL_PARAM);
boolean probablySpam = false; String comments = vreq.getParameter(COMMENTS_PARAM);
String spamReason = "";
String validationMessage = validateInput(webusername, webuseremail,
String originalReferer = (String) request.getSession().getAttribute("commentsFormReferer"); comments);
request.getSession().removeAttribute("commentsFormReferer"); if (validationMessage != null) {
if (originalReferer == null) { redirectToError(response, validationMessage, portal);
originalReferer = "none"; return;
// (the following does not support cookie-less browsing:) }
// probablySpam = true; webusername = webusername.trim();
// status = SPAM_MESSAGE; 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 { } else {
String referer = request.getHeader("Referer"); originalReferer = "none";
if (referer.indexOf("comments")<0 && referer.indexOf("correction")<0) { }
probablySpam=true;
status = SPAM_MESSAGE ; if (spamReason == null) {
spamReason = "The form was not submitted from the Contact Us or Corrections page."; spamReason = checkForSpam(comments);
} if (spamReason != null) {
statusMsg = SPAM_MESSAGE;
}
} }
String formType = vreq.getParameter("DeliveryType"); String formType = vreq.getParameter("DeliveryType");
@ -104,19 +125,19 @@ public class ContactMailServlet extends VitroHttpServlet {
if ("comment".equals(formType)) { if ("comment".equals(formType)) {
if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) { if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) {
log.error("No contact mail address defined in current portal "+portal.getPortalId()); LOG.error("No contact mail address defined in current portal "+portal.getPortalId());
throw new Error( throw new Error(
"To establish the Contact Us mail capability the system administrators must " "To establish the Contact Us mail capability the system administrators must "
+ "specify an email address in the current portal."); + "specify an email address in the current portal.");
} else { } else {
deliverToArray = portal.getContactMail().split(","); deliverToArray = portal.getContactMail().split(",");
} }
deliveryfrom = "Message from the "+portal.getAppName()+" Contact Form (ARMANN-nospam)"; deliveryfrom = "Message from the "+portal.getAppName()+" Contact Form";
} else if ("correction".equals(formType)) { } else if ("correction".equals(formType)) {
if (portal.getCorrectionMail() == null || portal.getCorrectionMail().trim().length()==0) { if (portal.getCorrectionMail() == null || portal.getCorrectionMail().trim().length()==0) {
log.error("Expecting one or more correction email addresses to be specified in current portal "+portal.getPortalId()+"; will attempt to use contact mail address"); LOG.error("Expecting one or more correction email addresses to be specified in current portal "+portal.getPortalId()+"; will attempt to use contact mail address");
if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) { if (portal.getContactMail() == null || portal.getContactMail().trim().length()==0) {
log.error("No contact mail address or correction mail address defined in current portal "+portal.getPortalId()); LOG.error("No contact mail address or correction mail address defined in current portal "+portal.getPortalId());
} else { } else {
deliverToArray = portal.getContactMail().split(","); deliverToArray = portal.getContactMail().split(",");
} }
@ -126,78 +147,104 @@ public class ContactMailServlet extends VitroHttpServlet {
deliveryfrom = "Message from the "+portal.getAppName()+" Correction Form (ARMANN-nospam)"; deliveryfrom = "Message from the "+portal.getAppName()+" Correction Form (ARMANN-nospam)";
} else { } else {
deliverToArray = portal.getContactMail().split(","); deliverToArray = portal.getContactMail().split(",");
status = SPAM_MESSAGE ; statusMsg = SPAM_MESSAGE ;
spamReason = "The form specifies no delivery type."; spamReason = "The form specifies no delivery type.";
} }
recipientCount=(deliverToArray == null) ? 0 : deliverToArray.length; recipientCount=(deliverToArray == null) ? 0 : deliverToArray.length;
if (recipientCount == 0) { if (recipientCount == 0) {
log.error("recipientCount is 0 when DeliveryType specified as \""+formType+"\""); LOG.error("recipientCount is 0 when DeliveryType specified as \""+formType+"\"");
throw new Error( throw new Error(
"To establish the Contact Us mail capability the system administrators must " "To establish the Contact Us mail capability the system administrators must "
+ "specify at least one email address in the current portal."); + "specify at least one email address in the current portal.");
} }
// obtain passed in form data with a simple trim on the values String msgText = composeEmail(webusername, webuseremail, comments,
String webusername = vreq.getParameter("webusername");// Null.trim(); will give you an exception deliveryfrom, originalReferer, request.getRemoteAddr());
String webuseremail = vreq.getParameter("webuseremail");//.trim();
String comments = vreq.getParameter("s34gfd88p9x1"); // debugging
PrintWriter outFile = new PrintWriter
(new FileWriter(request.getSession().getServletContext()
.getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush
writeBackupCopy(outFile, msgText, spamReason);
if( webusername == null || "".equals(webusername) ){ // Set the smtp host
probablySpam=true; Properties props = System.getProperties();
status = SPAM_MESSAGE; props.put("mail.smtp.host", smtpHost);
spamReason = "A proper webusername field was not found in the form submitted."; Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
webusername=""; //s.setDebug(true);
} else try {
webusername=webusername.trim();
if (spamReason == null) {
sendMessage(s, webuseremail, deliverToArray, deliveryfrom,
recipientCount, msgText);
}
if( webuseremail == null || "".equals(webuseremail) ){ } catch (AddressException e) {
probablySpam=true; statusMsg = "Please supply a valid email address.";
status = SPAM_MESSAGE; outFile.println( statusMsg );
spamReason = "A proper webuser email field was not found in the form submitted."; outFile.println( e.getMessage() );
webuseremail=""; } catch (SendFailedException e) {
} else statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
webuseremail=webuseremail.trim(); 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();
}
if (comments==null || comments.equals("")) { // to avoid error messages in log due to null comments String outFile.flush();
probablySpam=true; outFile.close();
status = SPAM_MESSAGE;
spamReason = "The proper comments field was not found in the form submitted."; // Redirect to the appropriate confirmation page
if (statusMsg == null && spamReason == null) {
// message was sent successfully
redirectToConfirmation(response, statusMsg, portal);
} else { } else {
comments=comments.trim(); // exception occurred
redirectToError( response, statusMsg, portal);
} }
}
/* *************************** The following chunk code is for blocking specific types of spam messages. It should be removed from a more generalized codebase. */ public void doPost( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
doGet( request, response );
}
/* if this blog markup is found, treat comment as blog spam */ private void redirectToConfirmation(HttpServletResponse response,
if (!probablySpam String statusMsg, Portal portal) throws IOException {
&& (comments.indexOf("[/url]") > -1 response.sendRedirect( "test?bodyJsp=" + CONFIRM_PAGE + "&home=" +
|| comments.indexOf("[/URL]") > -1 portal.getPortalId() );
|| comments.indexOf("[url=") > -1 }
|| comments.indexOf("[URL=") > -1)) {
probablySpam = true; private void redirectToError(HttpServletResponse response, String statusMsg,
status = SPAM_MESSAGE; Portal portal) throws IOException {
spamReason = "The message contained blog link markup."; response.sendRedirect( "test?bodyJsp=" + ERR_PAGE + "&ERR=" + statusMsg
} + "&home=" + portal.getPortalId() );
}
/* if message is absurdly short, treat as blog spam */
if (!probablySpam && comments.length()<15) { /** Intended to mangle url so it can get through spam filtering
probablySpam=true; * http://host/dir/servlet?param=value -> host: dir/servlet?param=value */
status = SPAM_MESSAGE; public String stripProtocol( String in ){
spamReason="The message was too short."; if( in == null )
} return "";
else
/* if contact form was requested directly, and message contains 'phentermine', treat as spam */ return in.replaceAll("http://", "host: " );
if (!probablySpam && originalReferer.equals("none") && (comments.indexOf("phentermine")>-1 || comments.indexOf("Phentermine")>-1)) { }
probablySpam=true;
status = SPAM_MESSAGE; private String composeEmail(String webusername, String webuseremail,
spamReason = "The comments form was requested directly, and the message contains the word 'Phentermine.'"; String comments, String deliveryfrom,
} String originalReferer, String ipAddr) {
/* ************************** end spam filtering code */ StringBuffer msgBuf = new StringBuffer();
// contains the intro copy for the body of the email message
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 String lineSeparator = System.getProperty("line.separator");
// \r\n on windows, \n on unix
// from MyLibrary // from MyLibrary
msgBuf.setLength(0); msgBuf.setLength(0);
msgBuf.append("Content-Type: text/html; charset='us-ascii'" + lineSeparator); msgBuf.append("Content-Type: text/html; charset='us-ascii'" + lineSeparator);
@ -208,7 +255,8 @@ public class ContactMailServlet extends VitroHttpServlet {
msgBuf.append("</head>" + lineSeparator ); msgBuf.append("</head>" + lineSeparator );
msgBuf.append("<body>" + lineSeparator ); msgBuf.append("<body>" + lineSeparator );
msgBuf.append("<h4>" + deliveryfrom + "</h4>" + lineSeparator ); msgBuf.append("<h4>" + deliveryfrom + "</h4>" + lineSeparator );
msgBuf.append("<h4>From: "+webusername +" (" + webuseremail + ")"+" at IP address "+request.getRemoteAddr()+"</h4>"+lineSeparator); msgBuf.append("<h4>From: "+webusername +" (" + webuseremail + ")" +
" at IP address " + ipAddr + "</h4>"+lineSeparator);
if (!(originalReferer == null || originalReferer.equals("none"))){ if (!(originalReferer == null || originalReferer.equals("none"))){
//The spam filter that is being used by the listsrv is rejecting <a href="... //The spam filter that is being used by the listsrv is rejecting <a href="...
@ -227,17 +275,18 @@ public class ContactMailServlet extends VitroHttpServlet {
msgBuf.append("</body>" + lineSeparator ); msgBuf.append("</body>" + lineSeparator );
msgBuf.append("</html>" + lineSeparator ); msgBuf.append("</html>" + lineSeparator );
String msgText = msgBuf.toString(); return msgBuf.toString();
// debugging
PrintWriter outFile = new PrintWriter (new FileWriter(request.getSession().getServletContext().getRealPath("/WEB-INF/LatestMessage.html"),true)); //autoflush
Calendar cal = Calendar.getInstance();
}
private void writeBackupCopy(PrintWriter outFile, String msgText,
String spamReason) {
Calendar cal = Calendar.getInstance();
outFile.println("<hr/>"); outFile.println("<hr/>");
outFile.println(); outFile.println();
outFile.println("<p>"+cal.getTime()+"</p>"); outFile.println("<p>"+cal.getTime()+"</p>");
outFile.println(); outFile.println();
if (probablySpam) { if (spamReason != null) {
outFile.println("<p>REJECTED - SPAM</p>"); outFile.println("<p>REJECTED - SPAM</p>");
outFile.println("<p>"+spamReason+"</p>"); outFile.println("<p>"+spamReason+"</p>");
outFile.println(); outFile.println();
@ -247,86 +296,82 @@ public class ContactMailServlet extends VitroHttpServlet {
outFile.println(); outFile.println();
outFile.flush(); outFile.flush();
// outFile.close(); // 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 smtp host // Set the from address
Properties props = System.getProperties(); msg.setFrom( new InternetAddress( webuseremail ));
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true);
try {
// Construct the message
MimeMessage msg = new MimeMessage( s );
//System.out.println("trying to send message from servlet");
// Set the from address // Set the recipient address
msg.setFrom( new InternetAddress( webuseremail ));
if (recipientCount>0){
// Set the recipient address InternetAddress[] address=new InternetAddress[recipientCount];
for (int i=0; i<recipientCount; i++){
if (recipientCount>0){ address[i] = new InternetAddress(deliverToArray[i]);
InternetAddress[] address=new InternetAddress[recipientCount];
for (int i=0; i<recipientCount; i++){
address[i] = new InternetAddress(deliverToArray[i]);
}
msg.setRecipients( Message.RecipientType.TO, address );
} }
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() );
//System.out.println("sending from servlet");
if (!probablySpam)
Transport.send( msg ); // try to send the message via smtp - catch error exceptions
} catch (AddressException e) {
status = "Please supply a valid email address.";
outFile.println( status );
outFile.println( e.getMessage() );
} catch (SendFailedException e) {
status = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
outFile.println( status );
outFile.println( e.getMessage() );
} catch (MessagingException e) {
status = "The system was unable to deliver your mail. Please try again later. [MESSAGING]";
outFile.println( status );
outFile.println( e.getMessage() );
e.printStackTrace();
} }
outFile.flush(); // Set the subject and text
outFile.close(); msg.setSubject( deliveryfrom );
// Redirect to the appropriate confirmation page // add the multipart to the message
if (status == null && !probablySpam) { msg.setContent(msgText,"text/html");
// message was sent successfully
response.sendRedirect( "test?bodyJsp=" + confirmpage + "&home=" + portal.getPortalId() ); // set the Date: header
} else { msg.setSentDate( new Date() );
// exception occurred
response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status + "&home=" + portal.getPortalId() ); 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) {
public void doPost( HttpServletRequest request, HttpServletResponse response ) return "The message was too short.";
throws ServletException, IOException }
{
doGet( request, response ); return null;
}
/** 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: " );
} }
} }

View file

@ -27,6 +27,7 @@ import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl; import org.openrdf.model.impl.URIImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory;
@ -37,12 +38,14 @@ public class URLRewritingHttpServletResponse implements HttpServletResponse {
private HttpServletResponse _response; private HttpServletResponse _response;
private HttpServletRequest _request; private HttpServletRequest _request;
private ServletContext _context; private ServletContext _context;
private WebappDaoFactory wadf;
private int contextPathDepth; private int contextPathDepth;
private Pattern slashPattern = Pattern.compile("/"); private Pattern slashPattern = Pattern.compile("/");
public URLRewritingHttpServletResponse(HttpServletResponse response, HttpServletRequest request, ServletContext context) { public URLRewritingHttpServletResponse(HttpServletResponse response, HttpServletRequest request, ServletContext context) {
this._response = response; this._response = response;
this._context = context; this._context = context;
this.wadf = (WebappDaoFactory) context.getAttribute("webappDaoFactory");
this.contextPathDepth = slashPattern.split(request.getContextPath()).length-1; this.contextPathDepth = slashPattern.split(request.getContextPath()).length-1;
} }
@ -94,8 +97,11 @@ public class URLRewritingHttpServletResponse implements HttpServletResponse {
return _response.encodeURL(inUrl); return _response.encodeURL(inUrl);
} }
// rewrite home parameters as portal prefixes for URLs not relative to the current location // rewrite home parameters as portal prefixes or remove
if (url.pathBeginsWithSlash && PortalPickerFilter.isPortalPickingActive) { // if there is only one portal
if ( url.pathBeginsWithSlash &&
(PortalPickerFilter.isPortalPickingActive ||
wadf.getPortalDao().isSinglePortal()) ) {
PortalPickerFilter ppf = PortalPickerFilter.getPortalPickerFilter(this._context); PortalPickerFilter ppf = PortalPickerFilter.getPortalPickerFilter(this._context);
if ( (ppf != null) && (url.queryParams != null) ) { if ( (ppf != null) && (url.queryParams != null) ) {
Iterator<String[]> qpIt = url.queryParams.iterator(); Iterator<String[]> qpIt = url.queryParams.iterator();
@ -149,7 +155,16 @@ public class URLRewritingHttpServletResponse implements HttpServletResponse {
if ( (uri.getNamespace() != null) && (uri.getLocalName() != null) ) { if ( (uri.getNamespace() != null) && (uri.getLocalName() != null) ) {
String prefix = nsMap.getPrefixForNamespace(uri.getNamespace()); String prefix = nsMap.getPrefixForNamespace(uri.getNamespace());
String localName = uri.getLocalName(); String localName = uri.getLocalName();
if (prefix != null) { if (wadf.getDefaultNamespace().
equals(uri.getNamespace())
&& prefix == null) {
// make a URI that matches the URI
// of the resource to support
// linked data request
url.pathParts.add(localName);
// remove the ugly uri parameter
indexToRemove = qpIndex;
} else if (prefix != null) {
// add the pretty path parts // add the pretty path parts
url.pathParts.add(prefix); url.pathParts.add(prefix);
url.pathParts.add(localName); url.pathParts.add(localName);

View file

@ -24,6 +24,7 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType; import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
/** /**
@ -35,6 +36,7 @@ public class ABoxUpdater {
private OntModel oldTboxModel; private OntModel oldTboxModel;
private OntModel newTboxModel; private OntModel newTboxModel;
private OntModel aboxModel; private OntModel aboxModel;
private OntModel newTBoxAnnotationsModel;
private OntologyChangeLogger logger; private OntologyChangeLogger logger;
private OntologyChangeRecord record; private OntologyChangeRecord record;
private OntClass OWL_THING = (ModelFactory private OntClass OWL_THING = (ModelFactory
@ -57,12 +59,14 @@ public class ABoxUpdater {
public ABoxUpdater(OntModel oldTboxModel, public ABoxUpdater(OntModel oldTboxModel,
OntModel newTboxModel, OntModel newTboxModel,
OntModel aboxModel, OntModel aboxModel,
OntModel newAnnotationsModel,
OntologyChangeLogger logger, OntologyChangeLogger logger,
OntologyChangeRecord record) { OntologyChangeRecord record) {
this.oldTboxModel = oldTboxModel; this.oldTboxModel = oldTboxModel;
this.newTboxModel = newTboxModel; this.newTboxModel = newTboxModel;
this.aboxModel = aboxModel; this.aboxModel = aboxModel;
this.newTBoxAnnotationsModel = newAnnotationsModel;
this.logger = logger; this.logger = logger;
this.record = record; this.record = record;
} }
@ -129,30 +133,58 @@ public class ABoxUpdater {
Resource newClass = ResourceFactory.createResource(change.getDestinationURI()); Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
// Change class references in the subjects of statements // Change class references in the subjects of statements
// BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads."
// For now, the best behavior is to remove any remaining statements
// where the old class is the subject, *unless* the statements
// is part of the new annotations file (see comment below) or the
// predicate is vitro:autolinkedToTab. In the latter case,
// the autolinking annotation should be rewritten using the
// new class name.
Property autoLinkedToTab = ResourceFactory.createProperty(VitroVocabulary.TAB_AUTOLINKEDTOTAB);
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null); StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
int count = 0; int renameCount = 0;
int removeCount = 0;
while (iter.hasNext()) { while (iter.hasNext()) {
count++;
Statement oldStatement = iter.next(); Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(newClass, oldStatement.getPredicate(), oldStatement.getObject()); if (newTBoxAnnotationsModel.contains(oldStatement)) {
retractions.add(oldStatement); continue;
additions.add(newStatement); // if this statement was loaded from the new annotations,
// don't attempt to remove it.
// This happens in cases where a class hasn't really
// been removed, but we just want to map any ABox
// data using it to use a different class instead.
}
if (autoLinkedToTab.equals(oldStatement.getPredicate())) {
renameCount++;
Statement newStatement = ResourceFactory.createStatement(newClass, oldStatement.getPredicate(), oldStatement.getObject());
additions.add(newStatement);
} else {
removeCount++;
retractions.add(oldStatement);
}
//logChange(oldStatement, false); //logChange(oldStatement, false);
//logChange(newStatement,true); //logChange(newStatement,true);
} }
//log summary of changes //log summary of changes
if (count > 0) { if (renameCount > 0) {
logger.log("Changed " + count + " subject reference" + ((count > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class to be " + newClass.getURI()); logger.log("Changed " + renameCount + " subject reference" + ((renameCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class to be " + newClass.getURI());
}
if (removeCount > 0) {
logger.log("Removed " + removeCount + " remaining subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
} }
// Change class references in the objects of statements // Change class references in the objects of rdf:type statements
iter = aboxModel.listStatements((Resource) null, (Property) null, oldClass); iter = aboxModel.listStatements((Resource) null, (Property) null, oldClass);
count = 0; renameCount = 0;
while (iter.hasNext()) { while (iter.hasNext()) {
count++; renameCount++;
Statement oldStatement = iter.next(); Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), oldStatement.getPredicate(), newClass); Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), oldStatement.getPredicate(), newClass);
retractions.add(oldStatement); retractions.add(oldStatement);
@ -163,8 +195,8 @@ public class ABoxUpdater {
} }
//log summary of changes //log summary of changes
if (count > 0) { if (renameCount > 0) {
logger.log("Changed " + count + " object reference" + ((count > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class to be " + newClass.getURI()); logger.log("Changed " + renameCount + " object reference" + ((renameCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class to be " + newClass.getURI());
} }
aboxModel.remove(retractions); aboxModel.remove(retractions);

View file

@ -96,13 +96,11 @@ public class OntologyUpdater {
settings.getNewTBoxModel(), settings.getNewTBoxModel(),
settings.getOldTBoxModel()); settings.getOldTBoxModel());
//updateTBox(changes); //process the TBox before the ABox
//preprocessChanges(changes); updateTBoxAnnotations();
updateABox(changes); updateABox(changes);
updateTBoxAnnotations();
} }
/** /**
@ -172,8 +170,12 @@ public class OntologyUpdater {
} }
} }
aboxModel.add(actualAdditions); aboxModel.add(actualAdditions);
logger.log("Constructed " + actualAdditions.size() + " new " + if (actualAdditions.size() > 0) {
"statements using SPARQL CONSTRUCT queries."); logger.log("Constructed " + actualAdditions.size() + " new " +
"statement"
+ ((actualAdditions.size() > 1) ? "s" : "") +
" using SPARQL CONSTRUCT queries.");
}
record.recordAdditions(actualAdditions); record.recordAdditions(actualAdditions);
} finally { } finally {
aboxModel.leaveCriticalSection(); aboxModel.leaveCriticalSection();
@ -198,7 +200,8 @@ public class OntologyUpdater {
OntModel newTBoxModel = settings.getNewTBoxModel(); OntModel newTBoxModel = settings.getNewTBoxModel();
OntModel ABoxModel = settings.getOntModelSelector().getABoxModel(); OntModel ABoxModel = settings.getOntModelSelector().getABoxModel();
ABoxUpdater aboxUpdater = new ABoxUpdater( ABoxUpdater aboxUpdater = new ABoxUpdater(
oldTBoxModel, newTBoxModel, ABoxModel, logger, record); oldTBoxModel, newTBoxModel, ABoxModel,
settings.getNewTBoxAnnotationsModel(), logger, record);
aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges()); aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges());
aboxUpdater.processClassChanges(changes.getAtomicClassChanges()); aboxUpdater.processClassChanges(changes.getAtomicClassChanges());
// run additional SPARQL CONSTRUCTS // run additional SPARQL CONSTRUCTS

View file

@ -54,9 +54,9 @@ public class UpdateKnowledgeBase implements ServletContextListener {
private final String ERROR_LOG_FILE = DATA_DIR + LOG_DIR + private final String ERROR_LOG_FILE = DATA_DIR + LOG_DIR +
"knowledgeBaseUpdate.error.log"; "knowledgeBaseUpdate.error.log";
private final String REMOVED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + private final String REMOVED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR +
"removedData.rdf"; "removedData.n3";
private final String ADDED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + private final String ADDED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR +
"addedData.rdf"; "addedData.n3";
private final String SPARQL_CONSTRUCTS_DIR = DATA_DIR + "sparqlConstructs/"; private final String SPARQL_CONSTRUCTS_DIR = DATA_DIR + "sparqlConstructs/";
private final String MISC_REPLACEMENTS_FILE = DATA_DIR + "miscReplacements.rdf"; private final String MISC_REPLACEMENTS_FILE = DATA_DIR + "miscReplacements.rdf";
private final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; private final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/";