Revision: 20322 http://sourceforge.net/p/gate/code/20322 Author: ian_roberts Date: 2018-11-27 15:49:02 +0000 (Tue, 27 Nov 2018) Log Message: ----------- Use the jnlp:// or jnlps:// URL scheme for web start links, so they are handed directly to Java Web Start for download rather than being downloaded by the browser, leaving the user to run them locally.
Modified Paths: -------------- teamware/trunk/executive/src/web/gleam/executive/webapp/action/CorpusAction.java teamware/trunk/executive/src/web/gleam/executive/webapp/action/MainMenuAction.java teamware/trunk/executive/web/common/taglibs.jsp teamware/trunk/executive/web/pages/corpusList.jsp teamware/trunk/executive/web/pages/documentList.jsp Added Paths: ----------- teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/ teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/JnlpColumnTag.java teamware/trunk/executive/web/WEB-INF/tw-display.tld Modified: teamware/trunk/executive/src/web/gleam/executive/webapp/action/CorpusAction.java =================================================================== --- teamware/trunk/executive/src/web/gleam/executive/webapp/action/CorpusAction.java 2018-11-23 12:23:04 UTC (rev 20321) +++ teamware/trunk/executive/src/web/gleam/executive/webapp/action/CorpusAction.java 2018-11-27 15:49:02 UTC (rev 20322) @@ -209,6 +209,12 @@ DocServiceManager mgr = (DocServiceManager) getBean("docServiceManager"); request.setAttribute(Constants.CORPUS_LIST, mgr.listCorpora()); request.setAttribute(Constants.docServiceURL, mgr.getDocServiceURL()); + String urlBase = (String)getServlet().getServletContext().getAttribute("urlbase"); + if(urlBase == null || !urlBase.startsWith("http")) { + request.setAttribute("jnlpUrlBase", ""); + } else { + request.setAttribute("jnlpUrlBase", "jnl" + urlBase.substring(3)); + } String userName = request.getRemoteUser(); if (log.isDebugEnabled()) { Modified: teamware/trunk/executive/src/web/gleam/executive/webapp/action/MainMenuAction.java =================================================================== --- teamware/trunk/executive/src/web/gleam/executive/webapp/action/MainMenuAction.java 2018-11-23 12:23:04 UTC (rev 20321) +++ teamware/trunk/executive/src/web/gleam/executive/webapp/action/MainMenuAction.java 2018-11-27 15:49:02 UTC (rev 20322) @@ -33,6 +33,7 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; @@ -73,7 +74,7 @@ if (display) { DocServiceManager docMgr = (DocServiceManager) getBean("docServiceManager"); - String annotatorGUIURL = docMgr.getPoolModeAnnotatorGUIURL(); + String annotatorGUIURL = makeJnlpUrl(request, docMgr.getPoolModeAnnotatorGUIURL()); log.debug("annotatorGUIURL " + annotatorGUIURL); request.setAttribute("annotatorGUIURL", annotatorGUIURL); @@ -121,6 +122,35 @@ return mapping.findForward("displayMainMenu"); } + private String makeJnlpUrl(HttpServletRequest req, String uri) { + StringBuilder result = new StringBuilder(); + if(!(uri.startsWith("http:") || uri.startsWith("https:"))) { + result.append(getServlet().getServletContext().getAttribute("urlbase")); + result.append(req.getContextPath()); + } + String trailer = ""; + int indexOfQuestion = uri.indexOf('?'); + if(indexOfQuestion >= 0) { + result.append(uri, 0, indexOfQuestion); + trailer = uri.substring(indexOfQuestion); + } else { + result.append(uri); + } + // add the session ID + HttpSession sess = req.getSession(false); + if(sess != null) { + result.append(";jsessionid="); + result.append(sess.getId()); + } + result.append(trailer); + + // at this point, we know the URL starts http:// or https://, replace with jnlp: or jnlps: + result.setCharAt(0, 'j'); + result.setCharAt(1, 'n'); + result.setCharAt(2, 'l'); + return result.toString(); + } + boolean roleMatch(Collection<Role> roles, Collection<Role> accessRoles) { boolean flag = false; Iterator<Role> it1 = roles.iterator(); Added: teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/JnlpColumnTag.java =================================================================== --- teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/JnlpColumnTag.java (rev 0) +++ teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/JnlpColumnTag.java 2018-11-27 15:49:02 UTC (rev 20322) @@ -0,0 +1,69 @@ +package gleam.executive.webapp.taglib.displaytag; + +import org.displaytag.tags.ColumnTag; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.jsp.JspException; +import org.apache.commons.lang.StringUtils; + +/** + * Variant of the DisplayTag column tag that generates absolute jnlp: URLs instead of relative ones. + */ +public class JnlpColumnTag extends org.displaytag.tags.ColumnTag { + /** + * setter for the "href" tag attribute. + * @param value attribute value + */ + public void setHref(String value) + { + // call encodeURL to preserve session id when cookies are disabled + String encodedHref = ((HttpServletResponse) this.pageContext.getResponse()).encodeURL(StringUtils + .defaultString(value)); + super.setHref(makeHref(encodedHref)); + } + + /** + * setter for the "url" tag attribute. This has the same meaning of href, but prepends the context path to the given + * URI. + * @param value attribute value + */ + public void setUrl(String value) + { + HttpServletRequest req = (HttpServletRequest) pageContext.getRequest(); + // call encodeURL to preserve session id when cookies are disabled + String encodedHref = ((HttpServletResponse) this.pageContext.getResponse()).encodeURL(StringUtils + .defaultString(req.getContextPath() + value)); + super.setHref(makeHref(encodedHref)); + } + + private String makeHref(String encodedHref) { + HttpServletRequest req = (HttpServletRequest) pageContext.getRequest(); + StringBuilder result = new StringBuilder(); + if(!(encodedHref.startsWith("http:") || encodedHref.startsWith("https:"))) { + result.append(pageContext.getServletContext().getAttribute("urlbase")); + } + String trailer = ""; + int indexOfQuestion = encodedHref.indexOf('?'); + if(indexOfQuestion >= 0) { + result.append(encodedHref, 0, indexOfQuestion); + trailer = encodedHref.substring(indexOfQuestion); + } else { + result.append(encodedHref); + } + // add the session ID + HttpSession sess = req.getSession(false); + if(sess != null) { + result.append(";jsessionid="); + result.append(sess.getId()); + } + result.append(trailer); + + // at this point, we know the URL starts http:// or https://, replace with jnlp: or jnlps: + result.setCharAt(0, 'j'); + result.setCharAt(1, 'n'); + result.setCharAt(2, 'l'); + return result.toString(); + } +} Property changes on: teamware/trunk/executive/src/web/gleam/executive/webapp/taglib/displaytag/JnlpColumnTag.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Added: teamware/trunk/executive/web/WEB-INF/tw-display.tld =================================================================== --- teamware/trunk/executive/web/WEB-INF/tw-display.tld (rev 0) +++ teamware/trunk/executive/web/WEB-INF/tw-display.tld 2018-11-27 15:49:02 UTC (rev 20322) @@ -0,0 +1,329 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> +<taglib> + + <tlib-version>1.0</tlib-version> + <jsp-version>1.2</jsp-version> + <short-name>tw-display</short-name> + <description>Teamware-specific extension of the displaytag library</description> + + <tag> + <name>jnlpColumn</name> + <tag-class>gleam.executive.webapp.taglib.displaytag.JnlpColumnTag</tag-class> + <body-content>JSP</body-content> + <display-name>jnlpColumn</display-name> + <description> + Displays a property of a row object inside a table. MUST be nested inside of a Table tag. The value displayed will + be the results of a decorator (if any); else the property named by the 'property' attribute; or if the 'property' + attribute is null, then the results of evaluating the JSP body of the tag. This is an extension of the standard + column tag which produces absolute jnlp:// or jnlps:// URLs instead of relative ones. + </description> + <attribute> + <name>property</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + name of the property in the bean specified in the parent table tag (via the "name" attribute) mapped to this + column + </description> + </attribute> + <attribute> + <name>sortProperty</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + name of the property in the bean specified in the parent table tag (via the "name" attribute) which will be used + to sort values in the column. This can be used when the column body is filled or a decorator is used and column + should sort on undeorated values. + </description> + </attribute> + <attribute> + <name>title</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description>title of the column (text for the th cell)</description> + </attribute> + <attribute> + <name>comparator</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <description> + The classname of comparator to use when sorting this column, or the comparator itself. Defaults to the + DefaultComparator. + </description> + </attribute> + <attribute> + <name>titleKey</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <description> + Resource key used to lookup the title value. Only works if "title" is not defined. Works together with a + configured I18nResourceProvider, specified via the displaytag.properties file. By default, if JSTL is available, + the JSTL provider is used, which makes this attribute work the same as fmt:message's key property. + </description> + </attribute> + <attribute> + <name>nulls</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + <description> + By default, null values don't appear in the list. By setting 'nulls' to 'true', then null values will appear as + "null" in the list (mostly useful for debugging). Defaults to 'false'. + </description> + </attribute> + <attribute> + <name>total</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + <description> + If true, will total the contents of this column. This value is available via the Map named in varTotals for the + table. Column values need to Numbers. + </description> + </attribute> + <attribute> + <name>sortable</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + <description>Set to 'true' to make the column sortable. Defaults to 'false'.</description> + </attribute> + <attribute> + <name>defaultorder</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + The default sort order for this column. Valid values are "ascending" (default) or "descending" + </description> + </attribute> + <attribute> + <name>autolink</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + <description> + Automatically hyperlink URLs and email addresses that appear in the column. Defaults to 'false'. + </description> + </attribute> + <attribute> + <name>format</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + A MessageFormat patter that will be used to decorate objects in the column. Can be used as a "shortcut" for + simple column decorations. @since 1.1 + </description> + </attribute> + <attribute> + <name>escapeXml</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + <description> + Set it to true to escape special characters in html and xml output. Defaults to 'false'. @since 1.1 + </description> + </attribute> + <attribute> + <name>media</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + Use this attribute to keep a column from being output during an export. The column will only render for the + named media type(s) - it won't be added to the table if the current request media is not supported. Can be any + space separated combination of 'html', 'csv', 'xml', 'all', or 'excel'. Defaults to 'all'. See the export page + in the example webapp for more details. + </description> + </attribute> + <attribute> + <name>href</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + <![CDATA[ + The base URL used to construct the dynamic link. If this attribute is provided, then the data that is shown for + this column is wrapped inside a <a href=""> tag with the url provided through this attribute. Typically you + would use this attribute along with one of the struts-like param attributes (param*) to create a dynamic link so + that each row creates a different URL based on the data that is being viewed. An empty href value will generate + a link to the current page, preserving parameters just like for paging links.]]> + </description> + </attribute> + <attribute> + <name>url</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + The base URL used to construct the dynamic link. This attribute has the same functionality as the href + attribute, but it pre-pends the contextPath. + </description> + </attribute> + <attribute> + <name>paramId</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + The name of the request parameter that will be dynamically added to the generated href URL. The corresponding + value is defined by the paramProperty and (optional) paramName attributes, optionally scoped by the paramScope + attribute. + </description> + </attribute> + <attribute> + <name>paramName</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if + paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if + paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, + if it is specified. If paramName is omitted, then it is assumed that the current object being iterated on is the + target bean. + </description> + </attribute> + <attribute> + <name>paramProperty</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + The name of a property of the current object being iterated on, whose return value will be used as the value of + the parameter (named by the paramId attribute) that will be dynamically added to this href URL. If paramName is + also specified the property will not be fetched from the object being iterated on, but from the bean specified + by paramName. The support of paramProperty in conjunction with paramName will be probably removed in future: use + paramProperty only if you need a property in the iterated object, elsewhere use only paramName (you can select a + property using an expression name.property). + </description> + </attribute> + <attribute> + <name>paramScope</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + @deprecated - use Expressions in paramName. The scope within which to search for the bean specified by the + paramName attribute. If not specified, all scopes are searched. If paramName is not provided, then the current + object being iterated on is assumed to be the target bean. + </description> + </attribute> + <attribute> + <name>maxLength</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>int</type> + <description> + If this attribute is provided, then the column's displayed is limited to this number of characters. An elipse + (...) is appended to the end if this column is linked, and the user can mouseover the elipse to get the full + text. Be careful on using this attribute for String which can contain html tags or entities, or together with + the autolink attribute turned on: displaytag will do its best trying to avoid leaving unclosed tags or broken + entities in the output, but a complex or bad input could lead to unattended results. + </description> + </attribute> + <attribute> + <name>maxWords</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>int</type> + <description> + If this attribute is provided, then the column's displayed is limited to this number of words. An elipse (...) + is appended to the end if this column is linked, and the user can mouseover the elipse to get the full text. Be + careful on using this attribute for String which can contain html tags or entities, or together with the + autolink attribute turned on: displaytag will do its best trying to avoid leaving unclosed tags or broken + entities in the output, but a complex or bad input could lead to unattended results. + </description> + </attribute> + <attribute> + <name>class</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + html pass through attribute; use this instead of directly coding presentational atttributes. + </description> + </attribute> + <attribute> + <name>headerClass</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description>"class" html attribute added only for header cells.</description> + </attribute> + <attribute> + <name>style</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description>html pass through attribute.</description> + </attribute> + <attribute> + <name>group</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>int</type> + <description> + The grouping level (starting at 1 and incrementing) of this column (indicates if successive contain the same + values, then they should not be displayed). The level indicates that if a lower level no longer matches, then + the matching for this higher level should start over as well. If this attribute is not included, then no + grouping is performed. + </description> + </attribute> + <attribute> + <name>decorator</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + Whitespace separated list of column decorators to apply to the current column. A table decorator name can be the + name of an object in page, request, session or application scope or a fully qualified class name of a class + implementing the org.displaytag.decorator.DisplaytagColumnDecorator interface. If a decorator is specified for + the entire table, then this decorator will decorate that decorator. + </description> + </attribute> + <attribute> + <name>sortName</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description> + Used with sort="external", the name that should be given to the server to sort this column. IE if + sortName="buzz", then the href for this column to sort will have a parameter d-(encodedId)-s=buzz. If sortName + is ommitted the value for the sort param will default to the column number. + </description> + </attribute> + <attribute> + <name>headerScope</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description>"scope" html attribute added only for header cells.</description> + </attribute> + <attribute> + <name>scope</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.String</type> + <description>"scope" html attribute.</description> + </attribute> + <attribute> + <name>value</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <type>java.lang.Object</type> + <description> + Static value to be used for the column. It has the same meaning of setting a value in the tag body, but values + set using this attribute will not be coerced to Strings. You may need to use the value attribute instead of a + scriptlet in the tag body if you need to calculate totals on numeric values. + </description> + </attribute> + </tag> + +</taglib> Modified: teamware/trunk/executive/web/common/taglibs.jsp =================================================================== --- teamware/trunk/executive/web/common/taglibs.jsp 2018-11-23 12:23:04 UTC (rev 20321) +++ teamware/trunk/executive/web/common/taglibs.jsp 2018-11-27 15:49:02 UTC (rev 20322) @@ -24,6 +24,7 @@ <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%> <%@ taglib uri="/WEB-INF/executive.tld" prefix="executive" %> +<%@ taglib uri="/WEB-INF/tw-display.tld" prefix="tw-display" %> <%-- Set all pages that include this page to use XHTML --%> <%-- Using this Struts html tag in a page tells all other html taglib tags to render themselves as XHTML 1.0. Modified: teamware/trunk/executive/web/pages/corpusList.jsp =================================================================== --- teamware/trunk/executive/web/pages/corpusList.jsp 2018-11-23 12:23:04 UTC (rev 20321) +++ teamware/trunk/executive/web/pages/corpusList.jsp 2018-11-27 15:49:02 UTC (rev 20322) @@ -58,7 +58,12 @@ <display:column style="width: 3%" property="startProjectLink" title="" media="html"/> </authz:authorize> <display:column style="width: 3%" media="html"> - <a id="<c:out value="annic${corpusList.corpusName}"/>" href="<c:url value="/annicgui.html?docservice-url=${docServiceURL}&corpus-id=${corpusList.corpusID}&autoconnect=true"/>"> + <c:url var="annicLink" value="${jnlpUrlBase}${pageContext.request.contextPath}/annicgui.html;jsessionid=${pageContext.session.id}"> + <c:param name="docservice-url" value="${docServiceURL}" /> + <c:param name="corpus-id" value="${corpusList.corpusID}" /> + <c:param name="autoconnect" value="true" /> + </c:url> + <a id="<c:out value="annic${corpusList.corpusName}"/>" href="<c:out value="${annicLink}"/>"> <img src="<c:url value="/images/annic.png"/>" onmouseover="ajax_showTooltip('ajaxtooltip/info/annicSearch.jsp',this);return false" onmouseout="ajax_hideTooltip()" class="icon" /> </a> </display:column> Modified: teamware/trunk/executive/web/pages/documentList.jsp =================================================================== --- teamware/trunk/executive/web/pages/documentList.jsp 2018-11-23 12:23:04 UTC (rev 20321) +++ teamware/trunk/executive/web/pages/documentList.jsp 2018-11-27 15:49:02 UTC (rev 20322) @@ -34,13 +34,14 @@ <display:column style="width: 65%" property="documentName" sortable="true" headerClass="sortable" titleKey="documentForm.documentName"/> - <display:column style="width: 5%" url="/viewDocument.html" paramId="documentId" paramProperty="documentID" media="html"> + <%-- Use jnlpColumn to make the wrapper URLs be jnlp: rather than http: --%> + <tw-display:jnlpColumn style="width: 5%" url="/viewDocument.html" paramId="documentId" paramProperty="documentID" media="html"> <img src="<c:url value="/images/view.gif"/>" onmouseover="ajax_showTooltip('ajaxtooltip/info/viewDocument.jsp',this);return false" onmouseout="ajax_hideTooltip()" class="icon" /> - </display:column> + </tw-display:jnlpColumn> - <display:column style="width: 5%" media="html" url="/viewDocument.html?method=diff" paramId="documentId" paramProperty="documentID"> + <tw-display:jnlpColumn style="width: 5%" media="html" url="/viewDocument.html?method=diff" paramId="documentId" paramProperty="documentID"> <img src="<c:url value="/images/annDiff.png"/>" onmouseover="ajax_showTooltip('ajaxtooltip/info/annoDiff.jsp',this);return false" onmouseout="ajax_hideTooltip()" class="icon" /> - </display:column> + </tw-display:jnlpColumn> <display:column style="width: 5%" media="html"> <a href="<c:url value="/caculateIAA.html?method=searchAnnSetNames&show=false&corpusID=${param.corpusID}&corpusName=${param.corpusName}&documentID=${documentList.documentID}&documentName=${documentList.documentName}"/>"> <img src="<c:url value="/images/view_completed.gif"/>" onmouseover="ajax_showTooltip('ajaxtooltip/info/iaa.jsp',this);return false" onmouseout="ajax_hideTooltip()" class="icon"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ GATE-cvs mailing list GATE-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gate-cvs