Index: lams_common/src/java/org/lamsfoundation/lams/tool/SimpleURL.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_common/src/java/org/lamsfoundation/lams/tool/SimpleURL.java (.../SimpleURL.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_common/src/java/org/lamsfoundation/lams/tool/SimpleURL.java (.../SimpleURL.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -53,4 +53,4 @@ public void setNameToDisplay(String nameToDisplay) { this.nameToDisplay = nameToDisplay; } -} +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/web/util/AttributeNames.java =================================================================== diff -u -r4f33380083bd35fd6d0851de9def290c62ffc3c9 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_common/src/java/org/lamsfoundation/lams/web/util/AttributeNames.java (.../AttributeNames.java) (revision 4f33380083bd35fd6d0851de9def290c62ffc3c9) +++ lams_common/src/java/org/lamsfoundation/lams/web/util/AttributeNames.java (.../AttributeNames.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -93,4 +93,5 @@ public static final String ATTR_PAGE_STR = "pageString"; public static final String ATTR_DO_NOT_SHOW_AGAIN = "doNotShowAgain"; public static final String ATTR_SHOW_TUTORIAL = "showTutorial"; + public static final String PARAM_TOOL_CONTENT_HANDLER_NAME = "toolContentHandler"; } \ No newline at end of file Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java =================================================================== diff -u -r1def3fbfd260882b596d17fa62d8cd57b50ee530 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 1def3fbfd260882b596d17fa62d8cd57b50ee530) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -21,7 +21,7 @@ * **************************************************************** */ -/* $$Id$$ */ +/* $$Id$$ */ package org.lamsfoundation.lams.contentrepository.client; import java.io.BufferedInputStream; @@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.contentrepository.FileException; import org.lamsfoundation.lams.contentrepository.ITicket; @@ -45,339 +46,336 @@ import org.lamsfoundation.lams.contentrepository.ValueFormatException; import org.lamsfoundation.lams.contentrepository.service.IRepositoryService; import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; - /** - * This is a specialised servlet that supports the downloading of single - * files and the rendering of packages. + * This is a specialised servlet that supports the downloading of single files and the rendering of packages. *

- * It has a rather odd format - you can call it initially with - * the file/package uuid (and optional version and preferDownload parameters) using
+ * It has a rather odd format - you can call it initially with the file/package uuid (and optional version and + * preferDownload parameters) using
* download?uuid=<uuid>&version=<version>&preferDownload=[true|false]. *

- * If it is a file, then the file is downloaded. If it is a package, then - * it redirects to download/<uuid>/<version>/relPath?preferDownload=false - * where the <uuid> and <version> are the uuid and version - * of the package node. + * If it is a file, then the file is downloaded. If it is a package, then it redirects to + * download/<uuid>/<version>/relPath?preferDownload=false where the <uuid> and <version> are the + * uuid and version of the package node. *

- * The download/<uuid>/<version>/relPath should only be used - * internally - the servlet should be called with the parameter - * version initially. + * The download/<uuid>/<version>/relPath should only be used internally - the servlet should be called with + * the parameter version initially. *

- * This / format allows the relative pathed links - * within an html file to work properly. + * This / format allows the relative pathed links within an html file to work properly. *

- * If you want to try to download the file rather than display the file, - * add the parameter preferDownload=true to the url. This is only meaningful - * for a file - it is ignored for packages. + * If you want to try to download the file rather than display the file, add the parameter preferDownload=true to the + * url. This is only meaningful for a file - it is ignored for packages. *

- * This is an abstract class, to allow other modules to customise the - * repository access. To implement, you must implement getTicket() - * and getRepositoryService(). If you are using ToolContentHandler, - * then you can use ToolDownload, which is a concrete implementation - * of this class using the ToolContentHandler. - * + * This is an abstract class, to allow other modules to customise the repository access. To implement, you must + * implement getTicket() and getRepositoryService(). If you are using ToolContentHandler, then you can use ToolDownload, + * which is a concrete implementation of this class using the ToolContentHandler. + * * @author Fiona Malikoff * @see org.lamsfoundation.lams.contentrepository.client.ToolDownload */ -/* A package node could be handled by either getting the - stream from the package node - this is the first file - in the package - or by using the property in the node - that specifies the path to the first file and go back - to the repository and get that node. In a roundabout - way, this servlet uses the second method - it redirects - to the path for the first file. - - method 1: the package node returns a stream which is the first file. - InputStream = node.getFile(); - set up any header variables - +/* + * A package node could be handled by either getting the stream from the package node - this is the first file in the + * package - or by using the property in the node that specifies the path to the first file and go back to the + * repository and get that node. In a roundabout way, this servlet uses the second method - it redirects to the path for + * the first file. + * + * method 1: the package node returns a stream which is the first file. InputStream = node.getFile(); set up any header + * variables + * + * method 2: get initial path node and download that IValue value = node.getProperty(PropertyName.INITIALPATH); String + * initialPath = value != null ? value.getString() : null; IVersionedNode childNode = + * getRepository().getFileItem(ticket,uuid, initialPath, null); InputStream = node.getFile(); + */ - method 2: get initial path node and download that - IValue value = node.getProperty(PropertyName.INITIALPATH); - String initialPath = value != null ? value.getString() : null; - IVersionedNode childNode = getRepository().getFileItem(ticket,uuid, initialPath, null); - InputStream = node.getFile(); - - -*/ - public abstract class Download extends HttpServlet { - public static final String UUID_NAME = "uuid"; - public static final String VERSION_NAME = "version"; - public static final String PREFER_DOWNLOAD = "preferDownload"; + public static final String UUID_NAME = "uuid"; + public static final String VERSION_NAME = "version"; + public static final String PREFER_DOWNLOAD = "preferDownload"; + protected static Logger log = Logger.getLogger(Download.class); - protected static Logger log = Logger.getLogger(Download.class); + private static final String expectedFormat = "Expected format /download?" + Download.UUID_NAME + "&" + + Download.VERSION_NAME + "=" + Download.PREFER_DOWNLOAD + + "= (version number optional) or /download///"; - private static final String expectedFormat = - "Expected format /download?" - +UUID_NAME - +"&" - +VERSION_NAME - +"=" - +PREFER_DOWNLOAD - +"= (version number optional) or /download///"; + /** + * Get the ticket that may be used to access the repository. + */ + public abstract ITicket getTicket() throws RepositoryCheckedException; - /** Get the ticket that may be used to access the repository. -*/ - public abstract ITicket getTicket() throws RepositoryCheckedException; - public abstract IRepositoryService getRepositoryService() throws RepositoryCheckedException; + public abstract ITicket getTicket(String source) throws RepositoryCheckedException; - /** - * The doGet method of the servlet.
- * - * This method is called when a form has its tag value method equals to get. - * - * @param request the request send by the client to the server - * @param response the response send by the server to the client - * @throws ServletException if an error occurred - * @throws IOException if an error occurred - */ - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + public abstract IRepositoryService getRepositoryService() throws RepositoryCheckedException; - try { - handleCall(request, response); - } catch (RepositoryCheckedException e) { - log.error("Exception occured in download. Exception "+e.getMessage() - +"Request URL was "+request.getRequestURL(),e); - throw new ServletException(e); - } + /** + * The doGet method of the servlet.
+ * + * This method is called when a form has its tag value method equals to get. + * + * @param request + * the request send by the client to the server + * @param response + * the response send by the server to the client + * @throws ServletException + * if an error occurred + * @throws IOException + * if an error occurred + */ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + try { + handleCall(request, response); + } catch (RepositoryCheckedException e) { + Download.log.error("Exception occured in download. Exception " + e.getMessage() + "Request URL was " + + request.getRequestURL(), e); + throw new ServletException(e); } + } - private void handleCall(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException, RepositoryCheckedException { - - long start = System.currentTimeMillis(); + private void handleCall(HttpServletRequest request, HttpServletResponse response) throws ServletException, + IOException, RepositoryCheckedException { - ITicket ticket = getTicket(); - if ( ticket == null ) { - throw new RepositoryCheckedException("Unable to get ticket - getTicket(false) returned null"); - } + long start = System.currentTimeMillis(); - Long uuid = getLong(request.getParameter(UUID_NAME)); - Long version = null; - boolean saveFile = getBoolean(request.getParameter(PREFER_DOWNLOAD)); + ITicket ticket = null; + String toolContentHandlerName = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME); + if (StringUtils.isBlank(toolContentHandlerName)) { + ticket = getTicket(); + } else { + ticket = getTicket(toolContentHandlerName); + } - String callId = null; + if (ticket == null) { + throw new RepositoryCheckedException("Unable to get ticket - getTicket(false) returned null"); + } - if ( uuid != null ) { + Long uuid = getLong(request.getParameter(Download.UUID_NAME)); + Long version = null; + boolean saveFile = getBoolean(request.getParameter(Download.PREFER_DOWNLOAD)); - version = getLong(request.getParameter(VERSION_NAME)); - - IVersionedNode node = getFileItem(ticket, uuid, version,null); - - // update versionId in case it was null and we got the latest version... - version = node.getVersion(); - - if ( node.isNodeType(NodeType.PACKAGENODE) ) { - - // now get the path of the initial page in the package - IValue value = node.getProperty(PropertyName.INITIALPATH); - String initialPage = value != null ? value.getString() : null; - if ( initialPage == null || initialPage.length() ==0 ) { - throw new RepositoryCheckedException("No initial page found for this set of content. Node Data is "+node.toString()); - } + String callId = null; - // redirect to the initial path - // prepend with servlet and id - initial call doesn't include the id - // and depending on "/"s, the servlet name is sometimes lost by the redirect. - // make sure it displays the file - rather than trying to download it. - initialPage = request.getRequestURL() + "/" + uuid - + "/" + version + "/" + initialPage+"?preferDownload=false"; - log.debug("Attempting to redirect to initial page "+initialPage); - response.sendRedirect(initialPage); - - } else if ( node.isNodeType(NodeType.FILENODE) ) { + if (uuid != null) { - handleFileNode(response, request, node, saveFile); + version = getLong(request.getParameter(Download.VERSION_NAME)); - } else { - throw new RepositoryCheckedException("Unsupported node type " - +node.getNodeType()+". Node Data is "+node.toString(),null); - } - - } else { - - // using the /download// format - must be a file node! - String pathString = request.getPathInfo(); - String[] strings = deriveIdFile(pathString); - uuid = getLong(strings[0]); - version = getLong(strings[1]); - String relPathString = strings[2]; - - callId = "download "+Math.random()+" "+uuid; - - if ( uuid == null ) { - throw new RepositoryCheckedException("UUID value is missing. "+expectedFormat); - } - - if ( version == null ) { - throw new RepositoryCheckedException("Version value is missing. "+expectedFormat); - } + IVersionedNode node = getFileItem(ticket, uuid, version, null); - if ( relPathString == null ) { - throw new RepositoryCheckedException("Filename is missing. "+expectedFormat); - } + // update versionId in case it was null and we got the latest version... + version = node.getVersion(); - IVersionedNode node = getFileItem(ticket, uuid, version, relPathString); - if ( ! node.isNodeType(NodeType.FILENODE) ) { - throw new RepositoryCheckedException("Unexpected type of node " - +node.getNodeType()+" Expected File node. Data is "+node); - } - handleFileNode(response, request, node, saveFile); + if (node.isNodeType(NodeType.PACKAGENODE)) { + // now get the path of the initial page in the package + IValue value = node.getProperty(PropertyName.INITIALPATH); + String initialPage = value != null ? value.getString() : null; + if (initialPage == null || initialPage.length() == 0) { + throw new RepositoryCheckedException("No initial page found for this set of content. Node Data is " + + node.toString()); } + + // redirect to the initial path + // prepend with servlet and id - initial call doesn't include the id + // and depending on "/"s, the servlet name is sometimes lost by the redirect. + // make sure it displays the file - rather than trying to download it. + initialPage = request.getRequestURL() + "/" + uuid + "/" + version + "/" + initialPage + + "?preferDownload=false"; + Download.log.debug("Attempting to redirect to initial page " + initialPage); + response.sendRedirect(initialPage); + + } else if (node.isNodeType(NodeType.FILENODE)) { + + handleFileNode(response, request, node, saveFile); + + } else { + throw new RepositoryCheckedException("Unsupported node type " + node.getNodeType() + ". Node Data is " + + node.toString(), null); + } + + } else { + + // using the /download// format - must be a file node! + String pathString = request.getPathInfo(); + String[] strings = deriveIdFile(pathString); + uuid = getLong(strings[0]); + version = getLong(strings[1]); + String relPathString = strings[2]; + + callId = "download " + Math.random() + " " + uuid; + + if (uuid == null) { + throw new RepositoryCheckedException("UUID value is missing. " + Download.expectedFormat); + } + + if (version == null) { + throw new RepositoryCheckedException("Version value is missing. " + Download.expectedFormat); + } + + if (relPathString == null) { + throw new RepositoryCheckedException("Filename is missing. " + Download.expectedFormat); + } + + IVersionedNode node = getFileItem(ticket, uuid, version, relPathString); + if (!node.isNodeType(NodeType.FILENODE)) { + throw new RepositoryCheckedException("Unexpected type of node " + node.getNodeType() + + " Expected File node. Data is " + node); + } + handleFileNode(response, request, node, saveFile); + } + } - /** - * The call getFileItem was throwing a runtime hibernate/jdbc error when being - * thrash tested, and I couldn't work out the context, so I've wrapped - * the call here so it can be debugged. - */ - private IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version, String relPathString) - throws RepositoryCheckedException { - try { - IVersionedNode node = null; - if ( relPathString != null ) { - // get file in package - node = getRepositoryService().getFileItem(ticket,uuid, version, relPathString); - } else { - // get node - node = getRepositoryService().getFileItem(ticket,uuid, version); - } - return node; - } catch ( RuntimeException e ) { - log.error("Exception thrown calling repository.getFileItem(," - +uuid+","+version+","+relPathString+"). "+e.getMessage(), e); - throw e; - } + /** + * The call getFileItem was throwing a runtime hibernate/jdbc error when being thrash tested, and I couldn't work + * out the context, so I've wrapped the call here so it can be debugged. + */ + private IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version, String relPathString) + throws RepositoryCheckedException { + try { + IVersionedNode node = null; + if (relPathString != null) { + // get file in package + node = getRepositoryService().getFileItem(ticket, uuid, version, relPathString); + } else { + // get node + node = getRepositoryService().getFileItem(ticket, uuid, version); + } + return node; + } catch (RuntimeException e) { + Download.log.error("Exception thrown calling repository.getFileItem(," + uuid + "," + version + "," + + relPathString + "). " + e.getMessage(), e); + throw e; } + } - /** - * @param response - * @param aNode - * @throws IOException - */ - protected void handleFileNode(HttpServletResponse response, HttpServletRequest request, IVersionedNode fileNode, boolean saveFile) - throws IOException, FileException, ValueFormatException { + /** + * @param response + * @param aNode + * @throws IOException + */ + protected void handleFileNode(HttpServletResponse response, HttpServletRequest request, IVersionedNode fileNode, + boolean saveFile) throws IOException, FileException, ValueFormatException { - // Try to get the mime type and set the response content type. - // Use the mime type was saved with the file, - // the type set up in the server (e.g. tomcat's config) or failing - // that, make it a octet stream. - IValue prop = fileNode.getProperty(PropertyName.MIMETYPE); - String mimeType = prop != null ? prop.getString() : null; - if ( mimeType == null ) { - prop = fileNode.getProperty(PropertyName.FILENAME); - if ( prop != null ) { - mimeType = getServletContext().getMimeType(prop.getString()); - } - } - if (mimeType == null) { - mimeType = "application/octet-stream"; - } - response.setContentType(mimeType); - - // Get the filename stored with the file - prop = fileNode.getProperty(PropertyName.FILENAME); - String filename = prop != null ? prop.getString() : null; - filename = FileUtil.encodeFilenameForDownload(request, filename); - - log.debug("Downloading file " + filename + " mime type " + mimeType); + // Try to get the mime type and set the response content type. + // Use the mime type was saved with the file, + // the type set up in the server (e.g. tomcat's config) or failing + // that, make it a octet stream. + IValue prop = fileNode.getProperty(PropertyName.MIMETYPE); + String mimeType = prop != null ? prop.getString() : null; + if (mimeType == null) { + prop = fileNode.getProperty(PropertyName.FILENAME); + if (prop != null) { + mimeType = getServletContext().getMimeType(prop.getString()); + } + } + if (mimeType == null) { + mimeType = "application/octet-stream"; + } + response.setContentType(mimeType); - if (saveFile) { - log.debug("Sending as attachment"); - response.setHeader("Content-Disposition","attachment;filename=\"" + filename+"\""); - } else { - log.debug("Sending as inline"); - response.setHeader("Content-Disposition","inline;filename=\"" + filename+"\""); + // Get the filename stored with the file + prop = fileNode.getProperty(PropertyName.FILENAME); + String filename = prop != null ? prop.getString() : null; + filename = FileUtil.encodeFilenameForDownload(request, filename); + + Download.log.debug("Downloading file " + filename + " mime type " + mimeType); + + if (saveFile) { + Download.log.debug("Sending as attachment"); + response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\""); + } else { + Download.log.debug("Sending as inline"); + response.setHeader("Content-Disposition", "inline;filename=\"" + filename + "\""); + } + response.setHeader("Cache-control", "must-revalidate"); + if (filename != null) { + response.addHeader("Content-Description", filename); + } + + InputStream in = new BufferedInputStream(fileNode.getFile()); + OutputStream out = response.getOutputStream(); + try { + int count = 0; + + int ch; + while ((ch = in.read()) != -1) { + out.write((char) ch); + count++; + } + Download.log.debug("Wrote out " + count + " bytes"); + response.setContentLength(count); + out.flush(); + } catch (IOException e) { + Download.log.error("Exception occured writing out file:" + e.getMessage()); + throw e; + } finally { + try { + if (in != null) { + in.close(); // very important } - response.setHeader("Cache-control","must-revalidate"); - if ( filename != null ) { - response.addHeader("Content-Description", filename); + if (out != null) { + out.close(); } - - InputStream in = new BufferedInputStream(fileNode.getFile()); - OutputStream out = response.getOutputStream(); - try { - int count = 0; - - int ch; - while ((ch = in.read()) != -1) - { - out.write((char) ch); - count++; - } - log.debug("Wrote out " + count + " bytes"); - response.setContentLength(count); - out.flush(); - } catch (IOException e) { - log.error( "Exception occured writing out file:" + e.getMessage()); - throw e; - } finally { - try { - if (in != null) in.close(); // very important - if (out != null) out.close(); - } - catch (IOException e) { - log.error("Error Closing file. File already written out - no exception being thrown.",e); - } - } + } catch (IOException e) { + Download.log.error("Error Closing file. File already written out - no exception being thrown.", e); + } } - - // Expect format ///. No parts are optional. Filename may be a path. - // returns an array of three strings. - private String[] deriveIdFile(String pathInfo) { - String[] result = new String[3]; - - if ( pathInfo != null ) { - - String[] strings = pathInfo.split("/",4); - - for ( int i=0, j=0; i 0 ) { - result[j++] = strings[i]; - } - } - - } - log.debug("Split path into following strings: '" - +result[0] - +"' '"+result[1] - +"' '"+result[2]); + } - return result; - } - + // Expect format ///. No parts are optional. Filename may be a path. + // returns an array of three strings. + private String[] deriveIdFile(String pathInfo) { + String[] result = new String[3]; - /** - * The doPost method of the servlet.
- * - * This method is called when a form has its tag value method equals to post. - * - * @param request the request send by the client to the server - * @param response the response send by the server to the client - * @throws ServletException if an error occurred - * @throws IOException if an error occurred - */ - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doGet(request, response); - } + if (pathInfo != null) { - protected static Long getLong(String longAsString) { - try { - return new Long(longAsString); - } catch ( NumberFormatException e ) { - return null; + String[] strings = pathInfo.split("/", 4); + + for (int i = 0, j = 0; i < strings.length && j < 3; i++) { + // splitting sometimes results in empty strings, so skip them! + if (strings[i].length() > 0) { + result[j++] = strings[i]; } + } + } + Download.log.debug("Split path into following strings: '" + result[0] + "' '" + result[1] + "' '" + result[2]); - protected static boolean getBoolean(String booleanAsString) { - return Boolean.valueOf(booleanAsString).booleanValue(); + return result; + } + + /** + * The doPost method of the servlet.
+ * + * This method is called when a form has its tag value method equals to post. + * + * @param request + * the request send by the client to the server + * @param response + * the response send by the server to the client + * @throws ServletException + * if an error occurred + * @throws IOException + * if an error occurred + */ + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + doGet(request, response); + } + + protected static Long getLong(String longAsString) { + try { + return new Long(longAsString); + } catch (NumberFormatException e) { + return null; } + } + + protected static boolean getBoolean(String booleanAsString) { + return Boolean.valueOf(booleanAsString).booleanValue(); + } } Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolDownload.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolDownload.java (.../ToolDownload.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolDownload.java (.../ToolDownload.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -21,35 +21,31 @@ * **************************************************************** */ -/* $$Id$$ */ +/* $$Id$$ */ package org.lamsfoundation.lams.contentrepository.client; -import javax.servlet.ServletConfig; - import org.lamsfoundation.lams.contentrepository.ITicket; import org.lamsfoundation.lams.contentrepository.RepositoryCheckedException; import org.lamsfoundation.lams.contentrepository.service.IRepositoryService; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; /** - * Implements the Download servlet, using the ToolContentHandler - * to manage the connection to the repository. + * Implements the Download servlet, using the ToolContentHandler to manage the connection to the repository. *

- * Tool's can use this class "as is" to download single files - * previously saved in the content repository. + * Tool's can use this class "as is" to download single files previously saved in the content repository. *

- * The servlet accesses the content repository via a tool's ToolContentHandler - * implementation. It looks for the bean that implements IToolContentHandler - * in the web based Spring context. The name of the bean is specified - * using the "toolContentHandlerBeanName" parameter in the servlet definition - * in web.xml. + * The servlet accesses the content repository via a tool's ToolContentHandler implementation. It looks for the bean + * that implements IToolContentHandler in the web based Spring context. The name of the bean is specified using the + * "toolContentHandlerBeanName" parameter in the servlet definition in web.xml. * - * If you do not have a ToolContentHandler implementation then this servlet will not work. - * If you need to set up the content repository access differently to the implementation - * in the Tool Content Handler, then derive a new concrete class from the Download servlet. + * If you do not have a ToolContentHandler implementation then this servlet will not work. If you need to set up the + * content repository access differently to the implementation in the Tool Content Handler, then derive a new concrete + * class from the Download servlet. *

- * Sample servlet definition:

+ * Sample servlet definition:
+ * + *
  *  <servlet>
  *      <description>Noticeboard Instructions Download</description>
  *      <display-name>Noticeboard Instructions Download</display-name>
@@ -62,15 +58,21 @@
  *      <load-on-startup>3</load-on-startup>
  *  </servlet>
  * 
+ * *

- * Sample mapping definition:

+ * Sample mapping definition:
+ * + *
  * 	<servlet-mapping>
- *		<servlet-name>download</servlet-name>
- *		<url-pattern>/download/*</url-pattern>
+ * 	<servlet-name>download</servlet-name>
+ * 	<url-pattern>/download/*</url-pattern>
  * 	</servlet-mapping>
  * 
+ * *

- * Sample HTML calls:

+ * Sample HTML calls:
+ * + *
  *  <table>
  *  <tr>
  *   <td>Filename</td>
@@ -79,19 +81,19 @@
  *  </tr>
  *  <tr>
  *   <td>SomeFile.jpg</td>
- *   <td><a href='javascript:launchInstructionsPopup("/lams/tool/lafrum11/download/?uuid=19&preferDownload=false")' class="button">View</a></td>
- *   <td><a href="/lams/tool/lafrum11/download/?uuid=19&preferDownload=true">Download</a></td>
+ *   <td><a href='javascript:launchInstructionsPopup("/lams/tool/lafrum11/download/?uuid=19&preferDownload=false")' class="button">View</a></td>
+ *   <td><a href="/lams/tool/lafrum11/download/?uuid=19&preferDownload=true">Download</a></td>
  *  </tr>
  * 
+ * *

- * The launchInstructionsPopup() method is defined in common.js, available as http://.../lams/includes/javascript/common.js. + * The launchInstructionsPopup() method is defined in common.js, available as + * http://.../lams/includes/javascript/common.js. *

- * For an example of this servlet being used, have a look at the lams_tool_imscp project. - * The jsps/authoring/forum/instructions.jsp calls the servlet and includes/header.jsp - * loads the common.js file. + * For an example of this servlet being used, have a look at the lams_tool_imscp project. The + * jsps/authoring/forum/instructions.jsp calls the servlet and includes/header.jsp loads the common.js file. *

- * For more details on the request parameters recognised by the ToolDownload servlet, see - * the parent class (Download). + * For more details on the request parameters recognised by the ToolDownload servlet, see the parent class (Download). * * @author Fiona Malikoff * @see org.lamsfoundation.lams.contentrepository.client.IToolContentHandler @@ -102,37 +104,51 @@ /** The name of the servlet parameter used to define the implementation bean name */ public final static String TOOL_CONTENT_HANDLER_BEAN_NAME = "toolContentHandlerBeanName"; - - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.lamsfoundation.lams.contentrepository.client.Download#getTicket() */ + @Override public ITicket getTicket() throws RepositoryCheckedException { - IToolContentHandler toolContentHandler = getToolContentHandler(); // make sure it is set up - return toolContentHandler != null ? toolContentHandler.getTicket(false):null; + IToolContentHandler toolContentHandler = getToolContentHandler(); // make sure it is set up + return toolContentHandler != null ? toolContentHandler.getTicket(false) : null; } - /* (non-Javadoc) + @Override + public ITicket getTicket(String toolContentHandlerName) throws RepositoryCheckedException { + IToolContentHandler toolContentHandler = getToolContentHandler(toolContentHandlerName); // make sure it is set + // up + return toolContentHandler != null ? toolContentHandler.getTicket(false) : null; + } + + /* + * (non-Javadoc) + * * @see org.lamsfoundation.lams.contentrepository.client.Download#getRepositoryService() */ + @Override public IRepositoryService getRepositoryService() throws RepositoryCheckedException { - IToolContentHandler toolContentHandler = getToolContentHandler(); // make sure it is set up - return toolContentHandler != null? toolContentHandler.getRepositoryService() : null; + IToolContentHandler toolContentHandler = getToolContentHandler(); // make sure it is set up + return toolContentHandler != null ? toolContentHandler.getRepositoryService() : null; } - + protected IToolContentHandler getToolContentHandler() { - - log.debug("ToolDownload servlet calling context and getting repository singleton."); - - String toolContentHandlerBeanName = getInitParameter(TOOL_CONTENT_HANDLER_BEAN_NAME); - if ( toolContentHandlerBeanName == null ) { - log.error("Accessing Download servlet but tool content handler bean has not been defined. Please define init parameter" - +TOOL_CONTENT_HANDLER_BEAN_NAME+"."); - return null; - } - - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - return (IToolContentHandler)wac.getBean(toolContentHandlerBeanName); - } + Download.log.debug("ToolDownload servlet calling context and getting repository singleton."); -} + String toolContentHandlerBeanName = getInitParameter(ToolDownload.TOOL_CONTENT_HANDLER_BEAN_NAME); + if (toolContentHandlerBeanName == null) { + Download.log + .error("Accessing Download servlet but tool content handler bean has not been defined. Please define init parameter" + + ToolDownload.TOOL_CONTENT_HANDLER_BEAN_NAME + "."); + return null; + } + return getToolContentHandler(toolContentHandlerBeanName); + } + + protected IToolContentHandler getToolContentHandler(String toolContentHandlerName) { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); + return (IToolContentHandler) wac.getBean(toolContentHandlerName); + } +} \ No newline at end of file Index: lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryOutputFactory.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryOutputFactory.java (.../ImageGalleryOutputFactory.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryOutputFactory.java (.../ImageGalleryOutputFactory.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -34,13 +34,15 @@ import org.lamsfoundation.lams.tool.SimpleURL; import org.lamsfoundation.lams.tool.ToolOutput; import org.lamsfoundation.lams.tool.ToolOutputDefinition; +import org.lamsfoundation.lams.tool.imageGallery.ImageGalleryConstants; import org.lamsfoundation.lams.tool.imageGallery.model.ImageComment; import org.lamsfoundation.lams.tool.imageGallery.model.ImageGallery; import org.lamsfoundation.lams.tool.imageGallery.model.ImageGalleryItem; import org.lamsfoundation.lams.tool.imageGallery.model.ImageGallerySession; import org.lamsfoundation.lams.tool.imageGallery.model.ImageGalleryUser; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.web.util.AttributeNames; public class ImageGalleryOutputFactory extends OutputFactory { @@ -144,11 +146,13 @@ for (ImageGalleryItem image : sessionImages) { if (!image.isCreateByAuthor()) { String serverUrl = Configuration.get(ConfigurationKeys.SERVER_URL); - String imageUrl = "javascript:var dummy = window.open('" + serverUrl + "download/?uuid=" - + image.getOriginalFileUuid() + "&preferDownload=false','" + image.getTitle() - + "','resizable,width=" + image.getOriginalImageWidth() + ",height=" - + image.getOriginalImageHeight() + ",scrollbars')"; - SimpleURL simpleUrl = new SimpleURL(image.getTitle(), imageUrl); + String innerUrl = serverUrl + "download/?uuid=" + image.getOriginalFileUuid() + + "&preferDownload=false&" + AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME + "=" + + ImageGalleryConstants.TOOL_CONTENT_HANDLER_NAME; + String fullUrl = "javascript:var dummy = window.open('" + innerUrl + "','" + + image.getTitle() + "','resizable,width=" + image.getOriginalImageWidth() + + ",height=" + image.getOriginalImageHeight() + ",scrollbars')"; + SimpleURL simpleUrl = new SimpleURL(image.getTitle(), fullUrl); uploadedImagesUrls.add(simpleUrl); } } Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceOutputFactory.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceOutputFactory.java (.../ResourceOutputFactory.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceOutputFactory.java (.../ResourceOutputFactory.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -37,6 +37,7 @@ import org.lamsfoundation.lams.tool.rsrc.model.ResourceItem; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.web.util.AttributeNames; public class ResourceOutputFactory extends OutputFactory { @@ -111,7 +112,8 @@ String path = uploadedItem.getUrl(); if (path == null) { path = serverUrl + "download/?uuid=" + uploadedItem.getFileUuid() - + "&preferDownload=false'"; + + "&preferDownload=false&" + AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME + + "=" + ResourceConstants.TOOL_CONTENT_HANDLER_NAME; } path = "javascript:var dummy = window.open('" + path + "','" + uploadedItem.getTitle() Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/service/PixlrOutputFactory.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/service/PixlrOutputFactory.java (.../PixlrOutputFactory.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/service/PixlrOutputFactory.java (.../PixlrOutputFactory.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -23,7 +23,9 @@ /* $Id$ */ package org.lamsfoundation.lams.tool.pixlr.service; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -32,8 +34,8 @@ import org.lamsfoundation.lams.tool.ToolOutput; import org.lamsfoundation.lams.tool.ToolOutputDefinition; import org.lamsfoundation.lams.tool.exception.ToolException; -import org.lamsfoundation.lams.tool.pixlr.model.Pixlr; import org.lamsfoundation.lams.tool.pixlr.model.PixlrSession; +import org.lamsfoundation.lams.tool.pixlr.model.PixlrUser; import org.lamsfoundation.lams.tool.pixlr.util.PixlrConstants; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; @@ -58,7 +60,7 @@ break; case ToolOutputDefinition.DATA_OUTPUT_DEFINITION_TYPE_DATA_FLOW: ToolOutputDefinition imageUrlDefinition = buildComplexOutputDefinition( - PixlrConstants.IMAGE_URL_DEFINITION_NAME, SimpleURL.class); + PixlrConstants.IMAGE_URL_DEFINITION_NAME, SimpleURL[].class); definitionMap.put(PixlrConstants.IMAGE_URL_DEFINITION_NAME, imageUrlDefinition); break; } @@ -102,16 +104,25 @@ String[] nameParts = splitConditionName(name); if (PixlrConstants.IMAGE_URL_DEFINITION_NAME.equals(nameParts[0])) { PixlrSession session = pixlrService.getSessionBySessionId(toolSessionId); + if (session != null) { - Pixlr pixlr = session.getPixlr(); - String serverUrl = Configuration.get(ConfigurationKeys.SERVER_URL); - String imageUrl = "javascript:var dummy = window.open('" + serverUrl + "www/images/pixlr/" - + pixlr.getImageFileName() + "','" + pixlr.getTitle() + "','resizable,width=" - + pixlr.getImageWidth() + ",height=" + pixlr.getImageHeight() + ",scrollbars')"; + Set users = session.getPixlrUsers(); + Set urls = new HashSet(users.size()); + for (PixlrUser user : users) { + if (user.getImageFileName() != null) { + String serverUrl = Configuration.get(ConfigurationKeys.SERVER_URL); + String imageName = user.getLastName() + "_" + user.getFirstName(); + String imageUrl = "javascript:var dummy = window.open('" + serverUrl + "www/images/pixlr/" + + user.getImageFileName() + "','" + imageName + "','resizable,width=" + + user.getImageWidth() + ",height=" + user.getImageHeight() + ",scrollbars')"; - SimpleURL url = new SimpleURL(session.getPixlr().getImageFileName(), imageUrl); + SimpleURL url = new SimpleURL(imageName, imageUrl); + urls.add(url); + } + } + SimpleURL[] urlArray = urls.toArray(new SimpleURL[] {}); return new ToolOutput(PixlrConstants.IMAGE_URL_DEFINITION_NAME, getI18NText( - PixlrConstants.IMAGE_URL_DEFINITION_NAME, true), url, false); + PixlrConstants.IMAGE_URL_DEFINITION_NAME, true), urlArray, false); } } } Index: lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesOutputFactory.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesOutputFactory.java (.../SubmitFilesOutputFactory.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesOutputFactory.java (.../SubmitFilesOutputFactory.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -37,6 +37,7 @@ import org.lamsfoundation.lams.tool.sbmt.util.SbmtConstants; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.web.util.AttributeNames; public class SubmitFilesOutputFactory extends OutputFactory { @@ -111,7 +112,9 @@ int urlIndex = 0; for (FileDetailsDTO filesDetailsDTO : files) { String fileUrl = "javascript:var dummy = window.open('" + serverUrl + "download/?uuid=" - + filesDetailsDTO.getUuID() + "&preferDownload=false','" + + filesDetailsDTO.getUuID() + "&preferDownload=false&" + + AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME + "=" + + SbmtConstants.TOOL_CONTENT_HANDLER_NAME + "','" + filesDetailsDTO.getFileDescription() + "','resizable,scrollbars')"; SimpleURL url = new SimpleURL(filesDetailsDTO.getFileDescription(), fileUrl); Index: lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/util/SbmtConstants.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -r0deb16204d87ee066914a10b3b545cf25eb4d714 --- lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/util/SbmtConstants.java (.../SbmtConstants.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/util/SbmtConstants.java (.../SbmtConstants.java) (revision 0deb16204d87ee066914a10b3b545cf25eb4d714) @@ -33,6 +33,7 @@ public static final String AUTHORING_DTO = "authoring"; + public static final String TOOL_CONTENT_HANDLER_NAME = "sbmtToolContentHandler"; // public static final String TOOL_SESSION_ID = "toolSessionID"; // public static final String TOOL_CONTENT_ID = "toolContentID"; public static final String USER_ID = "userID";