diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/N3EditFormController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/N3EditFormController.java new file mode 100644 index 000000000..8f04140b4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/N3EditFormController.java @@ -0,0 +1,88 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditSubmission; +import freemarker.template.ObjectWrapper; +import freemarker.template.TemplateModelException; + +/** + * This controller is intended to place N3 editing data into the + * FM data model and output the FM template for the form. + */ +public class N3EditFormController extends FreemarkerHttpServlet{ + + @Override + protected ResponseValues processRequest(VitroRequest vreq) { + try{ + //get edit objects + HttpSession session = vreq.getSession(false); + if( session == null ) + throw new Exception("Cannot get session"); + + EditConfiguration editConfig = EditConfiguration.getConfigFromSession(session, vreq); + if(editConfig == null ) + throw new Exception("Cannot get EditConfiguration from session"); + + EditSubmission editSubmission = EditSubmission.getEditSubmissionFromSession(session, editConfig); + + //add edit info to the template data model and call template + Map map = makeEditDataMap(editConfig, editSubmission); + + //how do I add css or js? + //The jsp is adding css and js like this: + /* + List customJs = new ArrayList(Arrays.asList(JavaScript.JQUERY_UI.path(), + JavaScript.CUSTOM_FORM_UTILS.path(), + "/edit/forms/js/customFormWithAutocomplete.js" + )); + request.setAttribute("customJs", customJs); + + List customCss = new ArrayList(Arrays.asList(Css.JQUERY_UI.path(), + Css.CUSTOM_FORM.path(), + "/edit/forms/css/customFormWithAutocomplete.css" + )); + request.setAttribute("customCss", customCss); + */ + + //What needs to happen?? + //map.put(???); + + return new TemplateResponseValues(editConfig.getTemplate(), map); + }catch(Exception ex){ + return new ExceptionResponseValues(ex); + } + } + + /** + * This method get data out of the editConfig and editSubmission for the template. + * @throws TemplateModelException + */ + private Map makeEditDataMap(EditConfiguration editConfig, + EditSubmission editSubmission) throws TemplateModelException { + + Map map = new HashMap(); + + //This dosen't seem to be the right thing: + map.put("editConfig", ObjectWrapper.BEANS_WRAPPER.wrap(editConfig)); + + //<@dump var="editConfig"/> outputs: + /* + * Template variable dump + Variable name: editConfig + Type: string + Value: edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration@1e60601 + */ + + if( editSubmission != null) + map.put("editSubmission", ObjectWrapper.BEANS_WRAPPER.wrap(editSubmission)); + return map; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/BaseEditElement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/BaseEditElement.java index 3bc5eb8b2..3d98df9d4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/BaseEditElement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/BaseEditElement.java @@ -9,6 +9,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.Field; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; @@ -16,6 +17,12 @@ import freemarker.template.TemplateException; public abstract class BaseEditElement implements EditElement { private static final Log log = LogFactory.getLog(BaseEditElement.class); + protected Field field; + + public BaseEditElement(Field field){ + this.field = field; + } + /** * Utility method for use in EditElements to merge a freemarker template. */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/EditElement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/EditElement.java index dcc6e7484..7df85c62e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/EditElement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/elements/EditElement.java @@ -10,8 +10,9 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditSubmission; import freemarker.template.Configuration; /** - * All classes that implement this interface must have a public empty constructor that - * will be called with using reflection. + * 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 EditElement { /** @@ -36,5 +37,11 @@ public interface EditElement { * 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, EditConfiguration editConfig, EditSubmission editSub, Configuration fmConfig); + public String draw(String fieldName, EditConfiguration editConfig, EditSubmission editSub, Configuration fmConfig); + + /** + * We may need a method to get existing URIs and Literals for use in building retraction statements? + */ + // public Map getExistingLiterals(?); + // public Map getExistingURIs(?); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/EditConfiguration.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/EditConfiguration.java index bc8a9da20..3cdf4ca12 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/EditConfiguration.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/EditConfiguration.java @@ -97,6 +97,12 @@ public class EditConfiguration { 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. @@ -943,4 +949,20 @@ public class EditConfiguration { 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; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/Field.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/Field.java index 090b7ba1f..d046a90b6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/Field.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/Field.java @@ -123,6 +123,7 @@ public class Field { /* *********************** Constructors ************************** */ public Field(String config, String varName) { + name=varName; JSONObject jsonObj = null; try{ jsonObj = new JSONObject(config); @@ -138,8 +139,8 @@ public class Field { } public Field() {} - - private static String[] parameterNames = {"newResource","validators","optionsType","predicateUri","objectClassUri","rangeDatatypeUri","rangeLang","literalOptions","assertions"}; + + 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){ @@ -161,7 +162,8 @@ public class Field { setLiteralOptions(obj.getJSONArray("literalOptions")); setAssertions(EditConfiguration.JsonArrayToStringList(obj.getJSONArray("assertions"))); - + + setEditElement( obj, fieldName); //check for odd parameters JSONArray names = obj.names(); @@ -178,7 +180,56 @@ public class Field { } + /** + * 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(Field.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[]{ Field.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 = (EditElement)obj; + } + /* ****************** Getters and Setters ******************************* */ + + public String getName(){ + return name; + } public List getRetractions() { return retractions; @@ -217,62 +268,43 @@ public class Field { 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)) { - setOptionsType(Field.OptionsType.LITERALS); + return Field.OptionsType.LITERALS; } else if ("HARDCODED_LITERALS".equals(s)) { - setOptionsType(Field.OptionsType.HARDCODED_LITERALS); + return Field.OptionsType.HARDCODED_LITERALS; } else if ("STRINGS_VIA_DATATYPE_PROPERTY".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.STRINGS_VIA_DATATYPE_PROPERTY); + return Field.OptionsType.STRINGS_VIA_DATATYPE_PROPERTY; } else if ("INDIVIDUALS_VIA_OBJECT_PROPERTY".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.INDIVIDUALS_VIA_OBJECT_PROPERTY); + return Field.OptionsType.INDIVIDUALS_VIA_OBJECT_PROPERTY; } else if ("INDIVIDUALS_VIA_VCLASS".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.INDIVIDUALS_VIA_VCLASS); + return Field.OptionsType.INDIVIDUALS_VIA_VCLASS; } else if ("MONIKERS_VIA_VCLASS".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.MONIKERS_VIA_VCLASS); + return Field.OptionsType.MONIKERS_VIA_VCLASS; } else if ("DATETIME".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.DATETIME); + return Field.OptionsType.DATETIME; } else if ("CHILD_VCLASSES".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.CHILD_VCLASSES); + return Field.OptionsType.CHILD_VCLASSES; } else if ("CHILD_VCLASSES_WITH_PARENT".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.CHILD_VCLASSES_WITH_PARENT); + return Field.OptionsType.CHILD_VCLASSES_WITH_PARENT; } else if ("VCLASSGROUP".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.VCLASSGROUP); + return Field.OptionsType.VCLASSGROUP; } else if ("FILE".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.FILE); + return Field.OptionsType.FILE; } else if ("DATE".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.DATE); + return Field.OptionsType.DATE; } else if ("TIME".equalsIgnoreCase(s)) { - setOptionsType(Field.OptionsType.TIME); - } else if ("UNDEFINED".equalsIgnoreCase(s) || s == null || s.isEmpty()){ - setOptionsType(Field.OptionsType.UNDEFINED); + return Field.OptionsType.TIME; } else { - setSpecalOptionType(s); - } + return Field.OptionsType.UNDEFINED; + } } - - private void setSpecalOptionType(String s) { - try { - Class clz = Class.forName(s); - Object obj = clz.newInstance(); - editElement = (EditElement)obj; - } catch (ClassNotFoundException e) { - log.error("Java Class " + s + " not found for field " + name); - setOptionsType(Field.OptionsType.UNDEFINED); - } catch (SecurityException e) { - log.error("Problem with Java Class " + s + " for field " + name, e); - setOptionsType(Field.OptionsType.UNDEFINED); - } catch (IllegalArgumentException e) { - log.error("Problem with Java Class " + s + " for field " + name, e); - setOptionsType(Field.OptionsType.UNDEFINED); - } catch (InstantiationException e) { - log.error("Problem with Java Class " + s + " for field " + name, e); - setOptionsType(Field.OptionsType.UNDEFINED); - } catch (IllegalAccessException e) { - log.error("Problem with Java Class " + s + " for field " + name, e); - setOptionsType(Field.OptionsType.UNDEFINED); - } - } - + public String getPredicateUri() { return predicateUri; } @@ -364,5 +396,10 @@ public class Field { public EditElement 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/web/widgets/SelectListWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/SelectListWidget.java new file mode 100644 index 000000000..924e96afa --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/SelectListWidget.java @@ -0,0 +1,59 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.web.widgets; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.SelectListGenerator; +import edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective; +import freemarker.core.Environment; +import freemarker.template.SimpleScalar; + +public class SelectListWidget extends Widget { + private static final Log log = LogFactory.getLog(SelectListWidget.class); + + @Override + protected WidgetTemplateValues process(Environment env, Map params, + HttpServletRequest request, ServletContext context) { + + Object obj = params.get("fieldName"); + if( obj == null || !(obj instanceof SimpleScalar)){ + log.error("SelectListWidget must have a parameter 'fieldName'"); + throw new Error("SelectListWidget must have a parameter'fieldName'"); + } + String fieldName = ((SimpleScalar)obj).getAsString(); + if( fieldName.isEmpty() ){ + log.error("SelectListWidget must have a parameter 'fieldName'"); + throw new Error("SelectListWidget must have a parameter 'fieldName' of type String"); + } + + VitroRequest vreq = new VitroRequest(request); + HttpSession session = request.getSession(false); + EditConfiguration editConfig = EditConfiguration.getConfigFromSession(session,request); + + WebappDaoFactory wdf; + if (editConfig != null) { + wdf = editConfig.getWdfSelectorForOptons().getWdf(vreq,context); + } else { + wdf = vreq.getWebappDaoFactory(); + } + + Map selectOptions = SelectListGenerator.getOptions(editConfig, fieldName, wdf); + Map rmap = new HashMap(); + rmap.put("selectList", selectOptions); + + return new WidgetTemplateValues("markup", rmap); + } + +} diff --git a/webapp/web/edit/forms/test/dateTimePrecTest.jsp b/webapp/web/edit/forms/test/dateTimePrecTest.jsp new file mode 100644 index 000000000..4541dd67b --- /dev/null +++ b/webapp/web/edit/forms/test/dateTimePrecTest.jsp @@ -0,0 +1,114 @@ +<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%> + +<%-- + +This is a test file for the DateTimeWithPrecision EditElement. + + --%> +<%@ page import="com.hp.hpl.jena.rdf.model.Model" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.Individual" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataProperty" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.VitroRequest"%> +<%@ page import="java.util.HashMap"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory"%> +<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils"%> + +<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> +<%@ taglib prefix="v" uri="http://vitro.mannlib.cornell.edu/vitro/tags" %> + +<% + org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("edu.cornell.mannlib.vitro.jsp.edit.forms.test.dateTimePrecTest.jsp"); + log.debug("Starting dateTimePrecTest.jsp"); +%> +<% + Individual subject = (Individual)request.getAttribute("subject"); + VitroRequest vreq = new VitroRequest(request); + WebappDaoFactory wdf = vreq.getWebappDaoFactory(); +%> + + + @prefix rdf: . + @prefix rdfs: . + @prefix vivo: . + @prefix vitro: . + @prefix core: . + + ?subject ?predicate ?object . + ?object ?dtX. + ?dtX . + + ?dtX ?dtX.value . + ?dtX ?dtX.precision . + + + + { + "formUrl" : "${formUrl}", + "editKey" : "${editKey}", + "urlPatternToReturnTo" : "/individual", + + "subject" : [ "subject", "${subjectUriJson}" ], + "predicate" : [ "predicate", "${predicateUriJson}" ], + "object" : [ "object", "${objectUriJson}", "URI" ], + + "n3required" : [ "${n3ForEdit}" ], + "n3optional" : [ ], + "newResources" : { "dtX" : "", "object" : "" }, + "urisInScope" : { }, + "literalsInScope" : { }, + "urisOnForm" : [ ], + "literalsOnForm" : [ ], + "filesOnForm" : [ ], + "sparqlForLiterals" : { }, + "sparqlForUris" : { }, + "sparqlForExistingLiterals" : { }, + "sparqlForExistingUris" : { }, + "fields" : { + "dtX" : { + "newResource" : "true", + "validators" : [ ], + "optionsType" : "edu.cornell.mannlib.vitro.webapp.edit.elements.DateTimeWithPrecision", + "literalOptions" : [ ], + "predicateUri" : "", + "objectClassUri" : "", + "rangeDatatypeUri" : "", + "rangeLang" : "", + "assertions" : [ "${n3ForEdit}" ] + } + } + } + +<% + EditConfiguration editConfig = EditConfiguration.getConfigFromSession(session,request); + if( editConfig == null ){ + editConfig = new EditConfiguration((String)request.getAttribute("editjson")); + EditConfiguration.putConfigInSession(editConfig, session); + } + + Model model = (Model)application.getAttribute("jenaOntModel"); + String objectUri = (String)request.getAttribute("objectUri"); + if( objectUri != null ){ + editConfig.prepareForObjPropUpdate(model); + }else{ + editConfig.prepareForNonUpdate(model); + } + + /* title is used by pre and post form fragments */ + request.setAttribute("title", "Edit dateTimePrec entry for " + subject.getName()); +%> + + + + + +

${title}

+ +
" > + + + + + diff --git a/webapp/web/templates/freemarker/widgets/widget-SelectList.ftl b/webapp/web/templates/freemarker/widgets/widget-SelectList.ftl new file mode 100644 index 000000000..cae4cfeb9 --- /dev/null +++ b/webapp/web/templates/freemarker/widgets/widget-SelectList.ftl @@ -0,0 +1,17 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- SelecListWidget --> + +<#macro assets> + <#-- + ${stylesheets.add("/css/something.css")} + ${scripts.add("/js/somejavascript.js")} + --> + + +<#macro markup> + <#assign keys = selectList?keys> + <#list keys as key> + + +