From 263cca27279f8c0af412dc36cecf374161c2a49c Mon Sep 17 00:00:00 2001 From: hjkhjk54 Date: Fri, 1 Jul 2011 21:43:59 +0000 Subject: [PATCH] Creating new versions that can handle multi-valued parameters for Edit Configuration and n3 editing --- .../vitro/webapp/controller/VitroRequest.java | 16 +- .../AdditionsAndRetractions.java | 2 +- .../n3editing/VTwo/EditConfigurationVTwo.java | 887 ++++++++++++++++++ .../edit/n3editing/VTwo/EditElementVTwo.java | 47 + .../n3editing/VTwo/EditN3GeneratorVTwo.java | 421 +++++++++ .../EditSubmissionUtils.java | 2 +- .../VTwo/EditSubmissionVTwoPreprocessor.java | 9 + .../webapp/edit/n3editing/VTwo/FieldVTwo.java | 407 ++++++++ .../MultiValueEditSubmission.java | 79 +- .../{processEdit => VTwo}/ProcessRdfForm.java | 38 +- .../n3editing/VTwo/SparqlEvaluateVTwo.java | 241 +++++ .../DefaultDataPropertyFormGenerator.java | 12 +- .../DefaultObjectPropertyFormGenerator.java | 28 +- .../EditConfigurationGenerator.java | 4 +- .../InstitutionalInternalClassForm.java | 6 +- .../generators/MenuEditingFormGenerator.java | 302 ++++++ ...DataPropStmtRequestDispatchController.java | 218 ----- .../EditRequestDispatchController.java | 54 +- .../controller/ProcessRdfFormController.java | 31 +- .../processEdit/EditN3Generator.java | 18 +- .../webapp/filters/VitroRequestPrep.java | 6 + .../edit/EditConfigurationTemplateModel.java | 6 +- ...MultiValueEditSubmissionTemplateModel.java | 34 + .../VTwo/EditN3GeneratorVTwoTest.java | 55 ++ .../processEdit/EditN3GeneratorTest.java | 94 +- webapp/web/edit/editRequestDispatch.jsp | 9 + 26 files changed, 2660 insertions(+), 366 deletions(-) rename webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/{processEdit => VTwo}/AdditionsAndRetractions.java (95%) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwo.java rename webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/{processEdit => VTwo}/EditSubmissionUtils.java (97%) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionVTwoPreprocessor.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/FieldVTwo.java rename webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/{processEdit => VTwo}/MultiValueEditSubmission.java (77%) rename webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/{processEdit => VTwo}/ProcessRdfForm.java (87%) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/SparqlEvaluateVTwo.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/MenuEditingFormGenerator.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditDataPropStmtRequestDispatchController.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/MultiValueEditSubmissionTemplateModel.java create mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwoTest.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index 7c35231c5..1d80699b7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -22,7 +22,9 @@ public class VitroRequest extends HttpServletRequestWrapper { private static final String FROM_ENCODING = "ISO-8859-1"; private static final String TO_ENCODING = "UTF-8"; public static boolean convertParameterEncoding = true; - + //Attribute in case of special model editing such as display model editing + public static final String SPECIAL_WRITE_MODEL = "specialWriteModel"; + public static boolean getConvertParameterEncoding() { return convertParameterEncoding; } @@ -109,6 +111,18 @@ public class VitroRequest extends HttpServletRequestWrapper { } } + //Method that retrieves write model, returns special model in case of write model + public OntModel getWriteModel() { + //if special write model doesn't exist use get ont model + if(this.getAttribute(this.SPECIAL_WRITE_MODEL) != null) { + return (OntModel)this.getAttribute(this.SPECIAL_WRITE_MODEL); + } else { + return getJenaOntModel(); + } + } + + + public OntModel getJenaOntModel() { Object ontModel = getAttribute("jenaOntModel"); if (ontModel instanceof OntModel) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/AdditionsAndRetractions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/AdditionsAndRetractions.java similarity index 95% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/AdditionsAndRetractions.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/AdditionsAndRetractions.java index f60693a51..d3467dfe5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/AdditionsAndRetractions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/AdditionsAndRetractions.java @@ -1,6 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit; +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; import java.util.List; import java.util.Map; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java new file mode 100644 index 000000000..0cc23e33c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java @@ -0,0 +1,887 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.joda.time.DateTime; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.ModelSelector; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.StandardModelSelector; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.StandardWDFSelector; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.WDFSelector; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditSubmissionVTwoPreprocessor; + +import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ResourceFactory; + +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.ModelChangePreprocessor; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.N3Validator; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditN3Utils; +import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; + + +/** + * Represents a set of fields on a form and how parameters from a from + * submission should be manipulated to create N3. + * + * Uris in urisInScope and urisOnForm should not have any quoting or escaping. + * + * Literals in literalsOnForm and literalsInScope should be escaped and quoted + * in preparation for N3. They may also be appended with a datatype or lang. + */ +public class EditConfigurationVTwo { + + //Strings representing required n3 for RDF + List n3Required; + //String representing optional N3 for RDF + List n3Optional; + //Names of variables of 'objects' i.e. URIs on form + List urisOnform; + //Names of variables corresponding to data values i.e. literals on form + List literalsOnForm; + //Names of variables corresponding to Files on form + List filesOnForm; + + //Multi values now supported for uris and literals, so second parameter needs to be List + //Mapping of variable name for object to values for object, i.e. URIs, e.g. "hasElement" = ", " + Map> urisInScope; + //Mapping from variable name to values for literals + Map> literalsInScope; + + //Map name of variable to sparql query which should return a one-column result set of URIs corresponding to variable + //E.g. sparql for inverse of object property + Map sparqlForAdditionalUrisInScope; + //Mapping variable to sparql query returning literals + Map sparqlForAdditionalLiteralsInScope; + + //Variable names to URI prefixes for variables that are allowed to have new instances created + Map newResources; + + //Variable names to fields, Field = additional configuration for variable + Map fields; + + //Mapping variable name to Sparql query to find existing literals corresponding to variable, result set should be one-column multi-row of literals + MapsparqlForExistingLiterals; + //Mapping variable name to Sparql query to find existing URIs corresponding to variable, result set should be one-column multi-row of URIs/URI resources + MapsparqlForExistingUris; + + String subjectUri; + String varNameForSubject; + + String predicateUri; + String varNameForPredicate; + + /** When this is a DataPropertyStmt edit, the object is not used, the + * DataPropertyStatement is retrieved using the subject, predicate and the + * datapropKey. When this edit is for a ObjectPropertyStmt, + * object is the uri without the quoting < or >. + */ + String object; + String varNameForObject; + boolean isObjectResource; + + String datapropKey; + String datapropValue; + + String urlPatternToReturnTo; + String entityToReturnTo; + String formUrl; + String editKey; + + List validators; + + EditN3GeneratorVTwo n3generator; + + private List modelChangePreprocessors; + + private List editSubmissionPreprocessors = null; + + private ProhibitedFromSearch prohibitedFromSearch; + + /** Name of freemarker template to generate form. */ + String template; + + /** URL to submit form to. */ + String submitToUrl; + + /** + * If true, then any dependent resources that are unlinked should be + * removed using DependentResourceDelete. + */ + private boolean useDependentResourceDelete = true; + + /** Model to write changes of a completed edit to. Usually this is null + * and the edit will be written to the main graph of the system. */ + private ModelSelector writeModelSelector; + + /** Model to query for existing and things like that. Usually this is null + * and the main Model of the system will be used as the default. */ + private ModelSelector queryModelSelector; + + /** Model to check when making new URIs to check that there is not already + * a resource with a given URI. */ + private ModelSelector resourceModelSelector; + + /** WebappDaoFactory to build option, check box, and radio button lists. + * Usually this is set to null and the main model will be used. */ + private WDFSelector wdfSelectorForOptons; + + public EditConfigurationVTwo(){ + writeModelSelector = StandardModelSelector.selector; + queryModelSelector = StandardModelSelector.selector; + resourceModelSelector = StandardModelSelector.selector; + wdfSelectorForOptons = StandardWDFSelector.selector; + } + + + /** + * Add symbols for things like currentTime and editingUser to + * editConfig.urisInScope and editConfig.literalsInScope. + */ + public void addSystemValues( Model model, HttpServletRequest request, ServletContext context){ + if( model == null ) throw new Error("EditConfiguration.addSystemValues() needs a Model"); + if( request == null ) throw new Error("EditConfiguration.addSystemValues() needs a request"); + + /* current time */ + if( getSparqlForAdditionalLiteralsInScope() != null && + getSparqlForAdditionalLiteralsInScope().containsKey("currentTime") && + USE_SYSTEM_VALUE.equals(getSparqlForAdditionalLiteralsInScope().get("currentTime"))){ + //Updating so that this is represented as an XSD Date Time literal - to allow for comparison later + //Currently it appears that this is only used for file upload + //getLiteralsInScope().put("currentTime", ResourceFactory.createTypedLiteral(new Date())); + SimpleDateFormat dateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + String formattedDate = dateTime.format(Calendar.getInstance().getTime()); + List dateLiterals = new ArrayList(); + dateLiterals.add(ResourceFactory.createTypedLiteral(formattedDate, XSDDatatype.XSDdateTime)); + getLiteralsInScope().put("currentTime", dateLiterals); + } + + /* editing user */ + if( getSparqlForAdditionalUrisInScope() != null && + getSparqlForAdditionalUrisInScope().containsKey("editingUser") && + USE_SYSTEM_VALUE.equals(getSparqlForAdditionalUrisInScope().get("editingUser"))) { + + if( request.getSession() == null ) + throw new Error("EditConfiguration.addSystemValues() needs a session"); + + /* ********** Get URI of a logged in user ************** */ + String userUri = EditN3Utils.getEditorUri(request); + log.debug("EditConfiguration.java - checking system value for User URI " + userUri); + List userUriList = new ArrayList(); + userUriList.add(userUri); + getUrisInScope().put("editingUser", userUriList); + } + } + + //TODO: Check if require + /** + * Make a copy of this EditConfiguration, prepare for a DataProperty update + * and return it. + */ + public void prepareForDataPropUpdate( Model model, DataPropertyStatement dpStmt){ + if( model == null ) throw new Error("EditConfiguration.prepareForDataPropUpdate() needs a Model"); + if( isObjectResource ){ + throw new Error("This request seems to be an objectPropertyStmt update, not a DataPropStmt update"); + } else if (datapropKey == null) { + throw new Error("This request does not appear to be for an update since it lacks a dataprop object or a dataProp hash key "); + } + + //TODO: Check if multiple statements might affect this implementation? + List dataPropLiterals = new ArrayList(); + dataPropLiterals.add(new EditLiteral(dpStmt.getData(),dpStmt.getDatatypeURI(), dpStmt.getLanguage())); + getLiteralsInScope().put(varNameForObject, dataPropLiterals); + + // run SPARQL, sub in values + SparqlEvaluateVTwo sparqlEval = new SparqlEvaluateVTwo(model); + runSparqlForAdditional( sparqlEval ); + runSparqlForExisting( sparqlEval ); + //Saving previous N3 state before edit + //build retraction N3 for each Field + for(String var : getFields().keySet() ){ + FieldVTwo field = getField(var); + List retractions = null; + retractions = n3generator.subInMultiLiterals(getLiteralsInScope(),field.getAssertions()); + retractions = n3generator.subInMultiUris(getUrisInScope(), retractions); + field.setRetractions(retractions); + } + } + + /** + * Make a copy of this EditConfiguration, prepare for a ObjectProperty update + * and return it. + */ + public void prepareForObjPropUpdate( Model model ){ + if( model == null ) { + //Added parens and output + log.debug("Model is null and will be throwing an error"); + throw new Error("EditConfiguration.prepareForObjPropUpdate() needs a Model");} + if( !isObjectResource ) + { + //Added parens and output + log.debug("This is not an object resource? lacks dataprop "); + throw new Error("This request does not appear to be for an update since it lacks a dataprop object or a dataProp hash key "); + } + //find the variable for object, this anchors the paths to the existing values + if( object == null || object.trim().length() == 0) + { + //Added parens and output + log.debug("Object is null or object length is null"); + throw new Error("This request does not appear to be for an update since it lacks an object"); + } + + List objectUris = new ArrayList(); + objectUris.add(object); + getUrisInScope().put( varNameForObject, objectUris); + log.debug("Putting uris in scope - var name for object " + varNameForObject + " and object is " + object); + // run SPARQL, sub in values + SparqlEvaluateVTwo sparqlEval = new SparqlEvaluateVTwo( model ); + runSparqlForAdditional( sparqlEval ); + try { + runSparqlForExisting( sparqlEval ); + } catch (Exception e) { + e.printStackTrace(); + } + + //build retraction N3 for each Field + for(String var : getFields().keySet() ){ + FieldVTwo field = getField(var); + List retractions = null; + retractions = n3generator.subInMultiLiterals(getLiteralsInScope(),field.getAssertions()); + retractions = n3generator.subInMultiUris(getUrisInScope(), retractions); + field.setRetractions(retractions); + } + } + + + public void prepareForNonUpdate( Model model ){ + if( model == null ) throw new Error("EditConfiguration.prepareForNonUpdate() needs a Model"); + + SparqlEvaluateVTwo sparqlEval = new SparqlEvaluateVTwo( model ); + runSparqlForAdditional( sparqlEval ); + //runSparqlForExisting( sparqlEval ); + } + + public void setFields(Map fields) { + this.fields = fields; + } + + public void prepareForResubmit(MultiValueEditSubmission editSub){ + //get any values from editSub and add to scope + } + + + /** + * Runs the queries for additional uris and literals then add those back into + * the urisInScope and literalsInScope. + */ + public void runSparqlForAdditional(SparqlEvaluateVTwo sparqlEval){ + sparqlEval.evaluateForAdditionalUris( this ); + sparqlEval.evalulateForAdditionalLiterals( this ); + } + + public void runSparqlForExisting(SparqlEvaluateVTwo sparqlEval){ + sparqlEval.evaluateForExistingUris( this ); + sparqlEval.evaluateForExistingLiterals( this ); + } + + public FieldVTwo getField(String key){ + if( fields == null) { + throw new Error("hashmap of field objects must be set before you can get a value from the EditConfiguration"); + } + return fields.get(key); + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public List getN3Required() { + List copyForPassByValue = new ArrayList (n3Required.size()); + for( String str : n3Required){ + copyForPassByValue.add(str); + } + return copyForPassByValue; + } + + public void setN3Required(List n3Required) { + this.n3Required = n3Required; + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public List getN3Optional() { + List copyForPassByValue = new ArrayList (n3Optional.size()); + for( String str : n3Optional){ + copyForPassByValue.add(str); + } + return copyForPassByValue; + } + + public void setN3Optional(List n3Optional) { + this.n3Optional = n3Optional; + } + + public Map getNewResources() { + return newResources; + } + + public void setNewResources(Map newResources) { + this.newResources = newResources; + } + + public List getUrisOnform() { + return urisOnform; + } + + public void setUrisOnform(List urisOnform) { + this.urisOnform = urisOnform; + } + + public void setFilesOnForm(List filesOnForm){ + this.filesOnForm = filesOnForm; + } + + public List getFilesOnForm(){ + return filesOnForm; + } + + public List getLiteralsOnForm() { + return literalsOnForm; + } + + public void setLiteralsOnForm(List literalsOnForm) { + this.literalsOnForm = literalsOnForm; + } + + public Map> getUrisInScope() { + return urisInScope; + } + + public void setUrisInScope(Map> urisInScope) { + this.urisInScope = urisInScope; + } + + public Map> getLiteralsInScope() { + return literalsInScope; + } + + public void setLiteralsInScope(Map> literalsInScope) { + this.literalsInScope = literalsInScope; + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public Map getSparqlForAdditionalUrisInScope() { + Map copyForPassByValue = new HashMap(); + copy(sparqlForAdditionalUrisInScope, copyForPassByValue); + return copyForPassByValue; + } + + public void setSparqlForAdditionalUrisInScope(Map sparqlForAdditionalUrisInScope) { + this.sparqlForAdditionalUrisInScope = sparqlForAdditionalUrisInScope; + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public Map getSparqlForAdditionalLiteralsInScope() { + Map copyForPassByValue = new HashMap(); + copy(sparqlForAdditionalLiteralsInScope, copyForPassByValue); + return copyForPassByValue; + } + + private Map copy(Map source, Map dest){ + if( source == null ) return null; + dest.clear(); + for( String key : source.keySet()){ + dest.put(key, source.get(key)); + } + return dest; + } + + public void setSparqlForAdditionalLiteralsInScope(Map sparqlForAdditionalLiteralsInScope) { + this.sparqlForAdditionalLiteralsInScope = sparqlForAdditionalLiteralsInScope; + } + + public String getEntityToReturnTo() { + return entityToReturnTo; + } + + public void setEntityToReturnTo(String entityToReturnTo) { + this.entityToReturnTo = entityToReturnTo; + } + + public String getUrlPatternToReturnTo() { + return urlPatternToReturnTo; + } + + public void setUrlPatternToReturnTo(String s) { + urlPatternToReturnTo = s; + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public Map getSparqlForExistingLiterals() { + Map copyForPassByValue = new HashMap(); + copy(sparqlForExistingLiterals, copyForPassByValue); + return copyForPassByValue; + } + + public void setSparqlForExistingLiterals(Map sparqlForExistingLiterals) { + this.sparqlForExistingLiterals = sparqlForExistingLiterals; + } + + /** return a copy of the value so that the configuration is not modified by external code. + * @return + */ + public Map getSparqlForExistingUris() { + Map copyForPassByValue = new HashMap(); + copy(sparqlForExistingUris, copyForPassByValue); + return copyForPassByValue; + } + + public void setSparqlForExistingUris(Map sparqlForExistingUris) { + this.sparqlForExistingUris = sparqlForExistingUris; + } + + public static List JsonArrayToStringList(JSONArray jarray){ + ArrayList outv = new ArrayList(); + if( jarray != null ){ + for( int i = 0; i< jarray.length(); i++){ + try{ + outv.add(jarray.getString(i)); + }catch(JSONException je){} + } + } + return outv; + } + + public static Map JsonObjToMap(JSONObject jobj){ + HashMap outv = new HashMap(); + if( jobj != null ){ + Iterator keyIt = jobj.keys(); + while( keyIt.hasNext()){ + try{ + String key = (String)keyIt.next(); + outv.put(key,jobj.getString(key)); + }catch(JSONException je){ } + } + } + return outv; + } + + //Like above except returning Map with multiple values possible for key + //Are we doing this anymore? + public static Map> JsonObjToMultiValueMap(JSONObject jobj){ + HashMap> outv = new HashMap>(); + if( jobj != null ){ + Iterator keyIt = jobj.keys(); + while( keyIt.hasNext()){ + try{ + String key = (String)keyIt.next(); + JSONArray jsonArray = jobj.getJSONArray(key); + int len = jsonArray.length(); + List valueString = new ArrayList(); + for(int i = 0; i < len ; i++) { + valueString.add(jsonArray.get(i).toString()); + } + + outv.put(key,valueString); + }catch(JSONException je){ } + } + } + return outv; + } + public static Map JsonObjToMapOfFields(JSONObject jobj){ + HashMap outv = new HashMap(); + if( jobj != null ){ + Iterator keyIt = jobj.keys(); + while( keyIt.hasNext()){ + try{ + String key = (String)keyIt.next(); + JSONObject obj = jobj.getJSONObject(key); + FieldVTwo field = new FieldVTwo(obj, key); + outv.put(key, field); + }catch(JSONException je){ } + } + } + return outv; + } + + + public Map> getN3ForFields(){ + return fieldsToMap( getFields() ); + } + + private Map> fieldsToMap( Map fields){ + Map> out = new HashMap>(); + for( String fieldName : fields.keySet()){ + FieldVTwo field = fields.get(fieldName); + + List copyOfN3 = new ArrayList(); + for( String str : field.getAssertions()){ + copyOfN3.add(str); + } + out.put( fieldName, copyOfN3 ); + } + return out; + } + + /* ********************** static methods to get EditConfigs from Session ******************************** */ + + public static void clearAllConfigsInSession( HttpSession sess ){ + if(sess == null ) return; + sess.removeAttribute("editConfiguration"); + } + + + public static void clearEditConfigurationInSession(HttpSession session, EditConfigurationVTwo editConfig) { + if( session == null || editConfig == null ) + return; + Map configs = (Map)session.getAttribute("EditConfigurations"); + if( configs == null ) + return ; + if( configs.containsKey( editConfig.editKey ) ) + configs.remove( editConfig.editKey ); + } + + public static void putConfigInSession(EditConfigurationVTwo ec, HttpSession sess){ + if( sess == null ) + throw new Error("EditConfig: could not put config in session because session was null"); + if( ec.editKey == null ) + throw new Error("EditConfig: could not put into session because editKey was null."); + + Map configs = (Map)sess.getAttribute("EditConfigurations"); + if( configs == null ){ + configs = new HashMap(); + sess.setAttribute("EditConfigurations",configs); + } + configs.put(ec.editKey , ec); + } + + public static EditConfigurationVTwo getConfigFromSession(HttpSession sess, String editKey){ + Map configs = (Map)sess.getAttribute("EditConfigurations"); + if( configs == null ) + return null; + + EditConfigurationVTwo config = configs.get( editKey ); + if( config == null ) + return null; + else + return config; + } + + /** + * This may return null, which indicates that there is no editKey or EditConfiguration in the + * request or session. If the queryParams are supplied, look for the editKey + * there first since multipart parsing might have cleared them from the request. + */ + public static EditConfigurationVTwo getConfigFromSession( HttpSession sess, HttpServletRequest request ){ + String key = getEditKey(request); + + if( key == null ) + return null; + return getConfigFromSession(sess, key); + } + + /** + * The editKey can be a HTTP query parameter or it can be a request attribute. + */ + public static String getEditKey( ServletRequest request){ + String key = null; + if( request instanceof HttpServletRequest ){ + HttpServletRequest hsreq = (HttpServletRequest)request; + boolean isMultipart = ServletFileUpload.isMultipartContent(hsreq); + if( isMultipart ) { + //multipart parsing will consume all request parameters so + //the editKey needs to be stashed in the request attributes. + key = (String)request.getAttribute("editKey"); + if( key == null ) { + // handle the cancel button where nothing is really uploaded + key = request.getParameter("editKey"); + } + }else{ + key = (String)request.getAttribute("editKey"); + if( key != null ){ + return key; + } else { + key = request.getParameter("editKey"); + } + } + } + + if( key != null && key.trim().length() > 0 ){ + return key; + }else{ + log.debug("cannnot find editKey in request query parameters or from request"); + return null; + } + } + + public static String newEditKey(HttpSession sess){ + DateTime time = new DateTime(); + int mills = time.getMillisOfDay(); + + Map configs = (Map)sess.getAttribute("EditConfigurations"); + if( configs == null ){ + return Integer.toString(mills); + }else{ + while( configs.containsKey( Integer.toString(mills) )){ + mills ++; + } + return Integer.toString(mills); + } + } + + /* + * getters and setters + */ + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public boolean isObjectResource() { + return isObjectResource; + } + + public void setObjectResource(boolean isObjectResource) { + this.isObjectResource = isObjectResource; + } + + public String getDatapropKey() { + return datapropKey; + } + + public void setDatapropKey(String datapropKey) { + this.datapropKey = datapropKey; + } + + public String getSubjectUri() { + return subjectUri; + } + + public void setSubjectUri(String subjectUri) { + this.subjectUri = subjectUri; + } + + public String getPredicateUri() { + return predicateUri; + } + + public void setPredicateUri(String predicateUri) { + this.predicateUri = predicateUri; + } + + public Map getFields() { + return fields; + } + + public String getEditKey() { + return editKey; + } + + public void setEditKey(String editKey) { + this.editKey = editKey; + } + + public String getFormUrl() { + return formUrl; + } + + public void setFormUrl(String formUrl) { + this.formUrl = formUrl; + } + + public EditN3GeneratorVTwo getN3Generator(){ + return n3generator; + } + + public void setN3Generator(EditN3GeneratorVTwo gen) { + this.n3generator = gen; + } + + public String getVarNameForSubject() { + return this.varNameForSubject; + } + + public void setVarNameForSubject(String varName) { + this.varNameForSubject = varName; + } + + public String getVarNameForPredicate() { + return this.varNameForPredicate; + } + + public void setVarNameForPredicate(String varName) { + this.varNameForPredicate = varName; + } + + public String getVarNameForObject(){ + return this.varNameForObject; + } + + public void setVarNameForObject(String varName) { + this.varNameForObject = varName; + } + + /**If this is set to true, then dependent resources should be deleted on edits that + * remove the parent resource. + */ + public boolean isUseDependentResourceDelete() { + return useDependentResourceDelete; + } + + /**If this is set to true, then dependent resources should be deleted on edits that + * remove the parent resource. + */ + public void setUseDependentResourceDelete(boolean useDependentResourceDelete) { + this.useDependentResourceDelete = useDependentResourceDelete; + } + + public List getModelChangePreprocessors() { + return this.modelChangePreprocessors; + } + + public List setModelChangePreprocessors() { + return this.modelChangePreprocessors; + } + + public void addModelChangePreprocessor( ModelChangePreprocessor modelChangePreprocessor) { + this.modelChangePreprocessors.add( modelChangePreprocessor ); + } + + public void setProhibitedFromSearch( ProhibitedFromSearch prohibitedFromSearch) { + this.prohibitedFromSearch = prohibitedFromSearch; + } + + public ProhibitedFromSearch getProhibitedFromSearch() { + return this.prohibitedFromSearch; + } + + private void debugScope(String msg){ + if( log.isDebugEnabled()){ + log.debug(msg); + log.debug("literalsInScope:"); + for( String key: literalsInScope.keySet() ){ + String val = literalsInScope.get(key).toString(); + log.debug( key + " " + val ); + } + log.debug("uris in scope: " ); + for( String key: urisInScope.keySet() ){ + String val = urisInScope.get(key).toString(); + log.debug( key + " " + val ); + } + } + } + + public final static String USE_SYSTEM_VALUE = "USE_SYSTEM_VALUE"; + + private static final Log log = LogFactory.getLog(EditConfigurationVTwo.class.getName()); + + public ModelSelector getWriteModelSelector() { + return writeModelSelector; + } + + public void setWriteModelSelector(ModelSelector writeModel) { + if( writeModel != null ) + this.writeModelSelector = writeModel; + } + + public ModelSelector getQueryModelSelector() { + return queryModelSelector; + } + + public void setQueryModelSelector(ModelSelector queryModel) { + if( queryModel != null ) + this.queryModelSelector = queryModel; + } + + public WDFSelector getWdfSelectorForOptons() { + return wdfSelectorForOptons; + } + + public void setWdfSelectorForOptons(WDFSelector wdfForOptons) { + this.wdfSelectorForOptons = wdfForOptons; + } + + public ModelSelector getResourceModelSelector() { + return resourceModelSelector; + } + + public void setResourceModelSelector(ModelSelector resourceModelSelector) { + if( resourceModelSelector != null ) + this.resourceModelSelector = resourceModelSelector; + } + + public List getValidators() { + return validators; + } + + public void addValidator( N3Validator validator){ + if( this.validators == null ) + this.validators = new ArrayList(); + this.validators.add(validator); + } + + public void addEditSubmissionPreprocessor( EditSubmissionVTwoPreprocessor preprocessor){ + if( editSubmissionPreprocessors == null ) + editSubmissionPreprocessors = new ArrayList(); + editSubmissionPreprocessors.add(preprocessor); + } + + public List getEditSubmissionPreprocessors() { + return editSubmissionPreprocessors; + } + + public void setTemplate(String template){ + this.template = template; + } + + public String getTemplate() { + return this.template; + } + + public String getSubmitToUrl() { + return submitToUrl; + } + + public void setSubmitToUrl(String submitToUrl) { + this.submitToUrl = submitToUrl; + } + + public boolean isUpdate(){ + return this.getObject() != null && this.getObject().trim().length() > 0; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java new file mode 100644 index 000000000..677b0831a --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java @@ -0,0 +1,47 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; + +import java.util.Map; +import java.util.List; +import com.hp.hpl.jena.rdf.model.Literal; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; +import freemarker.template.Configuration; +/** + * All classes that implement this interface must have a public constructor that + * takes a edu.cornell.mannlib.vitro.webapp.edit.n3editing.Field. It will be + * called with using reflection. + */ +public interface EditElementVTwo { + /** + * This is a method to get a map of variable name to Literal value from the submitted form. + */ + public Map> + getLiterals(String fieldName, EditConfigurationVTwo editConfig, Map queryParameters ); + + /** + * This is a method to get a map of variable name to URI values from the submitted form. + */ + public Map> + getURIs(String fieldName, EditConfigurationVTwo editConfig, Map queryParameters ); + + /** + * Gets validation error messages. Returns an empty list if there are no errors. + */ + public Map + getValidationMessages(String fieldName, EditConfigurationVTwo editConfig, Map queryParameters); + + /** + * This is a method to generate the HTML output for a form element. It should use a freemarker template + * to produce the output. + */ + public String draw(String fieldName, EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub, Configuration fmConfig); + + /* in the future, we may need to get existing values */ + /* + public Map getExistingLiterals(???) + public Map getExistingURIs(???); + */ +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwo.java new file mode 100644 index 000000000..a287c0b1b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwo.java @@ -0,0 +1,421 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import antlr.StringUtils; + +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.vocabulary.XSD; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; + +/** + * Builds the N3 strings for the given EditConfiguration, model + * and EditSubmission. Main responsibility is the proper substitution + * of URI and literal strings in to the template N3. + * + * + */ +public class EditN3GeneratorVTwo { + + EditConfigurationVTwo editConfig; + Log log = LogFactory.getLog( EditN3GeneratorVTwo.class ); + + public EditN3GeneratorVTwo( EditConfigurationVTwo editConfig ){ + this.editConfig = editConfig; + } + + public List generateN3(MultiValueEditSubmission editSub, Model model){ + return Collections.EMPTY_LIST; + } + + /** + * This is the method to use to substitute in URIs into variables of target N3 strings. + * This takes into account multiple values that would be returned from a select list. + * subInUris should no longer be used. + * It's important that the map contain String to List mapping. + * Before values are sent in, all of the values for a variable should be placed within an array + */ + + + public static List subInMultiUris(Map> varsToVals, List n3targets){ + + if( varsToVals == null || varsToVals.isEmpty() ) return n3targets; + ArrayList outv = new ArrayList(); + for( String target : n3targets){ + String temp = target; + Set keySet = varsToVals.keySet(); + for( String key : keySet) { + List value = varsToVals.get(key); + String valueString = value.toString(); + System.out.println("Value String is " + valueString); + valueString = org.apache.commons.lang.StringUtils.join(value, ">, <"); + valueString = "<" + valueString + ">"; + System.out.println("Value string is " + valueString); + temp = subInUris( key, valueString, temp) ; + } + outv.add(temp); + } + return outv; + } + + public static List subInUris(Map varsToVals, List targets){ + if( varsToVals == null || varsToVals.isEmpty() ) return targets; + ArrayList outv = new ArrayList(); + for( String target : targets){ + String temp = target; + for( String key : varsToVals.keySet()) { + temp = subInUris( key, varsToVals.get(key), temp) ; + } + outv.add(temp); + } + return outv; + } + + + + //Already includes "<> for URIs so no need to add those here + public static String subInUris(String var, String value, String target) { + //empty URIs get skipped + if( var == null || var.length() == 0 || value==null ) + return target; + /* var followed by dot some whitespace or var followed by whitespace*/ + String varRegex = "\\?" + var + "(?=\\.\\p{Space}|\\p{Space})"; + String out = null; + if("".equals(value)) + out = target.replaceAll(varRegex,">::" + var + " was BLANK::< "); + else { + String replaceWith = Matcher.quoteReplacement(value); + out = target.replaceAll(varRegex,replaceWith); + } + if( out != null && out.length() > 0 ) + return out; + else + return target; + } + /* + //For cases where comma delimited URIs sent in already including <> + public static String subInMultipleUris(String var, List values, String target){ + //empty URIs get skipped + if( var == null || var.length() == 0 || values==null || values.size() == 0) + return target; + + String varRegex = "\\?" + var + "(?=\\.\\p{Space}|\\p{Space})"; + String out = null; + //Process each + for(String value: values) { + if("".equals(value)) + out = target.replaceAll(varRegex,">::" + var + " was BLANK::< "); + else + out = target.replaceAll(varRegex,"<"+Matcher.quoteReplacement(value)+"> "); + } + if( out != null && out.length() > 0 ) + return out; + else + return target; + + } + */ + public static ListsubInUris(String var, String value, List targets){ + ArrayList outv =new ArrayList(); + for( String target : targets){ + outv.add( subInUris( var,value, target) ) ; + } + return outv; + } + + /** + * This is the method to use to substitute in Literals into variables of target N3 strings. + * This takes into account multiple values that would be returned from a select list. + * subInUris should no longer be used. + */ + public static List subInMultiLiterals(Map> varsToVals, List n3targets){ + return null; + } + + public List subInLiterals(Map varsToVals, List targets){ + if( varsToVals == null || varsToVals.isEmpty()) return targets; + + ArrayList outv =new ArrayList(); + for( String target : targets){ + String temp = target; + for( String key : varsToVals.keySet()) { + temp = subInLiterals( key, varsToVals.get(key), temp); + } + outv.add(temp); + } + return outv; + } + +// public ListsubInLiterals(String var, String value, List targets){ +// ArrayList outv =new ArrayList(); +// for( String target : targets){ +// outv.add( subInLiterals( var,value, target) ) ; +// } +// return outv; +// } + + /** + * When we sub in literals we have to take in to account the Lang or Datatype of + * the literal. N3 needs to have its literals escaped in Python style. Java regex + * Matcher is used to do the substitution and it need escaping to avoid group + * references, Matcher.quoteReplacement() serves the purpose. + * + */ + public String subInLiterals(String var, Literal literal, String target){ + String varRegex = "\\?" + var + "(?=\\.\\p{Space}|\\p{Space})"; + if (target==null ) { + log.error("subInLiterals was passed a null target"); + return "blankBecauseTargetOrValueWasNull"; + }else if( var == null ){ + log.warn("subInLiterals was passed a null var name"); + return target; + }else if( literal == null ){ + log.debug("subInLiterals was passed a null value for var '"+var+"'; returning target: '"+target+"'"); + return target; + } + + try{ + if( literal.getValue() == null ) + log.debug("value of literal for " + var + " was null"); + }catch(com.hp.hpl.jena.datatypes.DatatypeFormatException ex){ + log.debug("value for " + var + " " + ex.getMessage()); + } + + //if( editConfig != null && editConfig.getFields() != null && + // editConfig.getFields().get(var) != null ){ + //The var might not be in the editConfig.fields if an EditN3Generator + //is being used to substitute in values that are not on the form, + //eg ?fileSize for file uploads + + String replacement = null; + if ( literal.getLexicalForm().length()==0 ) { + log.debug("empty string found on form for " + var + "."); + replacement = ">::" + var + " was empty::<"; + }else{ + replacement = formatLiteral(literal); + } + + String out = null; + if( replacement != null ) + out = target.replaceAll(varRegex, Matcher.quoteReplacement( replacement )); + else + out = target; + + if( out != null && out.length() > 0 ) + return out; + else{ + log.debug("After attempting to substitue in literals, the target N3 was empty" ); + return target; + } + } + + public Map> substituteIntoValues + (Map> varsToUris, + Map> varsToLiterals, + Map> namesToN3 ) + { + Map> outHash = new HashMap>(); + + if (namesToN3==null) { + return outHash; + } else if (namesToN3.isEmpty()) { + return outHash; + } else { + for(String fieldName : namesToN3.keySet()){ + List n3strings = namesToN3.get(fieldName); + List newList = new ArrayList(); + if( varsToUris != null) + newList = subInMultiUris(varsToUris, n3strings); + if( varsToLiterals != null) + newList = subInMultiLiterals(varsToLiterals, newList); + outHash.put(fieldName, newList); + } + } + return outHash; + } + + protected String quoteForN3(String in){ + //TODO: THIS NEEDS TO BE ESCAPED FOR N3 which is python string escaping + return in; + } + + + /* + * bdc34 2008-07-33 + * + * The following methods are from + * HP's Jena project ver 2.5.5 + * Found in file Jena-2.5.5/src/com/hp/hpl/jena/n3/N3JenaWriterCommon.java + * + * The following copyright statement applies to these methods. + */ + + /* + * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + protected String formatLiteral(Literal literal) + { + String datatype = literal.getDatatypeURI() ; + String lang = literal.getLanguage() ; + String s = literal.getLexicalForm() ; + + if ( datatype != null ) + { + // Special form we know how to handle? + // Assume valid text + if ( datatype.equals(XSD.integer.getURI()) ) + { + try { + new java.math.BigInteger(s) ; + return s ; + } catch (NumberFormatException nfe) {} + // No luck. Continue. + // Continuing is always safe. + } + + if ( datatype.equals(XSD.decimal.getURI()) ) + { + // Must have ., can't have e or E + if ( s.indexOf('.') >= 0 && + s.indexOf('e') == -1 && s.indexOf('E') == -1 ) + { + // See if parsable. + try { + BigDecimal d = new BigDecimal(s) ; + return s ; + } catch (NumberFormatException nfe) {} + } + } + + if ( datatype.equals(XSD.xdouble.getURI()) ) + { + // Must have 'e' or 'E' (N3 and Turtle now read 2.3 as a decimal). + if ( s.indexOf('e') >= 0 || + s.indexOf('E') >= 0 ) + { + try { + // Validate it. + Double.parseDouble(s) ; + return s ; + } catch (NumberFormatException nfe) {} + // No luck. Continue. + } + } + } + // Format the text - with escaping. + StringBuffer sbuff = new StringBuffer() ; + + String quoteMarks = "\"" ; + + sbuff.append(quoteMarks); + pyString(sbuff, s ) ; + sbuff.append(quoteMarks); + + // Format the language tag + if ( lang != null && lang.length()>0) + { + sbuff.append("@") ; + sbuff.append(lang) ; + } + + // Format the datatype + if ( datatype != null ) + { + sbuff.append("^^") ; + sbuff.append(formatURI(datatype)) ; + } + return sbuff.toString() ; + } + + + /* + * + * see http://www.python.org/doc/2.5.2/ref/strings.html + * or see jena's n3 grammar jena/src/com/hp/hpl/jena/n3/n3.g + */ + protected static void pyString(StringBuffer sbuff, String s) + { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + // Escape escapes and quotes + if (c == '\\' || c == '"' ) + { + sbuff.append('\\') ; + sbuff.append(c) ; + continue ; + } + + // Whitespace + if (c == '\n'){ sbuff.append("\\n");continue; } + if (c == '\t'){ sbuff.append("\\t");continue; } + if (c == '\r'){ sbuff.append("\\r");continue; } + if (c == '\f'){ sbuff.append("\\f");continue; } + if (c == '\b'){ sbuff.append("\\b");continue; } + if( c == 7 ) { sbuff.append("\\a");continue; } + + // Output as is (subject to UTF-8 encoding on output that is) + sbuff.append(c) ; + +// // Unicode escapes +// // c < 32, c >= 127, not whitespace or other specials +// String hexstr = Integer.toHexString(c).toUpperCase(); +// int pad = 4 - hexstr.length(); +// sbuff.append("\\u"); +// for (; pad > 0; pad--) +// sbuff.append("0"); +// sbuff.append(hexstr); + } + } + + protected String formatURI(String uriStr) + { + // Not as a qname - write as a quoted URIref + // Should we unicode escape here? + // It should be right - the writer should be UTF-8 on output. + return "<"+uriStr+">" ; + } + + /************************************************************************* + * End code taken from the Jena project and Hewlett-Packard + *************************************************************************/ +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditSubmissionUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionUtils.java similarity index 97% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditSubmissionUtils.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionUtils.java index 1063fe41f..ab7d2e1bc 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditSubmissionUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionUtils.java @@ -1,6 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit; +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; import java.util.HashMap; import java.util.List; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionVTwoPreprocessor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionVTwoPreprocessor.java new file mode 100644 index 000000000..c92cb11f7 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditSubmissionVTwoPreprocessor.java @@ -0,0 +1,9 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; + +public interface EditSubmissionVTwoPreprocessor { + public void preprocess(MultiValueEditSubmission editSubmission); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/FieldVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/FieldVTwo.java new file mode 100644 index 000000000..bdca658c6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/FieldVTwo.java @@ -0,0 +1,407 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; +public class FieldVTwo { + + public enum OptionsType { + LITERALS, + HARDCODED_LITERALS, + STRINGS_VIA_DATATYPE_PROPERTY, + INDIVIDUALS_VIA_OBJECT_PROPERTY, + INDIVIDUALS_VIA_VCLASS, + MONIKERS_VIA_VCLASS, + CHILD_VCLASSES, + CHILD_VCLASSES_WITH_PARENT, + VCLASSGROUP, + FILE, + UNDEFINED, + DATETIME, + DATE, + TIME + }; + + public static String RDF_XML_LITERAL_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"; + + private boolean newResource; + + private static Log log = LogFactory.getLog( FieldVTwo.class ); + + private String name; + + /** + * List of basic validators. See BaiscValidation. + */ + private List validators; + + /** + * What type of options is this? + */ + private OptionsType optionsType; + + /** + * Special class to use for option type + */ + private Class customOptionType; + + /** + * Used for building Options when OptionsType is INDIVIDUALS_VIA_OBJECT_PROPERTY + */ + private String predicateUri; + /** + * Used for building Options when OptionsType is INDIVIDUALS_VIA_VCLASS + */ + private String objectClassUri; + + /** + * Used for holding the expected/required datatype of the predicate when the predicate is a datatype propertyl. + * this can be a explicit URI or a qname. + * example: + * "this is the literal"^^ + * or + * "this is the literal"^^someprefix:type23 + */ + private String rangeDatatypeUri; + + /** + * Used for holding the language of the literal when the predicate is a datatype property. + * This is the lang of the literal. lang strings must be: [a-z]+(-[a-z0-9]+)* + */ + private String rangeLang; + + /** + * If this is a Select and it is of OptionsType LITERALS, these are the literals. + */ + private List> literalOptions; + + /** + * Strings of N3 to add to model. + */ + private List assertions; + + /** + * JSON configuration that was used to build this object. + */ + private String originalJson; + + /** + * Do not attempt to set the retractions when configuring a Field; they get built by the + * edit processing object. + * + * The strings in this list should be N3 for statements that need to be retracted to affect an update. + * Per Field retractions are necessary since we only want to retract for fields that have changed. + * The Model should be checked to make sure that all of the retractions exist so we are changing the + * statements that existed when this edit was configured. + * + * These retractions are just the assertions with the values subistituted in from before the change. + */ + private List retractions; + + private Map queryForExisting; + + /** + * Property for special edit element. + */ + private EditElementVTwo editElement=null;; + + /* *********************** Constructors ************************** */ + + public FieldVTwo(String config, String varName) { + name=varName; + JSONObject jsonObj = null; + try{ + jsonObj = new JSONObject(config); + }catch (JSONException je){ + throw new Error(je); + } + originalJson = config; + setValuesFromJson(jsonObj, varName); + } + + public FieldVTwo(JSONObject obj, String varName) { + setValuesFromJson(obj, varName); + } + + public FieldVTwo() {} + + private static String[] parameterNames = {"editElement","newResource","validators","optionsType","predicateUri","objectClassUri","rangeDatatypeUri","rangeLang","literalOptions","assertions"}; + static{ Arrays.sort(parameterNames); } + + private void setValuesFromJson(JSONObject obj, String fieldName){ + try{ + this.name = fieldName; + setNewResource(obj.getBoolean("newResource")); + validators = EditConfigurationVTwo.JsonArrayToStringList(obj.getJSONArray("validators")); + setOptionsType(obj.getString("optionsType")); + predicateUri = obj.getString("predicateUri"); + objectClassUri = obj.getString("objectClassUri"); + + rangeDatatypeUri = obj.getString("rangeDatatypeUri"); + if( rangeDatatypeUri != null && rangeDatatypeUri.trim().length() == 0) + rangeDatatypeUri = null; + + rangeLang = obj.getString("rangeLang"); + if( rangeLang != null && rangeLang.trim().length() == 0) + rangeLang = null; + + setLiteralOptions(obj.getJSONArray("literalOptions")); + setAssertions(EditConfigurationVTwo.JsonArrayToStringList(obj.getJSONArray("assertions"))); + + setEditElement( obj, fieldName); + + //check for odd parameters + JSONArray names = obj.names(); + int size = names.length(); + for(int i=0 ; i < size ; i++ ){ + String name = (String)names.optString(i); + if( Arrays.binarySearch(parameterNames, name) < 0 ) + log.debug("setValuesFromJson(): the field " + fieldName + " has the unrecognized parameter " + name); + } + + }catch(JSONException ex){ + throw new Error(ex); + } + } + + public void setEditElement(EditElementVTwo editElement){ + this.editElement = editElement; + } + + /** + * A field may specify a class for additional features. + */ + private void setEditElement(JSONObject fieldConfigObj, String fieldName) { + String className = fieldConfigObj.optString("editElement"); + if( className == null || className.isEmpty() ) + return; + setOptionsType(FieldVTwo.OptionsType.UNDEFINED); + Class clz = null; + try { + clz = Class.forName(className); + } catch (ClassNotFoundException e) { + log.error("Java Class " + className + " not found for field " + name); + return; + } catch (SecurityException e) { + log.error("Problem with Java Class " + className + " for field " + name, e); + return; + } catch (IllegalArgumentException e) { + log.error("Problem with Java Class " +className + " for field " + name, e); + return; + } + + Class[] types = new Class[]{ FieldVTwo.class }; + Constructor cons; + try { + cons = clz.getConstructor(types); + } catch (SecurityException e) { + log.error("Problem with Java Class " + className + " for field " + name, e); + return; + } catch (NoSuchMethodException e) { + log.error("Java Class " + className + " must have a constructor that takes a Field.", e); + return; + } + Object[] args = new Object[] { this }; + Object obj; + try { + obj = cons.newInstance(args); + } catch (Exception e) { + log.error("Problem with Java Class " + className + " for field " + name, e); + return; + } + + editElement = (EditElementVTwo)obj; + } + + /* ****************** Getters and Setters ******************************* */ + + public String getName(){ + return name; + } + + public List getRetractions() { + return retractions; + } + + public void setRetractions(List retractions) { + this.retractions = retractions; + } + + public List getAssertions() { + return assertions; + } + + public void setAssertions(List assertions) { + this.assertions = assertions; + } + + public boolean isNewResource() { + return newResource; + } + public void setNewResource(boolean b) { + newResource = b; + } + + public List getValidators() { + return validators; + } + public void setValidators(List v) { + validators = v; + } + + public OptionsType getOptionsType() { + return optionsType; + } + public void setOptionsType(OptionsType ot) { + optionsType = ot; + } + public void setOptionsType(String s) { + setOptionsType( getOptionForString(s)); + } + + public static OptionsType getOptionForString(String s){ + if( s== null || s.isEmpty() ) + return OptionsType.UNDEFINED; + if ("LITERALS".equals(s)) { + return FieldVTwo.OptionsType.LITERALS; + } else if ("HARDCODED_LITERALS".equals(s)) { + return FieldVTwo.OptionsType.HARDCODED_LITERALS; + } else if ("STRINGS_VIA_DATATYPE_PROPERTY".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.STRINGS_VIA_DATATYPE_PROPERTY; + } else if ("INDIVIDUALS_VIA_OBJECT_PROPERTY".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.INDIVIDUALS_VIA_OBJECT_PROPERTY; + } else if ("INDIVIDUALS_VIA_VCLASS".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS; + } else if ("MONIKERS_VIA_VCLASS".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.MONIKERS_VIA_VCLASS; + } else if ("DATETIME".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.DATETIME; + } else if ("CHILD_VCLASSES".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.CHILD_VCLASSES; + } else if ("CHILD_VCLASSES_WITH_PARENT".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.CHILD_VCLASSES_WITH_PARENT; + } else if ("VCLASSGROUP".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.VCLASSGROUP; + } else if ("FILE".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.FILE; + } else if ("DATE".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.DATE; + } else if ("TIME".equalsIgnoreCase(s)) { + return FieldVTwo.OptionsType.TIME; + } else { + return FieldVTwo.OptionsType.UNDEFINED; + } + } + + public String getPredicateUri() { + return predicateUri; + } + public void setPredicateUri(String s) { + predicateUri = s; + } + + public String getObjectClassUri() { + return objectClassUri; + } + public void setObjectClassUri(String s) { + objectClassUri = s; + } + + public String getRangeDatatypeUri() { + return rangeDatatypeUri; + } + public void setRangeDatatypeUri(String r) { + if( rangeLang != null && rangeLang.trim().length() > 0 ) + throw new IllegalArgumentException("A Field object may not have both rangeDatatypeUri and rangeLanguage set"); + + rangeDatatypeUri = r; + } + + public List > getLiteralOptions() { + return literalOptions; + } + public void setLiteralOptions(List> literalOptions) { + this.literalOptions = literalOptions; + } + + /** + * Expects a JSONArray of JSONArrays like: + * [ ["http://example.org/bob", "bob"] , ["http://example.org/kate", "kate"] ] + */ + private void setLiteralOptions(JSONArray array) { + if( array == null ) + literalOptions = Collections.EMPTY_LIST; + + literalOptions = Collections.EMPTY_LIST; + List> out = new ArrayList>( array.length() ); + + for(int i =0; ioption = new ArrayList(2); + option.add(value); + option.add(value); + out.add( option ); + } else { log.warn("could not get option list for " + this.name ); } + }else{ + if( pair.length() == 0 ){ + log.warn("option list too short for " + this.name + ": " + array.opt(i)); + continue; + } + if( pair.length() > 2 ) + log.warn("option list too long for " + this.name + ": " + array.opt(i) + " using first two items"); + + Listoption = new ArrayList(2); + option.add(pair.optString(0)); + if( pair.length() > 1 ) + option.add(pair.optString(1)); + else + option.add(pair.optString(0)); + out.add( option ); + } + } + literalOptions = out; + } + + public String getRangeLang() { + return rangeLang; + } + + public void setRangeLang(String rangeLang) { + if( rangeDatatypeUri != null && rangeDatatypeUri.trim().length() > 0) + throw new IllegalArgumentException("A Field object may not have both rangeDatatypeUri and rangeLanguage set"); + + this.rangeLang = rangeLang; + } + + public FieldVTwo copy(){ + FieldVTwo copy = new FieldVTwo(this.originalJson, name); + return copy; + } + + public EditElementVTwo getEditElement(){ + return editElement; + } + + /* this is mainly for unit testing */ + public void setName(String name){ + this.name = name; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/MultiValueEditSubmission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/MultiValueEditSubmission.java similarity index 77% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/MultiValueEditSubmission.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/MultiValueEditSubmission.java index 16f07c07e..3f66734cf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/MultiValueEditSubmission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/MultiValueEditSubmission.java @@ -1,12 +1,13 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit; +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.ArrayList; import java.util.Map; import javax.servlet.http.HttpSession; @@ -28,18 +29,20 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral; -import edu.cornell.mannlib.vitro.webapp.edit.elements.EditElement; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditElementVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.BasicValidation; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.N3Validator; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditN3Utils; public class MultiValueEditSubmission { String editKey; - - private Map literalsFromForm ; - private Map urisFromForm ; + + //TODO: Need to change below to be able to support multiple values + private Map> literalsFromForm ; + private Map> urisFromForm ; private Map validationErrors; private BasicValidation basicValidation; @@ -52,7 +55,7 @@ public class MultiValueEditSubmission { literalCreationModel = ModelFactory.createDefaultModel(); } - public MultiValueEditSubmission(Map queryParameters, EditConfiguration editConfig){ + public MultiValueEditSubmission(Map queryParameters, EditConfigurationVTwo editConfig){ if( editConfig == null ) throw new Error("EditSubmission needs an EditConfiguration"); this.editKey = editConfig.getEditKey(); @@ -61,15 +64,25 @@ public class MultiValueEditSubmission { validationErrors = new HashMap(); - this.urisFromForm = new HashMap(); + this.urisFromForm = new HashMap>(); for( String var: editConfig.getUrisOnform() ){ String[] valuesArray = queryParameters.get( var ); - String uri = null; + //String uri = null; List values = (valuesArray != null) ? Arrays.asList(valuesArray) : null; + //Iterate through the values and check to see if they should be added or removed from form + urisFromForm.put(var, values); + for(String uri : values) { + if( uri != null && uri.length() == 0 && editConfig.getNewResources().containsKey(var) ){ + log.debug("A new resource URI will be made for var " + var + " since it was blank on the form."); + urisFromForm.remove(var); + } + } + /* if( values != null && values.size() > 0){ if( values.size() == 1 ) { uri = values.get(0); } else if( values.size() > 1 ){ + //TODO: Change this and above so array/list sent as uri and not single value uri = values.get(0); log.error("Cannot yet handle multiple URIs for a single field, using first URI on list"); } @@ -81,12 +94,12 @@ public class MultiValueEditSubmission { if( uri != null && uri.length() == 0 && editConfig.getNewResources().containsKey(var) ){ log.debug("A new resource URI will be made for var " + var + " since it was blank on the form."); urisFromForm.remove(var); - } + }*/ } - this.literalsFromForm =new HashMap(); + this.literalsFromForm =new HashMap>(); for(String var: editConfig.getLiteralsOnForm() ){ - Field field = editConfig.getField(var); + FieldVTwo field = editConfig.getField(var); if( field == null ) { log.error("could not find field " + var + " in EditConfiguration" ); continue; @@ -96,6 +109,20 @@ public class MultiValueEditSubmission { String[] valuesArray = queryParameters.get(var); List valueList = (valuesArray != null) ? Arrays.asList(valuesArray) : null; if( valueList != null && valueList.size() > 0 ) { + List literalsArray = new ArrayList(); + //now support multiple values + for(String value:valueList) { + value = EditN3Utils.stripInvalidXMLChars(value); + //Add to array of literals corresponding to this variable + if (!StringUtils.isEmpty(value)) { + literalsArray.add(createLiteral( + value, + field.getRangeDatatypeUri(), + field.getRangeLang())); + } + } + literalsFromForm.put(var, literalsArray); + /* String value = valueList.get(0); // remove any characters that are not valid in XML 1.0 @@ -113,6 +140,7 @@ public class MultiValueEditSubmission { if(valueList != null && valueList.size() > 1 ) log.debug("For field " + var +", cannot yet handle multiple " + "Literals for a single field, using first Literal on list"); + */ }else{ log.debug("could not find value for parameter " + var ); @@ -130,7 +158,8 @@ public class MultiValueEditSubmission { } processEditElementFields(editConfig,queryParameters); - + //Not checking validation for now + /* Map errors = basicValidation.validateUris( urisFromForm ); if(editConfig.getValidators() != null ){ @@ -142,17 +171,17 @@ public class MultiValueEditSubmission { // validationErrors.putAll(errors); } } - } + } */ if( log.isDebugEnabled() ) log.debug( this.toString() ); } - protected void processEditElementFields(EditConfiguration editConfig, Map queryParameters ){ + protected void processEditElementFields(EditConfigurationVTwo editConfig, Map queryParameters ){ for( String fieldName : editConfig.getFields().keySet()){ - Field field = editConfig.getFields().get(fieldName); + FieldVTwo field = editConfig.getFields().get(fieldName); if( field != null && field.getEditElement() != null ){ - EditElement element = field.getEditElement(); + EditElementVTwo element = field.getEditElement(); log.debug("Checking EditElement for field " + fieldName + " type: " + element.getClass().getName()); //check for validation error messages @@ -162,10 +191,10 @@ public class MultiValueEditSubmission { if( errMsgs == null || errMsgs.isEmpty()){ //only check for uris and literals when element has no validation errors - Map urisFromElement = element.getURIs(fieldName, editConfig, queryParameters); + Map> urisFromElement = element.getURIs(fieldName, editConfig, queryParameters); if( urisFromElement != null ) urisFromForm.putAll(urisFromElement); - Map literalsFromElement = element.getLiterals(fieldName, editConfig, queryParameters); + Map> literalsFromElement = element.getLiterals(fieldName, editConfig, queryParameters); if( literalsFromElement != null ) literalsFromForm.putAll(literalsFromElement); }else{ @@ -203,11 +232,11 @@ public class MultiValueEditSubmission { return validationErrors; } - public Map getLiteralsFromForm() { + public Map> getLiteralsFromForm() { return literalsFromForm; } - public Map getUrisFromForm() { + public Map> getUrisFromForm() { return urisFromForm; } /** @@ -266,11 +295,11 @@ public class MultiValueEditSubmission { return new EditLiteral(hourStr + ":" + minuteStr + ":" + secondStr, TIME_URI, null); } - public void setLiteralsFromForm(Map literalsFromForm) { + public void setLiteralsFromForm(Map> literalsFromForm) { this.literalsFromForm = literalsFromForm; } - public void setUrisFromForm(Map urisFromForm) { + public void setUrisFromForm(Map> urisFromForm) { this.urisFromForm = urisFromForm; } @@ -283,5 +312,5 @@ public class MultiValueEditSubmission { return obj.toString(); } - private Log log = LogFactory.getLog(EditSubmission.class); + private Log log = LogFactory.getLog(MultiValueEditSubmission.class); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/ProcessRdfForm.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java similarity index 87% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/ProcessRdfForm.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java index e04c5fdc8..8a1c31f2b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/ProcessRdfForm.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java @@ -1,6 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit; +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; import java.io.StringReader; import java.util.ArrayList; @@ -19,7 +19,7 @@ import com.hp.hpl.jena.shared.Lock; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; 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.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.ModelChangePreprocessor; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities; @@ -31,7 +31,7 @@ public class ProcessRdfForm { * Execute any modelChangePreprocessors in the editConfiguration; * */ - public static void preprocessModels(AdditionsAndRetractions changes, EditConfiguration editConfiguration, VitroRequest request){ + public static void preprocessModels(AdditionsAndRetractions changes, EditConfigurationVTwo editConfiguration, VitroRequest request){ List modelChangePreprocessors = editConfiguration.getModelChangePreprocessors(); if ( modelChangePreprocessors != null ) { @@ -85,10 +85,10 @@ public class ProcessRdfForm { @SuppressWarnings("static-access") - public static AdditionsAndRetractions createNewResource(EditConfiguration editConfiguration , EditSubmission submission){ + public static AdditionsAndRetractions createNewResource(EditConfigurationVTwo editConfiguration , MultiValueEditSubmission submission){ List errorMessages = new ArrayList(); - EditN3Generator n3Subber = editConfiguration.getN3Generator(); + EditN3GeneratorVTwo n3Subber = editConfiguration.getN3Generator(); if(log.isDebugEnabled()){ log.debug("creating a new relation " + editConfiguration.getPredicateUri()); @@ -100,28 +100,28 @@ public class ProcessRdfForm { /* ********** URIs and Literals on Form/Parameters *********** */ //sub in resource uris off form - n3Required = n3Subber.subInUris(submission.getUrisFromForm(), n3Required); - n3Optional = n3Subber.subInUris(submission.getUrisFromForm(), n3Optional); + n3Required = n3Subber.subInMultiUris(submission.getUrisFromForm(), n3Required); + n3Optional = n3Subber.subInMultiUris(submission.getUrisFromForm(), n3Optional); if(log.isDebugEnabled()) { logRequiredOpt("substituted in URIs off from ",n3Required,n3Optional); } //sub in literals from form - n3Required = n3Subber.subInLiterals(submission.getLiteralsFromForm(), n3Required); - n3Optional = n3Subber.subInLiterals(submission.getLiteralsFromForm(), n3Optional); + n3Required = n3Subber.subInMultiLiterals(submission.getLiteralsFromForm(), n3Required); + n3Optional = n3Subber.subInMultiLiterals(submission.getLiteralsFromForm(), n3Optional); if(log.isDebugEnabled()) { logRequiredOpt("substituted in literals off from ",n3Required,n3Optional); } /* ****************** URIs and Literals in Scope ************** */ - n3Required = n3Subber.subInUris( editConfiguration.getUrisInScope(), n3Required); - n3Optional = n3Subber.subInUris( editConfiguration.getUrisInScope(), n3Optional); + n3Required = n3Subber.subInMultiUris( editConfiguration.getUrisInScope(), n3Required); + n3Optional = n3Subber.subInMultiUris( editConfiguration.getUrisInScope(), n3Optional); if(log.isDebugEnabled()) { logRequiredOpt("substituted in URIs from scope ",n3Required,n3Optional); } - n3Required = n3Subber.subInLiterals( editConfiguration.getLiteralsInScope(), n3Required); - n3Optional = n3Subber.subInLiterals( editConfiguration.getLiteralsInScope(), n3Optional); + n3Required = n3Subber.subInMultiLiterals( editConfiguration.getLiteralsInScope(), n3Required); + n3Optional = n3Subber.subInMultiLiterals( editConfiguration.getLiteralsInScope(), n3Optional); if(log.isDebugEnabled()) { logRequiredOpt("substituted in Literals from scope ",n3Required,n3Optional); } @@ -169,11 +169,11 @@ public class ProcessRdfForm { } @SuppressWarnings("static-access") - public static AdditionsAndRetractions editExistingResource(EditConfiguration editConfiguration, EditSubmission submission) { + public static AdditionsAndRetractions editExistingResource(EditConfigurationVTwo editConfiguration, MultiValueEditSubmission submission) { Map> fieldAssertions = Utilities.fieldsToAssertionMap(editConfiguration.getFields()); Map> fieldRetractions = Utilities.fieldsToRetractionMap(editConfiguration.getFields()); - EditN3Generator n3Subber = editConfiguration.getN3Generator(); + EditN3GeneratorVTwo n3Subber = editConfiguration.getN3Generator(); /* ********** URIs and Literals on Form/Parameters *********** */ fieldAssertions = n3Subber.substituteIntoValues(submission.getUrisFromForm(), submission.getLiteralsFromForm(), fieldAssertions); @@ -246,17 +246,17 @@ public class ProcessRdfForm { * This is intended to substitute vars from the EditConfiguration and * EditSubmission into the URL to return to. */ - public static String substitueForURL(EditConfiguration configuration, EditSubmission submission){ + public static String substitueForURL(EditConfigurationVTwo configuration, MultiValueEditSubmission submission){ List entToReturnTo = new ArrayList(1); entToReturnTo.add(configuration.getEntityToReturnTo()); - EditN3Generator n3Subber = configuration.getN3Generator(); + EditN3GeneratorVTwo n3Subber = configuration.getN3Generator(); // Substitute in URIs from the submission - entToReturnTo = n3Subber.subInUris(submission.getUrisFromForm(), entToReturnTo); + entToReturnTo = n3Subber.subInMultiUris(submission.getUrisFromForm(), entToReturnTo); // Substitute in URIs from the scope of the EditConfiguration - entToReturnTo = n3Subber.subInUris(configuration.getUrisInScope(), entToReturnTo); + entToReturnTo = n3Subber.subInMultiUris(configuration.getUrisInScope(), entToReturnTo); //The problem is that subInURI will add < and > around URIs for the N3 syntax. //for the URL to return to, replace < and > from URI additions. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/SparqlEvaluateVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/SparqlEvaluateVTwo.java new file mode 100644 index 000000000..35f64a834 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/SparqlEvaluateVTwo.java @@ -0,0 +1,241 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; +import com.hp.hpl.jena.query.*; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Resource; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * User: bdc34 + * Date: Jan 22, 2008 + * Time: 5:55:57 PM + */ +public class SparqlEvaluateVTwo { + private static Log log = LogFactory.getLog( SparqlEvaluateVTwo.class ); + + Model model; + public SparqlEvaluateVTwo(Model model){ + if( model == null ) throw new Error("SparqlEvaluate must be passed a Model"); + this.model = model; + } + + public void evaluateForAdditionalUris( EditConfigurationVTwo editConfig ){ + Map> varsToUris = sparqlEvaluateForUris(editConfig, editConfig.getSparqlForAdditionalUrisInScope()); + editConfig.getUrisInScope().putAll(varsToUris); + } + + public void evalulateForAdditionalLiterals( EditConfigurationVTwo editConfig ){ + Map> varsToLiterals = sparqlEvaluateForLiterals(editConfig, editConfig.getSparqlForAdditionalLiteralsInScope()); + editConfig.getLiteralsInScope().putAll(varsToLiterals); + } + + public void evaluateForExistingUris( EditConfigurationVTwo editConfig){ + Map> varsToUris = sparqlEvaluateForUris(editConfig, editConfig.getSparqlForExistingUris()); + editConfig.getUrisInScope().putAll(varsToUris); + } + + public void evaluateForExistingLiterals( EditConfigurationVTwo editConfig){ + Map> varsToLiterals = sparqlEvaluateForLiterals(editConfig, editConfig.getSparqlForExistingLiterals()); + editConfig.getLiteralsInScope().putAll(varsToLiterals); + } + +// public Map sparqlEvaluateForExistingToUris(Map varToSpqrql){ +// Map varToUris = new HashMap(); +// for(String var : varToSpqrql.keySet()){ +// varToUris.put(var, queryToUri( varToSpqrql.get(var) )); +// } +// return varToUris; +// } +// +// public Map sparqlEvaluateForAdditionalLiterals(Map varToSpqrql){ +// Map varToLiterals = new HashMap(); +// for(String var : varToSpqrql.keySet()){ +// varToLiterals.put(var, queryToLiteral( varToSpqrql.get(var) )); +// } +// return varToLiterals; +// } + +// private Map sparqlEvaluateForExistingToUris( EditConfiguration editConfig ) { +// Map varToSpqrql = editConfig.getSparqlForExistingUris(); +// Map uriScope = editConfig.getUrisInScope(); +// Map literalScope = editConfig.getLiteralsInScope(); +// +// Map varToUris = new HashMap(); +// +// for(String var : varToSpqrql.keySet()){ +// String query = varToSpqrql.get(var); +// List queryStrings = new ArrayList (); +// queryStrings.add(query); +// queryStrings= editConfig.getN3Generator().subInUris(uriScope, queryStrings); +// queryStrings = editConfig.getN3Generator().subInLiterals(literalScope,queryStrings); +// varToUris.put(var, queryToUri( queryStrings.get(0) )); //might result in (key -> null) +// } +// +// return varToUris; +// } + + public Map> sparqlEvaluateForLiterals( EditConfigurationVTwo editConfig, Map varToSparql) { + Map> uriScope = editConfig.getUrisInScope(); + Map> literalScope = editConfig.getLiteralsInScope(); + + Map> varToLiterals = new HashMap>(); + for(String var : varToSparql.keySet()){ + String query = varToSparql.get(var); + + /* skip if var set to use a system generated value */ + if( query == null || EditConfigurationVTwo.USE_SYSTEM_VALUE.equals( query )) + continue; + + List queryStrings = new ArrayList (); + queryStrings.add( query ); + queryStrings= editConfig.getN3Generator().subInMultiUris(uriScope, queryStrings); + queryStrings = editConfig.getN3Generator().subInMultiLiterals(literalScope,queryStrings); + varToLiterals.put(var, queryToLiteral( queryStrings.get(0) )); //might result in (key -> null) + } + + return varToLiterals; + } + + public Map> sparqlEvaluateForUris( EditConfigurationVTwo editConfig, MapvarToSparql) { + Map> uriScope = editConfig.getUrisInScope(); + Map> literalScope = editConfig.getLiteralsInScope(); + + Map> varToUris = new HashMap>(); + + for(String var : varToSparql.keySet()){ + String query = varToSparql.get(var); + /* skip if var set to use a system generated value */ + if( query == null || EditConfigurationVTwo.USE_SYSTEM_VALUE.equals( query )) + continue; + List queryStrings = new ArrayList (); + queryStrings.add(query); + queryStrings= editConfig.getN3Generator().subInMultiUris(uriScope, queryStrings); + queryStrings = editConfig.getN3Generator().subInMultiLiterals(literalScope,queryStrings); + List uriFromQuery = queryToUri( queryStrings.get(0) ); + if( uriFromQuery != null ) + { + //Added parens and output + varToUris.put(var, uriFromQuery); + } + else + log.debug("sparqlEvaluateForUris(): for var " + var + + " the following query evaluated to null:\n"+queryStrings.get(0)+"\n(end of query)\n"); + } + + return varToUris; + } + +// public Map sparqlEvaluateForAdditionalLiterals( EditConfiguration editConfig) { +// Map varToSpqrql = editConfig.getSparqlForAdditionalLiteralsInScope(); +// Map uriScope = editConfig.getUrisInScope(); +// Map literalScope = editConfig.getLiteralsInScope(); +// +// Map varToLiterals = new HashMap(); +// for(String var : varToSpqrql.keySet()){ +// String query = varToSpqrql.get(var); +// List queryStrings = new ArrayList (); +// queryStrings.add( query ); +// queryStrings= editConfig.getN3Generator().subInUris(uriScope, queryStrings); +// queryStrings = editConfig.getN3Generator().subInLiterals(literalScope,queryStrings); +// Literal literalFromQuery = queryToLiteral( queryStrings.get(0) ); +// if( literalFromQuery != null ) +// varToLiterals.put(var, literalFromQuery ); +// else +// log.debug("sparqlEvaluateForAdditionalLiterals(): for var " + var +// + "query evaluated to null. query: '" + queryStrings.get(0) +"'"); +// } +// +// return varToLiterals; +// } + + //now can return multiple uris + public List queryToUri(String querystr){ + log.debug("Query string in queryToUri():" + querystr); + String value = null; + List values = new ArrayList(); + QueryExecution qe = null; + try{ + Query query = QueryFactory.create(querystr); + qe = QueryExecutionFactory.create(query, model); + if( query.isSelectType() ){ + ResultSet results = null; + results = qe.execSelect(); + if( results.hasNext()){ + List vars = results.getResultVars(); + if( vars == null ) + throw new Error("sparql had no result variables"); + for(String var: vars) { + QuerySolution qs = results.nextSolution(); + Resource resource = qs.getResource(var); + value = resource.getURI(); + values.add(value); + } + + + + }else{ + return null; + } + } else { + throw new Error("only SELECT type SPARQL queries are supported"); + } + }catch(Exception ex){ + throw new Error("could not parse SPARQL in queryToUri: \n" + querystr + '\n' + ex.getMessage()); + }finally{ + if( qe != null) + qe.close(); + } + if( log.isDebugEnabled() ) log.debug("queryToUri() query: '"+ querystr +"'\nvalue: '" + values.toString() +"'"); + return values; + } + + + public List queryToLiteral(String querystr){ + Literal value = null; + List values = new ArrayList(); + QueryExecution qe = null; + try{ + Query query = QueryFactory.create(querystr); + qe = QueryExecutionFactory.create(query, model); + if( query.isSelectType() ){ + ResultSet results = null; + results = qe.execSelect(); + if( results.hasNext()){ + List vars = results.getResultVars(); + if( vars == null ) + throw new Error("sparql had no result variables"); + for(String var: vars){ + QuerySolution qs = results.nextSolution(); + value = qs.getLiteral(var); + values.add(value); + } + }else{ + return null; + } + } else { + throw new Error("only SELECT type SPARQL queries are supported"); + } + }catch(Exception ex){ + throw new Error("could not parse SPARQL in queryToLiteral: \n" + querystr + '\n' + ex.getMessage()); + }finally{ + if( qe != null) + qe.close(); + } + + if( log.isDebugEnabled() ) log.debug("queryToLiteral() query: '"+ querystr +"'\nvalue: '" + values.toString() +"'"); + return values; + } + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java index 81019c099..bbb2453a8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java @@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils; public class DefaultDataPropertyFormGenerator implements EditConfigurationGenerator { @@ -30,7 +30,7 @@ public class DefaultDataPropertyFormGenerator implements EditConfigurationGenera } @Override - public EditConfiguration getEditConfiguration(VitroRequest vreq, + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) { String subjectUri = vreq.getParameter("subjectUri"); @@ -45,11 +45,11 @@ public class DefaultDataPropertyFormGenerator implements EditConfigurationGenera int dataHash=0; DataProperty prop = (DataProperty)vreq.getAttribute("predicate"); - if( prop == null ) return doHelp(vreq, "In DefaultDataPropertyFormGenerator, could not find predicate " + predicateUri); + //if( prop == null ) return doHelp(vreq, "In DefaultDataPropertyFormGenerator, could not find predicate " + predicateUri); vreq.setAttribute("propertyName",prop.getPublicName()); Individual subject = (Individual)vreq.getAttribute("subject"); - if( subject == null ) return doHelp(vreq,"In DefaultDataPropertyFormGenerator, could not find subject " + subjectUri); + //if( subject == null ) return doHelp(vreq,"In DefaultDataPropertyFormGenerator, could not find subject " + subjectUri); vreq.setAttribute("subjectName",subject.getName()); String rangeDatatypeUri = vreq.getWebappDaoFactory().getDataPropertyDao().getRequiredDatatypeURI(subject, prop); @@ -99,7 +99,7 @@ public class DefaultDataPropertyFormGenerator implements EditConfigurationGenera String formUrl = (String)vreq.getAttribute("formUrl"); String editKey = (String)vreq.getAttribute("editKey"); - EditConfiguration editConfiguration = new EditConfiguration(); + EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo(); List n3ForEdit = new ArrayList(); n3ForEdit.add("?subject"); @@ -127,7 +127,7 @@ public class DefaultDataPropertyFormGenerator implements EditConfigurationGenera return null; } - private EditConfiguration doHelp(VitroRequest vreq, String string) { + private EditConfigurationVTwo doHelp(VitroRequest vreq, String string) { // TODO Auto-generated method stub return null; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java index b172f7eb9..9d78d2523 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java @@ -12,7 +12,7 @@ import javax.servlet.http.HttpSession; 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.Literal; import com.hp.hpl.jena.rdf.model.Model; @@ -20,12 +20,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.SelectListGenerator; -import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; /** * Generates the edit configuration for a default property form. @@ -36,7 +33,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene private Log log = LogFactory.getLog(DefaultObjectPropertyFormGenerator.class); @Override - public EditConfiguration getEditConfiguration(VitroRequest vreq, + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) { // TODO Generate a edit conf for the default object property form and return it. @@ -59,6 +56,8 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene String predicateUriJson = (String)vreq.getAttribute("predicateUriJson"); String objectUriJson = (String)vreq.getAttribute("objectUriJson"); + + //building the editjson object //TODO: There has to be a better way of doing this. // Tried building a java object with Google Gson and then @@ -113,8 +112,10 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene // vreq.setAttribute("editjson", editjson); // log.debug(vreq.getAttribute("editjson")); + //Alternative: Set - EditConfiguration editConfiguration = new EditConfiguration(); + + EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo(); editConfiguration.setFormUrl(formUrl); editConfiguration.setEditKey(editKey); @@ -129,6 +130,11 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene editConfiguration.setVarNameForObject("objectVar"); editConfiguration.setObject(objectUriJson); + //this needs to be set for the editing to be triggered properly, otherwise the 'prepare' method + //pretends this is a data property editing statement and throws an error + if(objectUriJson != null) { + editConfiguration.setObjectResource(true); + } List n3ForEdit = new ArrayList(); n3ForEdit.add("?subject"); @@ -144,9 +150,9 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene editConfiguration.setNewResources(new HashMap()); - editConfiguration.setUrisInScope(new HashMap()); + editConfiguration.setUrisInScope(new HashMap>()); - editConfiguration.setLiteralsInScope(new HashMap()); + editConfiguration.setLiteralsInScope(new HashMap>()); List urisOnForm = new ArrayList(); urisOnForm.add("objectVar"); @@ -198,7 +204,8 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene fields.put("objectVar", field); - editConfiguration.setFields(fields); + //TODO: Review why/how this method signature has changed + //editConfiguration.setFields(fields); editConfiguration.putConfigInSession(editConfiguration, session); @@ -208,6 +215,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene String formTitle = " "; String submitLabel = " "; + //Here, retrieve model from Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); //this block is for an edit of an existing object property statement diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/EditConfigurationGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/EditConfigurationGenerator.java index 4289155ef..2edca634b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/EditConfigurationGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/EditConfigurationGenerator.java @@ -5,8 +5,8 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators import javax.servlet.http.HttpSession; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; public interface EditConfigurationGenerator { - public EditConfiguration getEditConfiguration( VitroRequest vreq, HttpSession session ); + public EditConfigurationVTwo getEditConfiguration( VitroRequest vreq, HttpSession session ); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/InstitutionalInternalClassForm.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/InstitutionalInternalClassForm.java index b4c2df84c..b11be3129 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/InstitutionalInternalClassForm.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/InstitutionalInternalClassForm.java @@ -5,7 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators import javax.servlet.http.HttpSession; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; /** * Generate the EditConfiguration for the Institutional Internal Class Form. @@ -16,8 +16,8 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigu public class InstitutionalInternalClassForm implements EditConfigurationGenerator { @Override - public EditConfiguration getEditConfiguration(VitroRequest vreq, HttpSession session) { - EditConfiguration editConfig = new EditConfiguration(); + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) { + EditConfigurationVTwo editConfig = new EditConfigurationVTwo(); editConfig.setTemplate("institutionalInternalClassForm.ftl"); return editConfig; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/MenuEditingFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/MenuEditingFormGenerator.java new file mode 100644 index 000000000..7e3a2836c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/MenuEditingFormGenerator.java @@ -0,0 +1,302 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +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.Literal; +import com.hp.hpl.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.SelectListGenerator; +import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; + +/** + * Generates the edit configuration for a default property form. + * + */ +public class MenuEditingFormGenerator implements EditConfigurationGenerator { + + private Log log = LogFactory.getLog(DefaultObjectPropertyFormGenerator.class); + + @Override + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, + HttpSession session) { + + //The actual N3 created here needs to include multiple levels from hasElement all the way down to the + //actual pagej + + Individual subject = (Individual)vreq.getAttribute("subject"); + ObjectProperty prop = (ObjectProperty)vreq.getAttribute("predicate"); + + WebappDaoFactory wdf = vreq.getWebappDaoFactory(); + + String queryForInverse = "PREFIX owl: " + + " SELECT ?inverse_property " + + " WHERE { ?inverse_property owl:inverseOf ?predicate } "; + + + // retrieving attributes from the request object to build editjson string + String formUrl = (String)vreq.getAttribute("formUrl"); + String editKey = (String)vreq.getAttribute("editKey"); + + String subjectUriJson = (String)vreq.getAttribute("subjectUriJson"); + String predicateUriJson = (String)vreq.getAttribute("predicateUriJson"); + String objectUriJson = (String)vreq.getAttribute("objectUriJson"); + String objectUri = (String)vreq.getAttribute("objectUriJson"); + //Get actual object uri as not concerned with json escaped version + System.out.println("Object Uri is " + objectUri + " and json version is " + objectUriJson); + + + //building the editjson object + //TODO: There has to be a better way of doing this. + // Tried building a java object with Google Gson and then + // deserialize it to json, but the values in the string + // are sometimes lists, maps, literals. +/* String editjson = "{" + + " formUrl : " + formUrl + " ," + + " editKey : " + editKey + " ," + + " urlPatternToReturnTo : " + "/individual ," + + + " subject : [ subject , " + subjectUriJson + " ] , " + + " predicate : [ predicate , " + predicateUriJson + " ] ," + + " object : [ objectVar , " + objectUriJson + ", URI ] , " + + + " n3required : [ " + n3ForEdit + "] ," + + " n3optional : [ " + n3Inverse + "] ," + + " newResources : { } ," + + + " urisInScope : { } ," + + " literalsInScope: { } ," + + + " urisOnForm : [objectVar] ," + + " literalsOnForm : [ ] ," + + " filesOnForm : [ ] ," + + + "sparqlForLiterals : { } ," + + "sparqlForUris : { inverseProp : " + queryForInverse + " } ," + + + "sparqlForExistingLiterals : { } ," + + "sparqlForExistingUris : { } ," + + + "fields : { objectVar : { " + + " newResource : false ," + + " queryForExisting : { }, " + + " validators : [ nonempty ] ," + + " optionsType : INDIVIDUALS_VIA_OBJECT_PROPERTY , " + + " subjectUri : " + subjectUriJson + " ," + + " subjectClassUri : ," + + " predicateUri : " + predicateUriJson + " ," + + " objectClassUri : ," + + " rangeDatatypeUri : ," + + " rangeLang : , " + + " literalOptions : [ ] , " + + " assertions : [ " + n3ForEdit + " ," + n3Inverse + " ] " + + " } " + + " } " + + " } "; + +*/ + + //set the editjson attribute in the request + // vreq.setAttribute("editjson", editjson); + // log.debug(vreq.getAttribute("editjson")); + + //Alternative: Set + + + EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo(); + //Setting a custom test template for now + //TODO: Where to get this custom template from? Should it be a predicate in display model somewhere? + editConfiguration.setTemplate("testMenuEdit.ftl"); + + + editConfiguration.setFormUrl(formUrl); + editConfiguration.setEditKey(editKey); + + editConfiguration.setUrlPatternToReturnTo("/individual"); + + editConfiguration.setVarNameForSubject("subject"); + editConfiguration.setSubjectUri(subjectUriJson); + + editConfiguration.setVarNameForPredicate("predicate"); + editConfiguration.setPredicateUri(predicateUriJson); + + editConfiguration.setVarNameForObject("objectVar"); + editConfiguration.setObject(objectUriJson); + //Above, try regular Object uri if json does not work + //this needs to be set for the editing to be triggered properly, otherwise the 'prepare' method + //pretends this is a data property editing statement and throws an error + //"object" : [ "objectVar" , "${objectUriJson}" , "URI"], + if(objectUriJson != null) { + editConfiguration.setObjectResource(true); + } else { + //ObjectUriJson is null, so should include data prop info here + } + + + List n3ForEdit = new ArrayList(); + n3ForEdit.add("?subject"); + n3ForEdit.add("?predicate"); + n3ForEdit.add("?objectVar"); + editConfiguration.setN3Required(n3ForEdit); + + List n3Inverse = new ArrayList(); + n3Inverse.add("?objectVar"); + n3Inverse.add("?inverseProp"); + n3Inverse.add("?subject"); + editConfiguration.setN3Optional(n3Inverse); + + editConfiguration.setNewResources(new HashMap()); + + editConfiguration.setUrisInScope(new HashMap>()); + + editConfiguration.setLiteralsInScope(new HashMap>()); + + List urisOnForm = new ArrayList(); + urisOnForm.add("objectVar"); + editConfiguration.setN3Optional(urisOnForm); + + editConfiguration.setLiteralsOnForm(new ArrayList()); + + editConfiguration.setFilesOnForm(new ArrayList()); + + editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap()); + + Map urisInScope = new HashMap(); + urisInScope.put("inverseProp", queryForInverse); + editConfiguration.setSparqlForAdditionalUrisInScope(urisInScope); + + editConfiguration.setSparqlForExistingLiterals(new HashMap()); + editConfiguration.setSparqlForExistingUris(new HashMap()); + + Map fields = new HashMap(); + + Field field = new Field(); + field.setName("objectVar"); + field.setNewResource(false); + //queryForExisting is not being used anywhere in Field + + List validators = new ArrayList(); + validators.add("nonempty"); + field.setValidators(validators); + + //subjectUri and subjectClassUri are not being used in Field + + field.setOptionsType("INDIVIDUALS_VIA_OBJECT_PROPERTY"); + field.setPredicateUri(predicateUriJson); + + field.setObjectClassUri(null); + field.setRangeDatatypeUri(null); + + field.setRangeLang(null); + field.setLiteralOptions(new ArrayList>()); + + List assertions = new ArrayList(); + assertions.add("?subject"); + assertions.add("?predicate"); + assertions.add("?objectVar"); + assertions.add("?objectVar"); + assertions.add("?inverseProp"); + assertions.add("?subject"); + field.setAssertions(assertions); + + fields.put("objectVar", field); + + //TODO: Check why/how this method signature has changed + //editConfiguration.setFields(fields); + + editConfiguration.putConfigInSession(editConfiguration, session); + + editConfiguration.setTemplate("defaultPropertyForm.ftl"); + + + String formTitle = " "; + String submitLabel = " "; + + //Here, retrieve model from + //Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); + //Use special model instead + Model model = (Model) vreq.getWriteModel(); + + //this block is for an edit of an existing object property statement + if(vreq.getAttribute("object") != null) { + editConfiguration.prepareForObjPropUpdate(model); + formTitle = "Change entry for: " + prop.getDomainPublic() + " "; + submitLabel = "save change"; + } else { + editConfiguration.prepareForNonUpdate( model ); + if ( prop.getOfferCreateNewOption() ) { + //Try to get the name of the class to select from + VClass classOfObjectFillers = null; + + if( prop.getRangeVClassURI() == null ) { + // If property has no explicit range, try to get classes + List classes = wdf.getVClassDao().getVClassesForProperty(subject.getVClassURI(), prop.getURI()); + if( classes == null || classes.size() == 0 || classes.get(0) == null ){ + // If property has no explicit range, we will use e.g. owl:Thing. + // Typically an allValuesFrom restriction will come into play later. + classOfObjectFillers = wdf.getVClassDao().getTopConcept(); + } else { + if( classes.size() > 1 ) + log.debug("Found multiple classes when attempting to get range vclass."); + classOfObjectFillers = classes.get(0); + } + }else{ + classOfObjectFillers = wdf.getVClassDao().getVClassByURI(prop.getRangeVClassURI()); + if( classOfObjectFillers == null ) + classOfObjectFillers = wdf.getVClassDao().getTopConcept(); + } + + log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]"); + formTitle = "Select an existing "+classOfObjectFillers.getName()+" for "+subject.getName(); + submitLabel = "select existing"; + } else { + formTitle = "Add an entry to: "+prop.getDomainPublic()+""; + submitLabel = "save entry"; + } + } + + vreq.setAttribute("formTitle", formTitle); + +// if( prop.getSelectFromExisting() ){ +// // set ProhibitedFromSearch object so picklist doesn't show +// // individuals from classes that should be hidden from list views +// OntModel displayOntModel = +// (OntModel) session.getServletContext() +// .getAttribute("displayOntModel"); +// if (displayOntModel != null) { +// ProhibitedFromSearch pfs = new ProhibitedFromSearch( +// DisplayVocabulary.PRIMARY_LUCENE_INDEX_URI, displayOntModel); +// if( editConfiguration != null ) +// editConfiguration.setProhibitedFromSearch(pfs); +// } +// Map rangeOptions = SelectListGenerator.getOptions(editConfiguration, "objectVar" , wdf); +// if( rangeOptions != null && rangeOptions.size() > 0 ) { +// vreq.setAttribute("rangeOptionsExist", true); +// vreq.setAttribute("rangeOptions.objectVar", rangeOptions); +// } else { +// vreq.setAttribute("rangeOptionsExist",false); +// } +// } + + return editConfiguration; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditDataPropStmtRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditDataPropStmtRequestDispatchController.java deleted file mode 100644 index 7a55fbe60..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditDataPropStmtRequestDispatchController.java +++ /dev/null @@ -1,218 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpSession; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.rdf.model.Model; - -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -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.responsevalues.ResponseValues; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.EditConfigurationGenerator; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash; -import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils; - -public class EditDataPropStmtRequestDispatchController extends FreemarkerHttpServlet { - - public static Log log = LogFactory.getLog(EditDataPropStmtRequestDispatchController.class); - - final String DEFAULT_DATA_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.DefaultDataPropertyFormGenerator"; - final String DEFAULT_ERROR_FORM = "error.jsp"; - - @Override - protected ResponseValues processRequest(VitroRequest vreq) { - - HttpSession session = vreq.getSession(); - if( EditConfiguration.getEditKey( vreq ) == null ){ - vreq.setAttribute("editKey",EditConfiguration.newEditKey(session)); - }else{ - vreq.setAttribute("editKey", EditConfiguration.getEditKey( vreq )); - } - - //set title to Edit to maintain functionality from 1.1.1 and avoid updates to Selenium tests - vreq.setAttribute("title","Edit"); - - String subjectUri = vreq.getParameter("subjectUri"); - String predicateUri = vreq.getParameter("predicateUri"); - String formParam = vreq.getParameter("editForm"); - String command = vreq.getParameter("cmd"); - - - if( subjectUri == null || subjectUri.trim().length() == 0 ) { - log.error("required subjectUri parameter missing"); - return doHelp(vreq, "subjectUri was empty, it is required by EditDataPropStmtRequestDispatchController"); - } - if( predicateUri == null || predicateUri.trim().length() == 0) { - log.error("required subjectUri parameter missing"); - return doHelp(vreq, "predicateUri was empty, it is required by EditDataPropStmtRequestDispatchController"); - } - - // Since we have the URIs let's put the individual, data property, and optional data property statement in the request - vreq.setAttribute("subjectUri", subjectUri); - vreq.setAttribute("subjectUriJson", MiscWebUtils.escape(subjectUri)); - vreq.setAttribute("predicateUri", predicateUri); - vreq.setAttribute("predicateUriJson", MiscWebUtils.escape(predicateUri)); - - WebappDaoFactory wdf = vreq.getWebappDaoFactory(); - - Individual subject = wdf.getIndividualDao().getIndividualByURI(subjectUri); - if( subject == null ) { - log.error("Could not find subject Individual '"+subjectUri+"' in model"); - return doHelp(vreq, "EditDataPropStmtRequestDispatchController: Could not find subject Individual in model: '" + subjectUri + "'"); - } - vreq.setAttribute("subject", subject); - - DataProperty dataproperty = wdf.getDataPropertyDao().getDataPropertyByURI( predicateUri ); - if( dataproperty == null) { - // No dataproperty will be returned for rdfs:label, but we shouldn't throw an error. - // This is controlled by the Jena layer, so we can't change the behavior. - if (! predicateUri.equals(VitroVocabulary.LABEL)) { - log.error("Could not find data property '"+predicateUri+"' in model"); - return doHelp(vreq, "EditDataPropStmtRequestDispatchController: Could not find DataProperty in model: " + predicateUri); - } - } - else { - vreq.setAttribute("predicate", dataproperty); - } - - // Keep track of what form we are using so it can be returned to after a failed validation - // I'd like to get this from the request but sometimes that doesn't work well, internal forwards etc. - //TODO: this needs to be the same as the mapping in web.xml - vreq.setAttribute("formUrl", "/edit/editRequest?" + vreq.getQueryString()); - - String datapropKeyStr = vreq.getParameter("datapropKey"); - int dataHash = 0; - if( datapropKeyStr != null ){ - try { - dataHash = Integer.parseInt(datapropKeyStr); - vreq.setAttribute("datahash", dataHash); - log.debug("Found a datapropKey in parameters and parsed it to int: " + dataHash); - } catch (NumberFormatException ex) { - return doHelp(vreq, "Cannot decode incoming datapropKey value "+datapropKeyStr+" as an integer hash in EditDataPropStmtRequestDispatchController"); - } - } - - DataPropertyStatement dps = null; - if( dataHash != 0) { - Model model = (Model)session.getServletContext().getAttribute("jenaOntModel"); - dps = RdfLiteralHash.getPropertyStmtByHash(subject, predicateUri, dataHash, model); - - if (dps==null) { - log.error("No match to existing data property \""+predicateUri+"\" statement for subject \""+subjectUri+"\" via key "+datapropKeyStr); - //TODO: Needs to forward to dataPropMissingStatement.jsp - return null; - } - vreq.setAttribute("dataprop", dps ); - } - - if( log.isDebugEnabled() ){ - if (dataproperty != null) { - log.debug("predicate for DataProperty from request is " + dataproperty.getURI() + " with rangeDatatypeUri of '" + dataproperty.getRangeDatatypeURI() + "'"); - } - if( dps == null ) - log.debug("no existing DataPropertyStatement statement was found, making a new statemet"); - else{ - log.debug("Found an existing DataPropertyStatement"); - String msg = "existing datapropstmt: "; - msg += " subject uri: <"+dps.getIndividualURI() + ">\n"; - msg += " prop uri: <"+dps.getDatapropURI() + ">\n"; - msg += " prop data: \"" + dps.getData() + "\"\n"; - msg += " datatype: <" + dps.getDatatypeURI() + ">\n"; - msg += " hash of this stmt: " + RdfLiteralHash.makeRdfLiteralHash(dps); - log.debug(msg); - } - } - - -// vreq.setAttribute("preForm", "/edit/formPrefix.jsp"); -// vreq.setAttribute("postForm", "/edit/formSuffix.jsp"); - - if( "delete".equals(command) ){ - //TODO: Needs to forward to dataPropStmtDelete.jsp - return null; - } - - String form = null; - if (formParam != null) { - form = formParam; - } - else if (predicateUri.equals(VitroVocabulary.LABEL)) { // dataproperty is null here - form = "rdfsLabelForm.jsp"; - } - else { - form = dataproperty.getCustomEntryForm(); - if (form != null && form.length()>0) { - log.warn("have a custom form for this data property: "+form); - vreq.setAttribute("hasCustomForm","true"); - } else { - form = DEFAULT_DATA_FORM; - } - } - vreq.setAttribute("form", form); - - if( session.getAttribute("requestedFromEntity") == null ) { - session.setAttribute("requestedFromEntity", subjectUri ); - } - - /**** make the edit configuration ***/ - EditConfiguration editConfig = makeEditConfiguration( form, vreq, session); - - //what template? - String template = editConfig.getTemplate(); - - //what goes in the map for templates? - Map templateData = new HashMap(); - templateData.put("editConfiguration", editConfig); - - return new TemplateResponseValues(editConfig.getTemplate(), templateData); - - } - - - private EditConfiguration makeEditConfiguration( - String editConfGeneratorName, VitroRequest vreq, HttpSession session) { - - EditConfigurationGenerator editConfigurationGenerator = null; - - Object object = null; - try { - Class classDefinition = Class.forName(editConfGeneratorName); - object = classDefinition.newInstance(); - editConfigurationGenerator = (EditConfigurationGenerator) object; - } catch (InstantiationException e) { - System.out.println(e); - } catch (IllegalAccessException e) { - System.out.println(e); - } catch (ClassNotFoundException e) { - System.out.println(e); - } - - if(editConfigurationGenerator == null){ - log.error("could not find editConfigurationGenerator " + editConfGeneratorName); - return null; - } else { - return editConfigurationGenerator.getEditConfiguration(vreq, session); - } - - } - - private ResponseValues doHelp(VitroRequest vreq, String message){ - //output some sort of help message for the developers. - - return null; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index 48707dc6f..2fc5b9d5b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -17,7 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.EditConfigurationGenerator; import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit.EditConfigurationTemplateModel; @@ -40,7 +40,13 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { final String DEFAULT_ERROR_FORM = "error.jsp"; final String DEFAULT_ADD_INDIVIDUAL = "defaultAddMissingIndividualForm.jsp"; @Override - protected ResponseValues processRequest(VitroRequest vreq) { + protected ResponseValues processRequest(VitroRequest vreq) { + Map mapTest = vreq.getParameterMap(); + java.util.Iterator testIterator = mapTest.keySet().iterator(); + while(testIterator.hasNext()) { + String paramKey = (String) testIterator.next(); + System.out.println("Param key is " + paramKey + " and test iterator is value is " + mapTest.get(paramKey).toString()); + } try{ WebappDaoFactory wdf = vreq.getWebappDaoFactory(); @@ -48,9 +54,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { //The edit key links submissions to EditConfiguration objects in the session. HttpSession session = vreq.getSession(); String editKey = - (EditConfiguration.getEditKey(vreq) == null) - ? EditConfiguration.newEditKey(session) - : EditConfiguration.getEditKey(vreq); + (EditConfigurationVTwo.getEditKey(vreq) == null) + ? EditConfigurationVTwo.newEditKey(session) + : EditConfigurationVTwo.getEditKey(vreq); vreq.setAttribute("editKey", editKey); //set title to Edit to maintain functionality from 1.1.1 and avoid updates to Selenium tests @@ -125,7 +131,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { // Keep track of what form we are using so it can be returned to after a failed validation // I'd like to get this from the request but sometimes that doesn't work well, internal forwards etc. //TODO: this needs to be the same as the mapping in web.xml - vreq.setAttribute("formUrl", "/edit/editRequest?" + vreq.getQueryString()); + vreq.setAttribute("formUrl", "/edit/editRequestDispatch?" + vreq.getQueryString()); if ("delete".equals(command)) { //TODO: delete command is used with the defualt delete form @@ -155,14 +161,14 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { HashMap map = new HashMap(); map.put("errorMessage", "skip edit form for object properties is not yet implemented"); return new TemplateResponseValues("error-message.ftl", map); - } + } //use default object property form if nothing else works String editConfGeneratorName = DEFAULT_OBJ_FORM; // *** handle the case where the form is specified as a request parameter *** if( predicateUri == null && ( formParam != null && !formParam.isEmpty()) ){ - //form parameter must be a fully qualified java class name of a EditConfigurationGenerator implementation. + //form parameter must be a fully qualified java class name of a EditConfigurationVTwoGenerator implementation. editConfGeneratorName = formParam; } @@ -177,7 +183,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { if( objectProp != null ){ vreq.setAttribute("predicate", objectProp); //custom entry form use to be a jsp but it should now be a fully qualified java class name of a - //EditConfigurationGenerator implementation. + //EditConfigurationVTwoGenerator implementation. customForm = objectProp.getCustomEntryForm(); if (customForm != null && customForm.length() > 0) { //if there is a custom form on the predicate, use that @@ -185,9 +191,13 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { } } + // The default object proepty form offers the option to create a new item + // instead of selecting from existing individuals in the system. + // This is where the request to create a new indivdiual is handled. + // // Forward to create new is part of the default object property form - // it should be handled in that form's EditConfiguration, not here. - // The code that sets up the EditConfiguration should decide on + // it should be handled in that form's EditConfigurationVTwo, not here. + // The code that sets up the EditConfigurationVTwo should decide on // different configurations and templates to use based on isForwardToCreateNew. //TODO: make sure that forward to create new works on the default object property form if( isFowardToCreateNew(vreq, objectProp, command)){ @@ -198,9 +208,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { /**** make new or get an existing edit configuration ***/ - EditConfiguration editConfig = makeEditConfiguration( editConfGeneratorName, vreq, session); + EditConfigurationVTwo editConfig = makeEditConfigurationVTwo( editConfGeneratorName, vreq, session); editConfig.setEditKey(editKey); - EditConfiguration.putConfigInSession(editConfig, session); + EditConfigurationVTwo.putConfigInSession(editConfig, session); //what template? String template = editConfig.getTemplate(); @@ -208,7 +218,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { //what goes in the map for templates? Map templateData = new HashMap(); - templateData.put("editConfiguration", new EditConfigurationTemplateModel( editConfig, vreq)); + templateData.put("EditConfiguration", new EditConfigurationTemplateModel( editConfig, vreq)); templateData.put("formTitle", formTitle); return new TemplateResponseValues(template, templateData); @@ -222,16 +232,16 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { } } - private EditConfiguration makeEditConfiguration( + private EditConfigurationVTwo makeEditConfigurationVTwo( String editConfGeneratorName, VitroRequest vreq, HttpSession session) { - EditConfigurationGenerator editConfigurationGenerator = null; + EditConfigurationGenerator EditConfigurationVTwoGenerator = null; Object object = null; try { Class classDefinition = Class.forName(editConfGeneratorName); object = classDefinition.newInstance(); - editConfigurationGenerator = (EditConfigurationGenerator) object; + EditConfigurationVTwoGenerator = (EditConfigurationGenerator) object; } catch (InstantiationException e) { System.out.println(e); } catch (IllegalAccessException e) { @@ -240,19 +250,19 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { System.out.println(e); } - if(editConfigurationGenerator == null){ - log.error("could not find editConfigurationGenerator " + editConfGeneratorName); + if(EditConfigurationVTwoGenerator == null){ + log.error("could not find EditConfigurationVTwoGenerator " + editConfGeneratorName); return null; } else { - return editConfigurationGenerator.getEditConfiguration(vreq, session); + return EditConfigurationVTwoGenerator.getEditConfiguration(vreq, session); } } /* Forward to create new is part of the default object property form - it should be handled in that form's EditConfiguration, not here. - The code that sets up the EditConfiguration should decide on + it should be handled in that form's EditConfigurationVTwo, not here. + The code that sets up the EditConfigurationVTwo should decide on different configurations and templates to use based on isForwardToCreateNew. */ boolean isFowardToCreateNew(VitroRequest vreq, ObjectProperty objectProp, String command){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java index 14b1d10af..ab2f624a4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java @@ -30,12 +30,13 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.AdditionsAndRetractions; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditN3Utils; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.ProcessRdfForm; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditSubmissionUtils; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.AdditionsAndRetractions; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.ProcessRdfForm; /** * This servlet will process EditConfigurations with query parameters @@ -63,15 +64,15 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{ VitroRequest vreq = new VitroRequest(request); //get the EditConfiguration - EditConfiguration configuration = getEditConfiguration(request); + EditConfigurationVTwo configuration = getEditConfiguration(request); if(configuration == null){ doEditConfigNotFound( vreq, response); return; } //get the EditSubmission - EditSubmission submission = new EditSubmission(vreq.getParameterMap(), configuration); - EditSubmission.putEditSubmissionInSession(request.getSession(), submission); + MultiValueEditSubmission submission = new MultiValueEditSubmission(vreq.getParameterMap(), configuration); + EditSubmissionUtils.putEditSubmissionInSession(request.getSession(), submission); boolean hasErrors = doValidationErrors(vreq, configuration, submission, response); if( hasErrors) @@ -103,9 +104,9 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{ doPostEdit(vreq,response); } - private EditConfiguration getEditConfiguration(HttpServletRequest request) { + private EditConfigurationVTwo getEditConfiguration(HttpServletRequest request) { HttpSession session = request.getSession(); - EditConfiguration editConfiguration = EditConfiguration.getConfigFromSession(session, request); + EditConfigurationVTwo editConfiguration = EditConfigurationVTwo.getConfigFromSession(session, request); return editConfiguration; } private void doEditConfigNotFound(VitroRequest request, HttpServletResponse response) { @@ -120,7 +121,7 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{ } private boolean doValidationErrors(VitroRequest vreq, - EditConfiguration editConfiguration, EditSubmission submission, + EditConfigurationVTwo editConfiguration, MultiValueEditSubmission submission, HttpServletResponse response) throws ServletException, IOException { Map errors = submission.getValidationErrors(); @@ -148,10 +149,10 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{ private static Log log = LogFactory.getLog(ProcessRdfFormController.class); static Random random = new Random(); - public static Map> fieldsToAssertionMap( Map fields){ + public static Map> fieldsToAssertionMap( Map fields){ Map> out = new HashMap>(); for( String fieldName : fields.keySet()){ - Field field = fields.get(fieldName); + FieldVTwo field = fields.get(fieldName); List copyOfN3 = new ArrayList(); for( String str : field.getAssertions()){ @@ -162,10 +163,10 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{ return out; } - public static Map> fieldsToRetractionMap( Map fields){ + public static Map> fieldsToRetractionMap( Map fields){ Map> out = new HashMap>(); for( String fieldName : fields.keySet()){ - Field field = fields.get(fieldName); + FieldVTwo field = fields.get(fieldName); List copyOfN3 = new ArrayList(); for( String str : field.getRetractions()){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Generator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Generator.java index e956a54a3..e2a10934a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Generator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Generator.java @@ -40,14 +40,7 @@ public class EditN3Generator { return Collections.EMPTY_LIST; } - /** - * This is the method to use to substitute in URIs into variables of target N3 strings. - * This takes into account multiple values that would be returned from a select list. - * subInUris should no longer be used. - */ - public static List subInMultiUris(Map> varsToVals, List n3targets){ - return null; - } + public static List subInUris(Map varsToVals, List targets){ if( varsToVals == null || varsToVals.isEmpty() ) return targets; @@ -88,15 +81,6 @@ public class EditN3Generator { } return outv; } - - /** - * This is the method to use to substitute in Literals into variables of target N3 strings. - * This takes into account multiple values that would be returned from a select list. - * subInUris should no longer be used. - */ - public static List subInMultiLiterals(Map> varsToVals, List n3targets){ - return null; - } public List subInLiterals(Map varsToVals, List targets){ if( varsToVals == null || varsToVals.isEmpty()) return targets; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index 50d4ff344..c7f06450b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -271,11 +271,17 @@ public class VitroRequestPrep implements Filter { } //Changes will be made to the copy, not the original from the servlet context wadfj.setSpecialDataModel(useMainOntModel, useTboxOntModel, useDisplayOntModel); + //Set attribute on VitroRequest that saves special write model + vreq.setAttribute(vreq.SPECIAL_WRITE_MODEL, useMainOntModel); return wadfj; } } } //if no parameters exist for switching models, return the original webapp dao factory object + //ensure no attribute there if special write model not being utilized + if(vreq.getAttribute(vreq.SPECIAL_WRITE_MODEL) != null) { + vreq.removeAttribute(vreq.SPECIAL_WRITE_MODEL); + } return inputWadf; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index eff73d304..68fa19153 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -2,15 +2,15 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; public class EditConfigurationTemplateModel extends BaseTemplateModel { - EditConfiguration editConfig; + EditConfigurationVTwo editConfig; VitroRequest vreq; - public EditConfigurationTemplateModel( EditConfiguration editConfig, VitroRequest vreq){ + public EditConfigurationTemplateModel( EditConfigurationVTwo editConfig, VitroRequest vreq){ this.editConfig = editConfig; this.vreq = vreq; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/MultiValueEditSubmissionTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/MultiValueEditSubmissionTemplateModel.java new file mode 100644 index 000000000..db1893cee --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/MultiValueEditSubmissionTemplateModel.java @@ -0,0 +1,34 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit; + +import java.util.Map; +import java.util.List; +import com.hp.hpl.jena.rdf.model.Literal; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; + +public class MultiValueEditSubmissionTemplateModel { + private MultiValueEditSubmission editSub; + + public Map> getLiteralsFromForm() { + return editSub.getLiteralsFromForm(); + } + + /* + public Map> getValidationErrors() { + return editSub.getValidationErrors(); + }*/ + + public Map> getUrisFromForm() { + return editSub.getUrisFromForm(); + } + + public MultiValueEditSubmissionTemplateModel(MultiValueEditSubmission editSub){ + this.editSub = editSub; + } + + + + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwoTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwoTest.java new file mode 100644 index 000000000..4c831c62e --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditN3GeneratorVTwoTest.java @@ -0,0 +1,55 @@ +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; + + +public class EditN3GeneratorVTwoTest { + @Test + public void testSubInMultiUris() { + String n3 = "?subject ?predicate ?multivalue ." ; + List strs = new ArrayList(); + strs.add(n3); + + Map> keyToValues = new HashMap>(); + List values = new ArrayList(); + values.add("http://a.com/2"); + values.add("http://b.com/ont#2"); + values.add("http://c.com/individual/n23431"); + keyToValues.put("multivalue", values); + + List subject = new ArrayList(); + List predicate = new ArrayList(); + subject.add("http://testsubject.com/1"); + predicate.add("http://testpredicate.com/2"); + keyToValues.put("subject", subject); + keyToValues.put("predicate", predicate); + + List n3results = EditN3GeneratorVTwo.subInMultiUris(keyToValues, strs); + + Assert.assertNotNull(n3results); + Assert.assertTrue( n3results.size() == 1 ); + String expected =" , , ."; + Assert.assertEquals(expected, n3results.get(0)); + + //Replace subject and predicate with other variables + + //make a model, + Model expectedModel = ModelFactory.createDefaultModel(); + StringReader expectedReader = new StringReader(expected); + StringReader resultReader = new StringReader(n3results.get(0)); + expectedModel.read(expectedReader, null, "N3"); + Model resultModel = ModelFactory.createDefaultModel(); + resultModel.read(resultReader, null, "N3"); + Assert.assertTrue(expectedModel.isIsomorphicWith(resultModel)); + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3GeneratorTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3GeneratorTest.java index 2230085be..ff6149063 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3GeneratorTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3GeneratorTest.java @@ -8,34 +8,82 @@ import java.util.List; import java.util.Map; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; + +import java.io.StringReader; public class EditN3GeneratorTest { + + +EditN3Generator en3g ; + + @Before + public void setUp() throws Exception { + en3g = new EditN3Generator((EditConfiguration) null); + } + @Test - public void testSubInMultiUris() { -// String n3 = "?subject ?predicate ?multivalue." ; -// List strs = new ArrayList(); -// strs.add(n3); -// -// Map> keyToValues = new HashMap>(); -// List values = new ArrayList(); -// values.add("http://a.com/2"); -// values.add("http://b.com/ont#2"); -// values.add("http://c.com/individual/n23431"); -// keyToValues.put("multivalue", values); -// -// List n3results = EditN3Generator.subInMultiLiterals(keyToValues, strs); -// -// Assert.assertNotNull(n3results); -// Assert.assertTrue( n3results.size() == 1 ); -// String expected ="?subject ?predicate , , ."; -// Assert.assertEquals(expected, n3results); -// - //make a model, - //add statements - //prase resultn3 - //compare + public void testSubInLiterals() { + String var = "TestVar"; + String target = "Fake n3 ?TestVar ."; + Literal literal = null; + + EditN3Generator en3g = new EditN3Generator((EditConfiguration) null); + String result = en3g.subInLiterals(var, literal, target); + Assert.assertNotNull( result ); + } + + + @Test + public void testSubInLiteralsWithGroupReference() { + String var = "TestVar"; + String target = "Fake n3 ?TestVar ."; + Literal literal = new EditLiteral("should not a regex group --> ?2 <-- blblkj (lskdfj) " ,null,null); + + EditN3Generator en3g = new EditN3Generator((EditConfiguration) null); + String result = en3g.subInLiterals(var, literal, target); + Assert.assertNotNull( result ); + Assert.assertEquals("Fake n3 \"should not a regex group --> ?2 <-- blblkj (lskdfj) \" ." , result); + } + + @Test + public void testConflictingVarNames(){ + Map varToExisting= new HashMap(); + varToExisting.put("bob", "http://uri.edu#BobTheElder"); + varToExisting.put("bobJr", "http://uri.edu#BobTheSon"); + + String target = "SELECT ?cat WHERE{ ?bobJr ?cat }" ; + List targets = new ArrayList(); + targets.add(target); + + List out = en3g.subInUris(varToExisting, targets); + Assert.assertNotNull(out); + Assert.assertNotNull( out.get(0) ); + String expected = "SELECT ?cat WHERE{ ?cat }"; + Assert.assertEquals(expected, out.get(0) ); + + //force a non match on a initial-partial var name + varToExisting= new HashMap(); + varToExisting.put("bob", "http://uri.edu#BobTheElder"); + + target = "SELECT ?cat WHERE{ ?bobJr ?cat }" ; + targets = new ArrayList(); + targets.add(target); + + out = en3g.subInUris(varToExisting, targets); + Assert.assertNotNull(out); + Assert.assertNotNull( out.get(0) ); + expected = target; + Assert.assertEquals(expected, out.get(0) ); + } } diff --git a/webapp/web/edit/editRequestDispatch.jsp b/webapp/web/edit/editRequestDispatch.jsp index 2af319f81..3114bfd89 100644 --- a/webapp/web/edit/editRequestDispatch.jsp +++ b/webapp/web/edit/editRequestDispatch.jsp @@ -24,6 +24,15 @@ public static Log log = LogFactory.getLog("edu.cornell.mannlib.vitro.webapp.jsp. <% + + //Check if special model, in which case forward + if(request.getParameter("switchToDisplayModel") != null) { + //forward to Edit Request Dispatch Controller + String queryString = request.getQueryString(); + System.out.println("Query string is " + queryString); + System.out.println("Servlet path is " + request.getServletPath() + " and context path si " + request.getContextPath()); + response.sendRedirect("http://localhost:8080/vivo/editRequestDispatch?" + queryString); + } /* Decide which form to forward to, set subjectUri, subjectUriJson, predicateUri, and predicateUriJson in request. Also get the Individual for the subjectUri and put it in the request scope.