NIHVIVO-646 Autocomplete, remove author functionality

This commit is contained in:
rjy7 2010-06-29 16:15:49 +00:00
parent 0f6fd1b39a
commit fd0df8b281
7 changed files with 259 additions and 171 deletions

View file

@ -36,3 +36,6 @@ log4j.rootLogger=INFO, AllAppender
log4j.logger.org.apache.catalina=INFO log4j.logger.org.apache.catalina=INFO
log4j.logger.edu.cornell.mannlib.vitro.webapp.ConfigurationProperties=INFO log4j.logger.edu.cornell.mannlib.vitro.webapp.ConfigurationProperties=INFO
log4j.logger.edu.cornell.mannlib.vitro.webapp.filestorage.updater.FileStorageUpdater=INFO log4j.logger.edu.cornell.mannlib.vitro.webapp.filestorage.updater.FileStorageUpdater=INFO
log4j.logger.edu.cornell.mannlib.vitro.webapp.search.controller=DEBUG

View file

@ -1143,7 +1143,16 @@
<servlet-name>primitiveRdfEdit</servlet-name> <servlet-name>primitiveRdfEdit</servlet-name>
<url-pattern>/edit/primitiveRdfEdit</url-pattern> <url-pattern>/edit/primitiveRdfEdit</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet>
<servlet-name>primitiveRdfDelete</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.PrimitiveRdfDelete</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>primitiveRdfDelete</servlet-name>
<url-pattern>/edit/primitiveRdfDelete</url-pattern>
</servlet-mapping>
<!-- ============================== servlet-mappings ======================== --> <!-- ============================== servlet-mappings ======================== -->
<servlet-mapping> <servlet-mapping>
<servlet-name>fetch</servlet-name> <servlet-name>fetch</servlet-name>

View file

@ -0,0 +1,51 @@
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import freemarker.template.Configuration;
public class PrimitiveRdfDelete extends PrimitiveRdfEdit {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(PrimitiveRdfDelete.class);
protected void processRequest(VitroRequest vreq, HttpServletResponse response) {
String uriToDelete = vreq.getParameter("deletion");
if (StringUtils.isEmpty(uriToDelete)) {
doError(response, "No individual specified for deletion", 500);
return;
}
// Check permissions
// The permission-checking code should be inherited from superclass
boolean hasPermission = true;
if( !hasPermission ){
//if not okay, send error message
doError(response,"Insufficent permissions.",HttpStatus.SC_UNAUTHORIZED);
return;
}
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
IndividualDao idao = wdf.getIndividualDao();
int result = idao.deleteIndividual(uriToDelete);
if (result == 1) {
doError(response, "Error deleting individual", 500);
}
}
}

View file

@ -4,11 +4,14 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -25,6 +28,8 @@ import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vedit.beans.LoginFormBean; import edu.cornell.mannlib.vedit.beans.LoginFormBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditN3Utils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditN3Utils;
@ -32,34 +37,34 @@ import freemarker.template.Configuration;
public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{ public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override
protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
// boolean loggedIn = checkLoginStatus(request, response); // boolean loggedIn = checkLoginStatus(request, response);
// if( !loggedIn){ // if( !loggedIn){
// doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED); // doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED);
// return; // return;
// } // }
return mergeBodyToTemplate("primitiveRdfEdit.ftl",new HashMap<String, Object>(), config); return mergeBodyToTemplate("primitiveRdfEdit.ftl",new HashMap<String, Object>(), config);
} }
@Override @Override
protected String getTitle(String siteName) { protected String getTitle(String siteName) {
return "RDF edit"; return "RDF edit";
} }
@Override @Override
public void doPost(HttpServletRequest request, public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException { HttpServletResponse response) throws ServletException, IOException {
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
boolean loggedIn = checkLoginStatus(request, response); boolean loggedIn = checkLoginStatus(request, response);
if( !loggedIn){ if( !loggedIn){
doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED); doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED);
return; return;
} }
// PolicyIface policy = RequestPolicyList.getPolicies( request ); // PolicyIface policy = RequestPolicyList.getPolicies( request );
// //
// if( policy == null || ( policy instanceof PolicyList && ((PolicyList)policy).size() == 0 )){ // if( policy == null || ( policy instanceof PolicyList && ((PolicyList)policy).size() == 0 )){
@ -80,149 +85,159 @@ public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{
// return; // return;
// } // }
processRequest(vreq, response);
}
protected void processRequest(VitroRequest vreq, HttpServletResponse response) {
/* Predefined values for RdfFormat are "RDF/XML", /* Predefined values for RdfFormat are "RDF/XML",
* "N-TRIPLE", "TURTLE" (or "TTL") and "N3". null represents * "N-TRIPLE", "TURTLE" (or "TTL") and "N3". null represents
* the default language, "RDF/XML". "RDF/XML-ABBREV" is a synonym for "RDF/XML" */ * the default language, "RDF/XML". "RDF/XML-ABBREV" is a synonym for "RDF/XML" */
String format = request.getParameter("RdfFormat"); String format = vreq.getParameter("RdfFormat");
if( format == null ) if( format == null )
format = "N3"; format = "N3";
if ( ! ("N-TRIPLE".equals(format) || "TURTLE".equals(format) || "TTL".equals(format) if ( ! ("N-TRIPLE".equals(format) || "TURTLE".equals(format) || "TTL".equals(format)
|| "N3".equals(format)|| "RDF/XML-ABBREV".equals(format) || "RDF/XML".equals(format) )){ || "N3".equals(format)|| "RDF/XML-ABBREV".equals(format) || "RDF/XML".equals(format) )){
doError(response,"RdfFormat was not recoganized.",500); doError(response,"RdfFormat was not recognized.",500);
return; return;
} }
//parse RDF //parse RDF
Set<Model> additions= null; Set<Model> additions= null;
try { try {
additions = parseRdfParam(request.getParameterValues("additions"),format); additions = parseRdfParam(vreq.getParameterValues("additions"),format);
} catch (Exception e) { } catch (Exception e) {
doError(response,"Error reading RDF, set log level to debug for this class to get error messages in the server logs.",HttpStatus.SC_BAD_REQUEST); doError(response,"Error reading RDF, set log level to debug for this class to get error messages in the server logs.",HttpStatus.SC_BAD_REQUEST);
return; return;
} }
Set<Model> retractions = null; Set<Model> retractions = null;
try { try {
retractions = parseRdfParam(request.getParameterValues("retractions"),format); retractions = parseRdfParam(vreq.getParameterValues("retractions"),format);
} catch (Exception e) { } catch (Exception e) {
doError(response,"Error reading RDF, set log level to debug for this class to get error messages in the server logs.",HttpStatus.SC_BAD_REQUEST); doError(response,"Error reading RDF, set log level to debug for this class to get error messages in the server logs.",HttpStatus.SC_BAD_REQUEST);
return; return;
} }
//check permissions
//TODO: (bdc34)This is not yet implemented, must check the IDs against the policies for permissons before doing an edit! //check permissions
boolean hasPermission = true; //TODO: (bdc34)This is not yet implemented, must check the IDs against the policies for permissons before doing an edit!
// rjy7 put policy check in separate method so subclasses can inherit
if( !hasPermission ){ boolean hasPermission = true;
//if not okay, send error message
doError(response,"Insufficent permissions.",HttpStatus.SC_UNAUTHORIZED); if( !hasPermission ){
} //if not okay, send error message
doError(response,"Insufficent permissions.",HttpStatus.SC_UNAUTHORIZED);
if( hasPermission ){ return;
String editorUri = EditN3Utils.getEditorUri(vreq,request.getSession(false),getServletContext()); }
try {
processChanges( additions, retractions, getWriteModel(request),getQueryModel(request), editorUri); ServletContext sc = getServletContext();
} catch (Exception e) { String editorUri = EditN3Utils.getEditorUri(vreq, vreq.getSession(false), sc);
doError(response,e.getMessage(),HttpStatus.SC_INTERNAL_SERVER_ERROR); try {
} processChanges( additions, retractions, getWriteModel(vreq),getQueryModel(vreq), editorUri);
} } catch (Exception e) {
} doError(response,e.getMessage(),HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
protected void processChanges(Set<Model> additions, Set<Model> retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
Model a = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
for(Model m : additions)
a.add(m);
Model r = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
for(Model m : retractions)
r.add(m);
procesChanges(a,r,writeModel,queryModel,editorURI);
}
protected void procesChanges(Model additions, Model retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
/*
* Do a diff on the additions and retractions and then only add the delta to the jenaOntModel.
*/
Model assertionsAdded = additions.difference( retractions );
Model assertionsRetracted = retractions.difference( additions );
Model depResRetractions =
DependentResourceDeleteJena
.getDependentResourceDeleteForChange(assertionsAdded, assertionsRetracted, queryModel);
assertionsRetracted.add( depResRetractions );
Lock lock = null;
try{
lock = writeModel.getLock();
lock.enterCriticalSection(Lock.WRITE);
writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,true));
writeModel.add( assertionsAdded );
writeModel.remove( assertionsRetracted );
}catch(Throwable t){
throw new Exception("Error while modifying model \n" + t.getMessage());
}finally{
writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,false));
lock.leaveCriticalSection();
} }
} protected void processChanges(Set<Model> additions, Set<Model> retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
Model a = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
/** for(Model m : additions)
* Convert the values from a parameters into RDF models. a.add(m);
* @param parameters - the result of request.getParameters(String)
* @param format - a valid format string for Jena's Model.read() Model r = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
* @return for(Model m : retractions)
* @throws Exception r.add(m);
*/
protected Set<Model> parseRdfParam(String[] parameters, String format) throws Exception{ processChanges(a,r,writeModel,queryModel,editorURI);
Set<Model> models = new HashSet<Model>();
for( String param : parameters){ }
try{
StringReader reader = new StringReader(param); protected void processChanges(Model additions, Model retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
Model model = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel(); /*
model.read(reader, null, format); * Do a diff on the additions and retractions and then only add the delta to the jenaOntModel.
models.add(model); */
}catch(Error ex){ Model assertionsAdded = additions.difference( retractions );
log.error("Error reading RDF as " + format + " in " + param); Model assertionsRetracted = retractions.difference( additions );
throw new Exception("Error reading RDF, set log level to debug for this class to get error messages in the sever logs.");
} Model depResRetractions =
} DependentResourceDeleteJena
return models; .getDependentResourceDeleteForChange(assertionsAdded, assertionsRetracted, queryModel);
} assertionsRetracted.add( depResRetractions );
private void doError(HttpServletResponse response, String errorMsg,int httpstatus){ Lock lock = null;
response.setStatus(httpstatus); try{
try { lock = writeModel.getLock();
response.getWriter().write(errorMsg); lock.enterCriticalSection(Lock.WRITE);
} catch (IOException e) { writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,true));
log.debug("IO exception during output",e ); writeModel.add( assertionsAdded );
} writeModel.remove( assertionsRetracted );
} }catch(Throwable t){
throw new Exception("Error while modifying model \n" + t.getMessage());
protected OntModel getWriteModel(HttpServletRequest request){ }finally{
HttpSession session = request.getSession(false); writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,false));
if( session == null || session.getAttribute("jenaOntModel") == null ) lock.leaveCriticalSection();
return (OntModel)getServletContext().getAttribute("jenaOntModel"); }
else }
return (OntModel)session.getAttribute("jenaOntModel");
}
protected OntModel getQueryModel(HttpServletRequest request){
return getWriteModel(request);
}
Log log = LogFactory.getLog(PrimitiveRdfEdit.class.getName());
static public boolean checkLoginStatus(HttpServletRequest request, HttpServletResponse response){ /**
* Convert the values from a parameters into RDF models.
* @param parameters - the result of request.getParameters(String)
* @param format - a valid format string for Jena's Model.read()
* @return
* @throws Exception
*/
protected Set<Model> parseRdfParam(String[] parameters, String format) throws Exception{
Set<Model> models = new HashSet<Model>();
for( String param : parameters){
try{
StringReader reader = new StringReader(param);
Model model = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
model.read(reader, null, format);
models.add(model);
}catch(Error ex){
log.error("Error reading RDF as " + format + " in " + param);
throw new Exception("Error reading RDF, set log level to debug for this class to get error messages in the sever logs.");
}
}
return models;
}
protected void doError(HttpServletResponse response, String errorMsg,int httpstatus){
response.setStatus(httpstatus);
try {
response.getWriter().write(errorMsg);
} catch (IOException e) {
log.debug("IO exception during output",e );
}
}
protected OntModel getWriteModel(HttpServletRequest request){
HttpSession session = request.getSession(false);
if( session == null || session.getAttribute("jenaOntModel") == null )
return (OntModel)getServletContext().getAttribute("jenaOntModel");
else
return (OntModel)session.getAttribute("jenaOntModel");
}
protected OntModel getQueryModel(HttpServletRequest request){
return getWriteModel(request);
}
Log log = LogFactory.getLog(PrimitiveRdfEdit.class.getName());
static public boolean checkLoginStatus(HttpServletRequest request, HttpServletResponse response){
LoginFormBean loginBean = (LoginFormBean) request.getSession().getAttribute("loginHandler"); LoginFormBean loginBean = (LoginFormBean) request.getSession().getAttribute("loginHandler");
if (loginBean == null){ if (loginBean == null){
return false; return false;
} else { } else {
return true; return true;
} }
} }
} }

View file

@ -226,12 +226,16 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
// Run the search term through the query parser so that it gets normalized in the same // Run the search term through the query parser so that it gets normalized in the same
// way the index is normalized. // way the index is normalized.
QueryParser queryParser = new QueryParser(Entity2LuceneDoc.term.NAME, analyzer); // QueryParser queryParser = new QueryParser(Entity2LuceneDoc.term.NAMEUNSTEMMED, analyzer);
query = queryParser.parse(querystr + "*"); // query = queryParser.parse(querystr + "*");
querystr = querystr.toLowerCase();
{ {
BooleanQuery boolQuery = new BooleanQuery(); BooleanQuery boolQuery = new BooleanQuery();
boolQuery.add(query, BooleanClause.Occur.MUST); boolQuery.add(
new WildcardQuery(new Term(Entity2LuceneDoc.term.NAME, querystr + '*')),
BooleanClause.Occur.MUST);
//boolQuery.add(query, BooleanClause.Occur.MUST);
Object param = request.getParameter("type"); Object param = request.getParameter("type");
boolQuery.add( new TermQuery( boolQuery.add( new TermQuery(
new Term(Entity2LuceneDoc.term.RDFTYPE, new Term(Entity2LuceneDoc.term.RDFTYPE,

View file

@ -11,10 +11,17 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
public class PrimitiveRdfEditTest { public class PrimitiveRdfEditTest {
OntModel testModel;
WebappDaoFactory wdf;
private String testN3a = private String testN3a =
"<http://example.com/motorcycles/honda/vtl1000> <http://example.com/engines/displacement> \"1000cm3\" ." + "<http://example.com/motorcycles/honda/vtl1000> <http://example.com/engines/displacement> \"1000cm3\" ." +
@ -25,18 +32,12 @@ public class PrimitiveRdfEditTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception { }
}
@Test @Test
public void testProcessChanges() throws Exception { public void testProcessChanges() throws Exception {
OntModel writeModel = ModelFactory.createOntologyModel(); OntModel writeModel = ModelFactory.createOntologyModel();
String testN3a =
"<http://example.com/motorcycles/honda/vtl1000> <http://example.com/engines/displacement> \"1000cm3\" ." +
"<http://example.com/motorcycles/honda/919> <http://example.com/engines/displacement> \"919cm3\" ." ;
String testN3b =
"<http://example.com/motorcycles/honda/919> <http://example.com/motorcycles/relatedTo> <http://exmaple.com/motorcycle/honda/599> ." ;
int totalStmts = 3; int totalStmts = 3;
PrimitiveRdfEdit pre = new PrimitiveRdfEdit(); PrimitiveRdfEdit pre = new PrimitiveRdfEdit();

View file

@ -3,11 +3,16 @@
<div> <div>
<form method="POST"> <form method="POST">
additions: Addition:<br />
<textarea name="additions"></textarea> <textarea name="additions"></textarea>
retractions: <br /><br />
Retraction:<br />
<textarea name="retractions"></textarea> <textarea name="retractions"></textarea>
<br /><br />
<div> <div>
N3<input type="radio" name="rdfFormat" value="N3"/> N3<input type="radio" name="rdfFormat" value="N3"/>
TURTLE<input type="radio" name="rdfFormat" value="TURTLE"/> TURTLE<input type="radio" name="rdfFormat" value="TURTLE"/>