From: Bruno Sinou Date: Wed, 7 May 2014 21:18:36 +0000 (+0000) Subject: Fix file download for rap. Add various links in the bundle detail editor. X-Git-Tag: argeo-slc-2.1.7~194 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=18458e0376be8f3c4e38d26c937112bdbda27617;p=gpl%2Fargeo-slc.git Fix file download for rap. Add various links in the bundle detail editor. git-svn-id: https://svn.argeo.org/slc/trunk@6967 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/plugins/org.argeo.slc.client.rap/META-INF/spring/commands.xml b/plugins/org.argeo.slc.client.rap/META-INF/spring/commands.xml index 78adfc6cd..f19c55103 100644 --- a/plugins/org.argeo.slc.client.rap/META-INF/spring/commands.xml +++ b/plugins/org.argeo.slc.client.rap/META-INF/spring/commands.xml @@ -5,15 +5,16 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> - - - + + + + + + + - - \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/rap/OpenJcrFileService.java b/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/rap/OpenJcrFileService.java index d64a10bb7..a4dfaf42c 100644 --- a/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/rap/OpenJcrFileService.java +++ b/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/rap/OpenJcrFileService.java @@ -14,86 +14,58 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; -import org.argeo.slc.repo.RepoService; import org.eclipse.rwt.RWT; import org.eclipse.rwt.service.IServiceHandler; -import org.eclipse.rwt.service.IServiceManager; /** - * Basic Default service handler that retrieves and launch download of a file - * stored in a JCR Repository + * Basic Default service handler that retrieves a file from a NT_FILE JCR node + * and launch the download. */ public class OpenJcrFileService implements IServiceHandler { - public final static String ID = SlcRapPlugin.PLUGIN_ID + ".openJcrFileService"; - - // use local node repo and repository factory to retrieve and log to - // relevant repository - public final static String PARAM_REPO_NODE_PATH = "param.repoNodePath"; - // use URI and repository factory to retrieve and ANONYMOUSLY log in - // relevant repository - public final static String PARAM_REPO_URI = "param.repoUri"; - public final static String PARAM_WORKSPACE_NAME = "param.workspaceName"; - public final static String PARAM_FILE_PATH = "param.filePath"; - - public final static String SCHEME_HOST_SEPARATOR = "://"; - /* DEPENDENCY INJECTION */ - private RepoService repoService; - - public OpenJcrFileService() { - } + final private Node fileNode; - public void init() { - IServiceManager manager = RWT.getServiceManager(); - manager.registerServiceHandler(ID, this); - } - - public void destroy() { - IServiceManager manager = RWT.getServiceManager(); - manager.unregisterServiceHandler(ID); + public OpenJcrFileService(Node fileNode) { + this.fileNode = fileNode; } public void service() throws IOException, ServletException { - String repoNodePath = RWT.getRequest().getParameter(PARAM_REPO_NODE_PATH); - String repoUri = RWT.getRequest().getParameter(PARAM_REPO_URI); - String wkspName = RWT.getRequest().getParameter(PARAM_WORKSPACE_NAME); - String filePath = RWT.getRequest().getParameter(PARAM_FILE_PATH); - // Get the file content - byte[] download = getFileAsByteArray(repoNodePath, repoUri, wkspName, - filePath); + byte[] download = getFileAsByteArray(); // Send the file in the response HttpServletResponse response = RWT.getResponse(); response.setContentType("application/octet-stream"); response.setContentLength(download.length); - String contentDisposition = "attachment; filename=\"" - + JcrUtils.lastPathElement(filePath) + "\""; + String contentDisposition = null; + try { + contentDisposition = "attachment; filename=\"" + + JcrUtils.lastPathElement(fileNode.getPath()) + "\""; + } catch (RepositoryException e) { + throw new SlcException("Error while getting file Path " + fileNode, + e); + } response.setHeader("Content-Disposition", contentDisposition); try { response.getOutputStream().write(download); } catch (IOException ioe) { - throw new SlcException("Error while writing the file " + filePath + throw new SlcException("Error while writing the file " + fileNode + " to the servlet response", ioe); } } - protected byte[] getFileAsByteArray(String repoNodePath, String repoUri, - String wkspName, String filePath) { + protected byte[] getFileAsByteArray() { + Session businessSession = null; try { - businessSession = repoService.getRemoteSession(repoNodePath, - repoUri, wkspName); - Node result = businessSession.getNode(filePath); - boolean isValid = true; Node child = null; - if (!result.isNodeType(NodeType.NT_FILE)) + if (!fileNode.isNodeType(NodeType.NT_FILE)) isValid = false; else { - child = result.getNode(Property.JCR_CONTENT); + child = fileNode.getNode(Property.JCR_CONTENT); if (!(child.isNodeType(NodeType.NT_RESOURCE) || child .hasProperty(Property.JCR_DATA))) isValid = false; @@ -101,7 +73,7 @@ public class OpenJcrFileService implements IServiceHandler { if (!isValid) return null; - + byte[] ba = null; InputStream fis = null; try { @@ -109,10 +81,8 @@ public class OpenJcrFileService implements IServiceHandler { .getBinary().getStream(); ba = IOUtils.toByteArray(fis); } catch (Exception e) { - throw new SlcException( - "Stream error while opening file " + filePath - + " from repo " + repoUri == null ? repoNodePath - : repoUri, e); + throw new SlcException("Stream error while opening file " + + fileNode, e); } finally { IOUtils.closeQuietly(fis); } @@ -120,16 +90,9 @@ public class OpenJcrFileService implements IServiceHandler { } catch (RepositoryException e) { throw new SlcException("Unexpected error while " - + "getting repoNode info for repoNode at path " - + repoNodePath, e); + + "opening file node " + fileNode, e); } finally { JcrUtils.logoutQuietly(businessSession); } } - - /* DEPENDENCY INJECTION */ - public void setRepoService(RepoService repoService) { - this.repoService = repoService; - } - } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/ui/specific/OpenJcrFile.java b/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/ui/specific/OpenJcrFile.java index 21ed8eb08..48a0d8297 100644 --- a/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/ui/specific/OpenJcrFile.java +++ b/plugins/org.argeo.slc.client.rap/src/main/java/org/argeo/slc/client/ui/specific/OpenJcrFile.java @@ -16,12 +16,12 @@ package org.argeo.slc.client.ui.specific; import java.net.URL; +import java.util.UUID; +import javax.jcr.Node; import javax.jcr.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; import org.argeo.slc.client.rap.OpenJcrFileService; import org.argeo.slc.client.rap.SlcRapPlugin; import org.argeo.slc.repo.RepoService; @@ -30,27 +30,30 @@ import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.rwt.RWT; import org.eclipse.rwt.service.IServiceHandler; +import org.eclipse.rwt.service.IServiceManager; import org.eclipse.ui.PlatformUI; /** * Rap specific command handler to open a file retrieved from a distant JCR - * Repository. It forwards the request to the correct service after encoding - * file name and path in the request URI. + * Repository. It creates and register a service instantiated with the + * corresponding JCR node, forwards the request, and un register the service on + * dispose * * This command and the corresponding service are specific for RAP version [1.3, * 2) */ public class OpenJcrFile extends AbstractHandler { - private final static Log log = LogFactory.getLog(OpenJcrFile.class); + // private final static Log log = LogFactory.getLog(OpenJcrFile.class); public final static String ID = SlcRapPlugin.PLUGIN_ID + ".openJcrFile"; - public final static String PARAM_REPO_NODE_PATH = OpenJcrFileService.PARAM_REPO_NODE_PATH; - public final static String PARAM_REPO_URI = OpenJcrFileService.PARAM_REPO_URI; - public final static String PARAM_WORKSPACE_NAME = OpenJcrFileService.PARAM_WORKSPACE_NAME; - public final static String PARAM_FILE_PATH = OpenJcrFileService.PARAM_FILE_PATH; + public final static String PARAM_REPO_NODE_PATH = "param.repoNodePath"; + public final static String PARAM_REPO_URI = "param.repoUri"; + public final static String PARAM_WORKSPACE_NAME = "param.workspaceName"; + public final static String PARAM_FILE_PATH = "param.filePath"; private RepoService repoService; + private String currentServiceId; public Object execute(ExecutionEvent event) throws ExecutionException { @@ -59,74 +62,55 @@ public class OpenJcrFile extends AbstractHandler { String wkspName = event.getParameter(PARAM_WORKSPACE_NAME); String filePath = event.getParameter(PARAM_FILE_PATH); - // TODO remove - Session session = repoService.getRemoteSession(repoNodePath, repoUri, - wkspName); - JcrUtils.logoutQuietly(session); - // TODO sanity check if (filePath == null || "".equals(filePath.trim())) return null; - + Session businessSession = null; try { - if (log.isDebugEnabled()) - log.debug("URL : " - + createFullDownloadUrl(repoNodePath, repoUri, - wkspName, filePath)); - // RWT.getResponse().sendRedirect(createFullDownloadUrl(repoNodePath, - // repoUri, - // wkspName, filePath)); - - URL url = new URL(createFullDownloadUrl(repoNodePath, repoUri, - wkspName, filePath)); + businessSession = repoService.getRemoteSession(repoNodePath, + repoUri, wkspName); + Node result = businessSession.getNode(filePath); + + // Create a temporary service. No better solution has been found + // yet. + currentServiceId = UUID.randomUUID().toString(); + OpenJcrFileService ojfs = new OpenJcrFileService(result); + IServiceManager manager = RWT.getServiceManager(); + manager.registerServiceHandler(currentServiceId, ojfs); + String urlStr = createFullDownloadUrl(currentServiceId); + URL url = new URL(urlStr); PlatformUI.getWorkbench().getBrowserSupport() .createBrowser("DownloadDialog").openURL(url); } catch (Exception e) { - e.printStackTrace(); + throw new SlcException("Unable to open Jcr File for path " + + filePath, e); } return null; } - private String createFullDownloadUrl(String repoNodePath, String repoUri, - String wkspName, String filePath) { + @Override + public void dispose() { + IServiceManager manager = RWT.getServiceManager(); + manager.unregisterServiceHandler(currentServiceId); + super.dispose(); + } + + private String createFullDownloadUrl(String serviceId) { StringBuilder url = new StringBuilder(); url.append(RWT.getRequest().getRequestURL()); StringBuilder params = new StringBuilder(); params.append("?"); params.append(IServiceHandler.REQUEST_PARAM).append("="); - params.append(OpenJcrFileService.ID); - if (repoNodePath != null) - params.append("&").append(OpenJcrFileService.PARAM_REPO_NODE_PATH) - .append("=").append(repoNodePath); - - if (repoUri != null) - params.append("&").append(OpenJcrFileService.PARAM_REPO_URI) - .append("=").append(repoUri); - - if (wkspName != null) - params.append("&").append(OpenJcrFileService.PARAM_WORKSPACE_NAME) - .append("=").append(wkspName); - - if (filePath != null) - params.append("&").append(OpenJcrFileService.PARAM_FILE_PATH) - .append("=").append(filePath); - + params.append(serviceId); String encodedURL = RWT.getResponse().encodeURL(params.toString()); url.append(encodedURL); - return url.toString(); } /* Dependency Injection */ - // only used as a workaround to force the service instantiation - public void setOpenJcrFileService(OpenJcrFileService openJcrFileService) { - // do nothing. - } - public void setRepoService(RepoService repoService) { this.repoService = repoService; } - } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailPage.java index b63d91c61..bcf6070cb 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailPage.java @@ -35,6 +35,7 @@ import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; @@ -123,7 +124,7 @@ public class BundleDetailPage extends FormPage implements SlcNames { .getProperty(SlcNames.SLC_ARTIFACT_VERSION) .getString() : ""); - // 2nd Line: Vendor, licence, sources + // 3rd Line: Vendor, licence, sources createLT( parent, "Vendor", @@ -131,8 +132,17 @@ public class BundleDetailPage extends FormPage implements SlcNames { .getProperty(DistConstants.SLC_BUNDLE_VENDOR) .getString() : "N/A"); - createHyperlink(parent, "Licence", DistConstants.SLC_BUNDLE_LICENCE); + createLicencesLink(parent, "Licence", + DistConstants.SLC_BUNDLE_LICENCE); addSourceLink(parent); + + // 2nd Line: The Jar itself and the Manifest + createJarLink(parent); + createManifestLink(parent); + + // Last line + createPomLink(parent); + } catch (RepositoryException re) { throw new SlcException("Unable to get bundle name for node " + bundle, re); @@ -148,8 +158,7 @@ public class BundleDetailPage extends FormPage implements SlcNames { Section section = tk.createSection(parent, Section.TITLE_BAR | Section.DESCRIPTION); section.setText("Maven"); - section.setDescription("Copy Paste the below snippet " - + "to use it in your code."); + section.setDescription("Add the below tag to your Artifact pom dependencies"); section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Text snippetTxt = createMavenSnippet(section); section.setClient(snippetTxt); @@ -170,6 +179,124 @@ public class BundleDetailPage extends FormPage implements SlcNames { return text; } + private void createLicencesLink(Composite parent, String label, + String jcrPropName) throws RepositoryException { + tk.createLabel(parent, label, SWT.NONE); + if (bundle.hasProperty(jcrPropName)) { + + String licenceLinkVal = bundle.getProperty(jcrPropName).getString(); + String[] licenceVals = licenceLinkVal.split(", "); + + Composite body = tk.createComposite(parent); + body.setLayout(new RowLayout(SWT.WRAP)); + + for (String value : licenceVals) { + final Hyperlink link = tk + .createHyperlink(body, value, SWT.NONE); + link.addHyperlinkListener(new AbstractHyperlinkListener() { + @Override + public void linkActivated(HyperlinkEvent e) { + try { + IWorkbenchBrowserSupport browserSupport = PlatformUI + .getWorkbench().getBrowserSupport(); + IWebBrowser browser = browserSupport + .createBrowser( + IWorkbenchBrowserSupport.LOCATION_BAR + | IWorkbenchBrowserSupport.NAVIGATION_BAR, + "SLC Distribution browser", + "SLC Distribution browser", + "A tool tip"); + browser.openURL(new URL(link.getText())); + } catch (Exception ex) { + throw new SlcException("error opening browser", ex); //$NON-NLS-1$ + } + } + }); + } + } else + tk.createLabel(parent, "N/A", SWT.NONE); + } + + private void createJarLink(Composite parent) throws RepositoryException { + Label label = tk.createLabel(parent, "Jar", SWT.RIGHT); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + Composite body = tk.createComposite(parent); + RowLayout rl = new RowLayout(SWT.HORIZONTAL); + rl.spacing = 6; + body.setLayout(rl); + body.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); + + Hyperlink jarLink = tk + .createHyperlink(body, bundle.getName(), SWT.NONE); + jarLink.addHyperlinkListener(new OpenFileLinkListener(bundle.getPath())); + + // Corresponding check sums + + String name = bundle.getName() + ".md5"; + if (bundle.getParent().hasNode(name)) { + Node md5 = bundle.getParent().getNode(name); + Hyperlink md5Link = tk.createHyperlink(body, "MD5", SWT.NONE); + md5Link.addHyperlinkListener(new OpenFileLinkListener(md5.getPath())); + } + + name = bundle.getName() + ".sha1"; + if (bundle.getParent().hasNode(name)) { + Node sha1 = bundle.getParent().getNode(name); + Hyperlink sha1Link = tk.createHyperlink(body, "SHA1", SWT.NONE); + sha1Link.addHyperlinkListener(new OpenFileLinkListener(sha1 + .getPath())); + } + } + + private void createPomLink(Composite parent) throws RepositoryException { + Label label = tk.createLabel(parent, "Pom", SWT.RIGHT); + label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + + String name = bundle.getName().substring(0, bundle.getName().length() - "jar".length()) + "pom"; + + if (bundle.getParent().hasNode(name)) { + Node pom = bundle.getParent().getNode(name); + + Composite body = tk.createComposite(parent); + RowLayout rl = new RowLayout(SWT.HORIZONTAL); + rl.spacing = 6; + body.setLayout(rl); + body.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, + 3, 1)); + + Hyperlink pomLink = tk.createHyperlink(body, "pom.xml", SWT.NONE); + pomLink.addHyperlinkListener(new OpenFileLinkListener(pom.getPath())); + + // Corresponding check sums + + name = pom.getName() + ".md5"; + if (pom.getParent().hasNode(name)) { + Node md5 = pom.getParent().getNode(name); + Hyperlink md5Link = tk.createHyperlink(body, "MD5", SWT.NONE); + md5Link.addHyperlinkListener(new OpenFileLinkListener(md5 + .getPath())); + } + + name = pom.getName() + ".sha1"; + if (pom.getParent().hasNode(name)) { + Node sha1 = pom.getParent().getNode(name); + Hyperlink sha1Link = tk.createHyperlink(body, "SHA1", SWT.NONE); + sha1Link.addHyperlinkListener(new OpenFileLinkListener(sha1 + .getPath())); + } + } else + tk.createLabel(parent, "N/A", SWT.NONE); + } + + private void createManifestLink(Composite parent) + throws RepositoryException { + tk.createLabel(parent, "Manifest", SWT.NONE); + Hyperlink link = tk.createHyperlink(parent, "MANIFEST.MF", SWT.NONE); + // link.addHyperlinkListener(new + // OpenFileLinkListener(bundle.getPath())); + } + private void createHyperlink(Composite parent, String label, String jcrPropName) throws RepositoryException { tk.createLabel(parent, label, SWT.NONE); @@ -220,26 +347,30 @@ public class BundleDetailPage extends FormPage implements SlcNames { false)); final Hyperlink link = tk.createHyperlink(parent, srcName, SWT.NONE); - link.addHyperlinkListener(new AbstractHyperlinkListener() { - @Override - public void linkActivated(HyperlinkEvent e) { - try { - ModuleEditorInput editorInput = (ModuleEditorInput) getEditorInput(); - Map params = new HashMap(); - params.put(OpenJcrFile.PARAM_REPO_NODE_PATH, - editorInput.getRepoNodePath()); - params.put(OpenJcrFile.PARAM_REPO_URI, - editorInput.getUri()); - params.put(OpenJcrFile.PARAM_WORKSPACE_NAME, - editorInput.getWorkspaceName()); - params.put(OpenJcrFile.PARAM_FILE_PATH, - sourcesNode.getPath()); - CommandUtils.callCommand(OpenJcrFile.ID, params); - } catch (Exception ex) { - throw new SlcException("error opening browser", ex); //$NON-NLS-1$ - } - } - }); + link.addHyperlinkListener(new OpenFileLinkListener(sourcesNode + .getPath())); + + // { + // @Override + // public void linkActivated(HyperlinkEvent e) { + // try { + // ModuleEditorInput editorInput = (ModuleEditorInput) + // getEditorInput(); + // Map params = new HashMap(); + // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH, + // editorInput.getRepoNodePath()); + // params.put(OpenJcrFile.PARAM_REPO_URI, + // editorInput.getUri()); + // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME, + // editorInput.getWorkspaceName()); + // params.put(OpenJcrFile.PARAM_FILE_PATH, + // ); + // CommandUtils.callCommand(OpenJcrFile.ID, params); + // } catch (Exception ex) { + // throw new SlcException("error opening browser", ex); //$NON-NLS-1$ + // } + // } + // }); } } catch (RepositoryException e) { @@ -248,6 +379,31 @@ public class BundleDetailPage extends FormPage implements SlcNames { } } + private class OpenFileLinkListener extends AbstractHyperlinkListener { + final private String path; + + public OpenFileLinkListener(String path) { + this.path = path; + } + + @Override + public void linkActivated(HyperlinkEvent e) { + try { + ModuleEditorInput editorInput = (ModuleEditorInput) getEditorInput(); + Map params = new HashMap(); + params.put(OpenJcrFile.PARAM_REPO_NODE_PATH, + editorInput.getRepoNodePath()); + params.put(OpenJcrFile.PARAM_REPO_URI, editorInput.getUri()); + params.put(OpenJcrFile.PARAM_WORKSPACE_NAME, + editorInput.getWorkspaceName()); + params.put(OpenJcrFile.PARAM_FILE_PATH, path); + CommandUtils.callCommand(OpenJcrFile.ID, params); + } catch (Exception ex) { + throw new SlcException("error opening browser", ex); //$NON-NLS-1$ + } + } + } + /** Creates a text area with corresponding maven snippet */ private Text createMavenSnippet(Composite parent) { Text mavenSnippet = new Text(parent, SWT.MULTI | SWT.WRAP);