updates to allow autocomplete to edit an existing relationship and allow for creation of a new URI for the object (even with the old URI in scope)

This commit is contained in:
hjkhjk54 2012-03-08 22:40:19 +00:00
parent f0d005cb32
commit 5e025d66af
5 changed files with 144 additions and 5 deletions

View file

@ -28,6 +28,7 @@ import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
public class FreemarkerConfiguration extends Configuration {
@ -108,6 +109,9 @@ public class FreemarkerConfiguration extends Configuration {
sharedVariables.putAll(getMethods());
sharedVariables.put("siteTagline", appBean.getShortHand());
//Put in edit configuration constants - useful for freemarker templates/editing
sharedVariables.put("editConfigurationConstants", EditConfigurationConstants.exportConstants());
for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) {
try {
setSharedVariable(variable.getKey(), variable.getValue());

View file

@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
@ -23,6 +24,7 @@ import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
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.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities;
/**
@ -41,7 +43,6 @@ public class ProcessRdfForm {
private EditN3GeneratorVTwo populator;
private Map<String,String> urisForNewResources = null;
/**
* Construct the ProcessRdfForm object.
*/
@ -172,6 +173,12 @@ public class ProcessRdfForm {
//need to substitute into the return to URL becase it may need new resource URIs
List<String> URLToReturnTo = Arrays.asList(submission.getEntityToReturnTo());
/* *********** Check if new resource needs to be forcibly created ******** */
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
substituteInForcedNewURIs(urisForNewResources, submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added form URIs that required new URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
/* ********** Form submission URIs ********* */
substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
@ -182,10 +189,13 @@ public class ProcessRdfForm {
logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
//Retractions does NOT get values from form.
/* *********** Add subject, object and predicate ******** */
substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
/* ********* Existing URIs and Literals ********** */
substituteInMultiURIs(editConfig.getUrisInScope(),
requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
@ -197,7 +207,8 @@ public class ProcessRdfForm {
//Both Assertions and Retractions get existing values.
/* ************ Edits may need new resources *********** */
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
//moved this up?
//urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
// Only Assertions get new resources.
@ -205,6 +216,8 @@ public class ProcessRdfForm {
submission.setEntityToReturnTo(URLToReturnTo.get(0));
}
//TODO: maybe move this to utils or contorller?
public static AdditionsAndRetractions addDependentDeletes( AdditionsAndRetractions changes, Model queryModel){
//Add retractions for dependent resource delete if that is configured and
@ -455,5 +468,35 @@ public class ProcessRdfForm {
}
}
/*
* In some situations, an object may have an existing URI but be left blank
* when the desired behavior is that a new object be created to replace the existing URI
* E.g. autocomplete forms that allow editing of autocomplete fields
*/
@SuppressWarnings("unchecked")
private void substituteInForcedNewURIs(
Map<String, String> urisForNewResources, Map<String, List<String>> urisFromForm,
List<String> requiredAsserts, List<String> optionalAsserts,
List<String> uRLToReturnTo) {
Map<String, List<String>> newUris = new HashMap<String, List<String>>();
//Check if any values from the submission have the "force new uri" value
//TODO: Check how to handle multiple new resource values
Iterator<String> keyIterator = urisFromForm.keySet().iterator();
while(keyIterator.hasNext()) {
String key = keyIterator.next().toString();
if(urisFromForm.get(key).contains(EditConfigurationConstants.NEW_URI_SENTINEL)) {
String newUri = urisForNewResources.get(key);
List<String> newUrisForKey = new ArrayList<String>();
newUrisForKey.add(newUri);
newUris.put(key, newUrisForKey);
}
}
if(newUris.size() > 0) {
substituteInMultiURIs(newUris, requiredAsserts, optionalAsserts, uRLToReturnTo);
}
}
private static Log log = LogFactory.getLog(ProcessRdfForm.class);
}

View file

@ -0,0 +1,36 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.ProcessRdfForm;
public class EditConfigurationConstants {
/** Constants used by edit configuration */
//forces creation of new uri if present
public static final String NEW_URI_SENTINEL = ">NEW URI REQUIRED<";
//For freemarker configuration
public static Map<String, String> exportConstants() {
Map<String, String> constants = new HashMap<String, String>();
java.lang.reflect.Field[] fields = EditConfigurationConstants.class.getDeclaredFields();
for(java.lang.reflect.Field f: fields) {
if(Modifier.isStatic(f.getModifiers()) &&
Modifier.isPublic(f.getModifiers())) {
try {
constants.put(f.getName(), f.get(null).toString());
} catch(Exception ex) {
log.error("An exception occurred in trying to retrieve this field ", ex);
}
}
}
return constants;
}
private static Log log = LogFactory.getLog(EditConfigurationConstants.class);
}

View file

@ -50,6 +50,8 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{
private Log log = LogFactory.getLog(ProcessRdfFormController.class);
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.DO_FRONT_END_EDITING.ACTIONS;

View file

@ -15,6 +15,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
public class ProcessRdfFormTest extends AbstractTestClass{
@ -243,6 +244,59 @@ public class ProcessRdfFormTest extends AbstractTestClass{
ResourceFactory.createResource("http://test.com/uri3")));
}
@Test
//Edit existing statement
public void forcedNewResourceTest() throws Exception{
/* A very basic new statement edit. */
EditConfigurationVTwo config = new EditConfigurationVTwo();
config.setEditKey("mockEditKey");
config.setN3Required(Arrays.asList("?newRes ?test2 ?test3 ." ));
config.setUrisOnform(Arrays.asList( "newRes", "test2", "test3"));
//set uris in scope to include an existing value for new resource
config.addUrisInScope("newRes", Arrays.asList("<http://test.com/uri1>"));
config.addNewResource("newRes", null);
config.setEntityToReturnTo("?newRes");
Map<String,String[]> values = new HashMap<String, String[]>();
//value from form should indicate that newRes should have new uri created
values.put("newRes", (new String[] {EditConfigurationConstants.NEW_URI_SENTINEL}));
values.put("test2", (new String[] {"http://test.com/uri2"}));
values.put("test3", (new String[] {"http://test.com/uri3"}));
values.put("editKey", (new String[] {"mockEditKey"}));
MultiValueEditSubmission submission = new MultiValueEditSubmission(values, config);
ProcessRdfForm processor = new ProcessRdfForm(config,getMockNewURIMaker());
/* test just the N3 substitution part */
List<String>req = config.getN3Required();
List<String>opt = config.getN3Optional();
processor.subInValuesToN3( config , submission, req, opt, null , null);
assertNotNull(req);
assertTrue( req.size() > 0);
assertNotNull(req.get(0));
assertEquals("<"+NEWURI_STRING + "0> <http://test.com/uri2> <http://test.com/uri3> .", req.get(0));
assertEquals("<" + NEWURI_STRING + "0>", submission.getEntityToReturnTo());
/* test the N3 and parse RDF parts */
AdditionsAndRetractions changes = processor.process( config, submission );
assertNotNull( changes );
assertNotNull( changes.getAdditions() );
assertNotNull( changes.getRetractions());
assertTrue( changes.getAdditions().size() == 1 );
//the old uri should be removed
assertTrue( changes.getRetractions().size() == 0 );
assertTrue( changes.getAdditions().contains(
ResourceFactory.createResource(NEWURI_STRING + "0"),
ResourceFactory.createProperty("http://test.com/uri2"),
ResourceFactory.createResource("http://test.com/uri3")));
}
String NEWURI_STRING= "http://newURI/n";