From d03c677e7f26139e0a250ba4a35246bd18e3e915 Mon Sep 17 00:00:00 2001 From: ryounes Date: Fri, 17 Jun 2011 16:39:06 +0000 Subject: [PATCH 1/3] NIHVIVO-2701 Reorganized code dealing with linked data requests so the requests that should result in a 303 redirect are handled separately from those that shouldn't. --- .../freemarker/IndividualController.java | 189 +++++++++--------- 1 file changed, 99 insertions(+), 90 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index 23d9082fe..b8b875deb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -114,7 +114,7 @@ public class IndividualController extends FreemarkerHttpServlet { return doNotFound(vreq); } - ContentType rdfFormat = checkForLinkedDataRequest(url, vreq); + ContentType rdfFormat = checkUrlForLinkedDataRequest(url, vreq); if( rdfFormat != null ){ return doRdf(vreq, individual, rdfFormat); } @@ -472,110 +472,119 @@ public class IndividualController extends FreemarkerHttpServlet { * to a GET request because it can only send bytes and not things. The server * sends a 303, to mean "you asked for something I cannot send you, but I can * send you this other stream of bytes about that thing." - * In the case of a request like http://vivo.cornell.edu/individual/n1234/n1234.rdf, + * In the case of a request like http://vivo.cornell.edu/individual/n1234/n1234.rdf + * or http://vivo.cornell.edu/individual/n1234?format=rdfxml, * the request is for a set of bytes rather than an individual, so no 303 is needed. */ private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$"); private String checkForRedirect(String url, VitroRequest vreq) { - Matcher m = URI_PATTERN.matcher(url); - if( m.matches() && m.groupCount() == 1 ){ - ContentType c = checkForLinkedDataRequest(url, vreq); - if( c != null ){ - String redirectUrl = "/individual/" + m.group(1) + "/" + m.group(1) ; - if( RDFXML_MIMETYPE.equals( c.getMediaType()) ){ - return redirectUrl + ".rdf"; - }else if( N3_MIMETYPE.equals( c.getMediaType() )){ - return redirectUrl + ".n3"; - }else if( TTL_MIMETYPE.equals( c.getMediaType() )){ - return redirectUrl + ".ttl"; - }//else send them to html - } - //else redirect to HTML representation - return "display/" + m.group(1); - }else{ - return null; - } + + String formatParam = (String) vreq.getParameter("format"); + if ( formatParam == null ) { + Matcher m = URI_PATTERN.matcher(url); + if ( m.matches() && m.groupCount() == 1 ) { + ContentType c = checkAcceptHeaderForLinkedDataRequest(url, vreq); + if ( c != null ) { + String redirectUrl = "/individual/" + m.group(1) + "/" + m.group(1) ; + if ( RDFXML_MIMETYPE.equals( c.getMediaType() ) ) { + return redirectUrl + ".rdf"; + } else if ( N3_MIMETYPE.equals( c.getMediaType() ) ) { + return redirectUrl + ".n3"; + } else if ( TTL_MIMETYPE.equals( c.getMediaType() ) ) { + return redirectUrl + ".ttl"; + }//else send them to html + } + //else redirect to HTML representation + return "display/" + m.group(1); + } + } + return null; } - private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.rdf$"); - private static Pattern N3_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.n3$"); - private static Pattern TTL_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.ttl$"); - private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]*)$"); - + protected ContentType checkAcceptHeaderForLinkedDataRequest(String url, VitroRequest vreq) { + try { + /* + * Check the accept header. This request will trigger a + * redirect with a 303 ("see also"), because the request is for + * an individual but the server can only provide a set of bytes. + */ + String acceptHeader = vreq.getHeader("accept"); + if (acceptHeader != null) { + String ctStr = ContentType.getBestContentType( + ContentType.getTypesAndQ(acceptHeader), + getAcceptedContentTypes()); + + if (ctStr!=null && ( + RDFXML_MIMETYPE.equals(ctStr) || + N3_MIMETYPE.equals(ctStr) || + TTL_MIMETYPE.equals(ctStr) )) + return new ContentType(ctStr); + } + } catch (Throwable th) { + log.error("Problem while checking accept header " , th); + } + return null; + } + public static final Pattern RDFXML_FORMAT = Pattern.compile("rdfxml"); public static final Pattern N3_FORMAT = Pattern.compile("n3"); public static final Pattern TTL_FORMAT = Pattern.compile("ttl"); + private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.rdf$"); + private static Pattern N3_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.n3$"); + private static Pattern TTL_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.ttl$"); + private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]*)$"); + /** * @return null if this is not a linked data request, returns content type if it is a - * linked data request. + * linked data request. + * These are Vitro-specific ways of requesting rdf, unrelated to semantic web standards. + * They do not trigger a redirect with a 303, because the request is for a set of bytes + * rather than an individual. */ - protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) { - try { - Matcher m; - /* - * Check for url param specifying format. - * Example: http://vivo.cornell.edu/individual/n23?format=rdfxml - * This request will trigger a redirect with a 303. - */ - String formatParam = (String) vreq.getParameter("format"); - if (formatParam != null) { - m = RDFXML_FORMAT.matcher(formatParam); - if ( m.matches() ) { - return ContentType.RDFXML; - } - m = N3_FORMAT.matcher(formatParam); - if( m.matches() ) { - return ContentType.N3; - } - m = TTL_FORMAT.matcher(formatParam); - if( m.matches() ) { - return ContentType.TURTLE; - } - } - - /* - * Check the accept header. This request will trigger a - * redirect with a 303, because the request is for an individual - * but the server can only provide a set of bytes. - */ - String acceptHeader = vreq.getHeader("accept"); - if (acceptHeader != null) { - String ctStr = ContentType.getBestContentType( - ContentType.getTypesAndQ(acceptHeader), - getAcceptedContentTypes()); - - if (ctStr!=null && ( - RDFXML_MIMETYPE.equals(ctStr) || - N3_MIMETYPE.equals(ctStr) || - TTL_MIMETYPE.equals(ctStr) )) - return new ContentType(ctStr); - } - - /* - * Check for parts of URL that indicate request for RDF - * http://vivo.cornell.edu/individual/n23/n23.rdf - * http://vivo.cornell.edu/individual/n23/n23.n3 - * http://vivo.cornell.edu/individual/n23/n23.ttl - * This request will not trigger a redirect and 303, because - * the request is for a set of bytes rather than an individual. - */ - m = RDF_REQUEST.matcher(url); - if( m.matches() ) { - return ContentType.RDFXML; + protected ContentType checkUrlForLinkedDataRequest(String url, VitroRequest vreq ) { + + Matcher m; + + /* + * Check for url param specifying format. + * Example: http://vivo.cornell.edu/individual/n23?format=rdfxml + */ + String formatParam = (String) vreq.getParameter("format"); + if (formatParam != null) { + m = RDFXML_FORMAT.matcher(formatParam); + if ( m.matches() ) { + return ContentType.RDFXML; } - m = N3_REQUEST.matcher(url); - if( m.matches() ) { - return ContentType.N3; - } - m = TTL_REQUEST.matcher(url); - if( m.matches() ) { - return ContentType.TURTLE; - } + m = N3_FORMAT.matcher(formatParam); + if( m.matches() ) { + return ContentType.N3; + } + m = TTL_FORMAT.matcher(formatParam); + if( m.matches() ) { + return ContentType.TURTLE; + } + } + + /* + * Check for parts of URL that indicate request for RDF. Examples: + * http://vivo.cornell.edu/individual/n23/n23.rdf + * http://vivo.cornell.edu/individual/n23/n23.n3 + * http://vivo.cornell.edu/individual/n23/n23.ttl + */ + m = RDF_REQUEST.matcher(url); + if( m.matches() ) { + return ContentType.RDFXML; + } + m = N3_REQUEST.matcher(url); + if( m.matches() ) { + return ContentType.N3; + } + m = TTL_REQUEST.matcher(url); + if( m.matches() ) { + return ContentType.TURTLE; + } - } catch (Throwable th) { - log.error("problem while checking accept header " , th); - } return null; } From 86a22b397dac1de7bad562d9c4e169a6d0fa4db8 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 17 Jun 2011 17:31:23 +0000 Subject: [PATCH 2/3] Rename email templates to clarify their purpose. --- .../controller/accounts/admin/UserAccountsEditPageStrategy.java | 2 +- .../controller/accounts/user/UserAccountsResetPasswordPage.java | 2 +- .../controller/accounts/user/UserAccountsUserController.java | 2 -- ...setEmail.ftl => userAccounts-passwordResetCompleteEmail.ftl} | 0 ...wordEmail.ftl => userAccounts-passwordResetPendingEmail.ftl} | 0 5 files changed, 2 insertions(+), 4 deletions(-) rename webapp/web/templates/freemarker/body/accounts/{userAccounts-passwordResetEmail.ftl => userAccounts-passwordResetCompleteEmail.ftl} (100%) rename webapp/web/templates/freemarker/body/accounts/{userAccounts-resetPasswordEmail.ftl => userAccounts-passwordResetPendingEmail.ftl} (100%) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java index b043c2422..163d3cdda 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java @@ -57,7 +57,7 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage { private static class EmailStrategy extends UserAccountsEditPageStrategy { private static final String PARAMETER_RESET_PASSWORD = "resetPassword"; - private static final String EMAIL_TEMPLATE = "userAccounts-resetPasswordEmail.ftl"; + private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetPendingEmail.ftl"; public static final String RESET_PASSWORD_URL = "/accounts/resetPassword"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java index 3bd511b83..f1ec8ed52 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java @@ -26,7 +26,7 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl"; - private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetEmail.ftl"; + private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetCompleteEmail.ftl"; protected UserAccountsResetPasswordPage(VitroRequest vreq) { super(vreq); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java index 3dafd87f9..4437e35cb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,7 +17,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; -import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; /** * Parcel out the different actions required of the UserAccounts GUI. diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl similarity index 100% rename from webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail.ftl rename to webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl similarity index 100% rename from webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail.ftl rename to webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl From 7cd7e7f8a6688de788f3a847a86ef9ce58adaf26 Mon Sep 17 00:00:00 2001 From: manolobevia Date: Fri, 17 Jun 2011 17:34:06 +0000 Subject: [PATCH 3/3] NIHVIVO-2232. Worked on menu management main page. Work in progress. --- .../body/individual/individual-menu.ftl | 36 +++++++++++++++++++ .../individual/individual-menu-properties.ftl | 24 +++++++++++++ .../partials/individual/lib-properties.ftl | 20 +++++++++-- 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 webapp/web/templates/freemarker/body/individual/individual-menu.ftl create mode 100644 webapp/web/templates/freemarker/body/partials/individual/individual-menu-properties.ftl diff --git a/webapp/web/templates/freemarker/body/individual/individual-menu.ftl b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl new file mode 100644 index 000000000..302e452b8 --- /dev/null +++ b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl @@ -0,0 +1,36 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Default VIVO individual profile page template (extends individual.ftl in vitro) --> + +<#include "individual-setup.ftl"> + +<#assign individualProductExtension> + <#-- Include for any class specific template additions --> + ${classSpecificExtension!} + + <#include "individual-overview.ftl"> + + + + +<#assign nameForOtherGroup = "other"> <#-- used by both individual-propertyGroupMenu.ftl and individual-properties.ftl --> + +

Menu management

+ +<#-- Menu Ontology properties --> +<#include "individual-menu-properties.ftl"> + +${stylesheets.add('', + '')} + +${headScripts.add('', + '', + '', + '', + '', + '', + '', + '')} + +${scripts.add('', + '')} \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-menu-properties.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-menu-properties.ftl new file mode 100644 index 000000000..06870cc31 --- /dev/null +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-menu-properties.ftl @@ -0,0 +1,24 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for menu management page --> + +<#import "lib-properties.ftl" as p> + +<#list propertyGroups.all as group> + <#assign groupName = group.getName(nameForOtherGroup)> + + <#-- Display the group heading --> + <#if groupName?has_content> +

${groupName?capitalize}

+ + + <#-- List the menu items(properties) in the group --> + <#list group.properties as property> + <#if property.localName == "hasElement"> + <#-- List menu Items --> + <@p.objectProperty property editable property.template /> +
<#--remove break--> + <@p.addLink property editable /> + + + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/partials/individual/lib-properties.ftl b/webapp/web/templates/freemarker/body/partials/individual/lib-properties.ftl index 779f3bf2f..89d82af59 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/lib-properties.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/lib-properties.ftl @@ -75,7 +75,11 @@ Assumes property is non-null. --> <#macro objectPropertyList property editable statements=property.statements template=property.template> <#list statements as statement> - <@propertyListItem property statement editable><#include "${template}"> + <#if property.localName == "hasElement"> + <@menuItem property statement editable><#include "${template}"> + <#else> + <@propertyListItem property statement editable><#include "${template}"> + @@ -95,7 +99,11 @@ name will be used as the label. --> <#--@dump var="property"/--> <#local url = property.addUrl> <#if url?has_content> - <@showAddLink property.localName label addParamsToEditUrl(url, extraParams) /> + <#if property.localName == "hasElement"> + <@showAddMenuItemLink property.localName label addParamsToEditUrl(url, extraParams) /> + <#else> + <@showAddLink property.localName label addParamsToEditUrl(url, extraParams) /> + @@ -241,4 +249,12 @@ name will be used as the label. --> <@editingLinks "label" label editable /> +<#-- Add menu item button --> +<#macro showAddMenuItemLink propertyLocalName label url> + Add menu item + +<#-- List menu items --> +<#macro menuItem property statement editable > + Position | <#nested> | <@editingLinks "${property.localName}" statement editable/>
+