This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository scmwebeditor. See http://git.nuiton.org/scmwebeditor.git commit bb08171f13a51313a7f56ef2490fe18e2099915a Author: Hugo PIGEON <hpigeon@codelutin.com> Date: Fri Jun 5 14:46:23 2015 +0200 Add the ability to download the non-editable files --- .../org/nuiton/scmwebeditor/git/GitConnection.java | 23 +++- .../org/nuiton/scmwebeditor/api/ScmConnection.java | 10 +- .../org/nuiton/scmwebeditor/svn/SvnConnection.java | 2 +- .../uiweb/actions/DownloadFileAction.java | 123 +++++++++++++++++++++ .../scmwebeditor/uiweb/actions/EditAction.java | 14 ++- .../scmwebeditor/uiweb/actions/GetImageAction.java | 3 + .../uiweb/actions/ViewImageAction.java | 2 +- .../i18n/scmwebeditor-ui-web_en_GB.properties | 5 + .../i18n/scmwebeditor-ui-web_fr_FR.properties | 5 + swe-ui-web/src/main/resources/struts.xml | 6 + .../webapp/WEB-INF/content/fileNotEditable.jsp | 58 ++++++++++ .../webapp/WEB-INF/content/modificationViewer.jsp | 10 +- 12 files changed, 248 insertions(+), 13 deletions(-) diff --git a/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitConnection.java b/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitConnection.java index 03eee50..365af80 100644 --- a/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitConnection.java +++ b/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitConnection.java @@ -73,7 +73,7 @@ public class GitConnection implements ScmConnection { /** the name of the file to edit */ protected String fileName; - /** the id of the HTTP session */ + /** the path to the directory which contains all the repositories */ protected String pathToLocalRepos; /** the default branch to use when the requested one was not found */ @@ -511,7 +511,26 @@ public class GitConnection implements ScmConnection { } @Override - public String getImagePath(String address, String repositoryRoot) { + public String getFilePath(String address, String repositoryRoot, String username, String password) { + + try { + updateRepository(username, password); + } catch (RepositoryNotFoundException e) { + if (log.isErrorEnabled()) { + log.error("Error while cloning or pulling the repository", e); + } + return null; + } catch (IOException e) { + if (log.isErrorEnabled()) { + log.error("Error while cloning or pulling the repository", e); + } + return null; + } catch (AuthenticationException e) { + if (log.isErrorEnabled()) { + log.error("Error while cloning or pulling the repository", e); + } + return null; + } String path = localDirectory.getAbsolutePath() + address.replace(repositoryRoot, ""); path.replaceAll("/", File.separator); diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmConnection.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmConnection.java index 6e70f7a..cf92dd4 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmConnection.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmConnection.java @@ -87,12 +87,14 @@ public interface ScmConnection { /** - * Gives the path to use to display an image on a web page - * @param address the full address of the image on the repository + * Gives the path to use to get a file from the repository + * @param address the full address of the file on the repository * @param repositoryRoot the address of the repository's root - * @return the path to use to display an image on a web page + * @param username the user's login for the SCM + * @param password the user's password for the SCM + * @return the path to use to get a file from the repository */ - String getImagePath(String address, String repositoryRoot); + String getFilePath(String address, String repositoryRoot, String username, String password); /** diff --git a/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnConnection.java b/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnConnection.java index baa9116..bfd6c18 100644 --- a/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnConnection.java +++ b/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnConnection.java @@ -505,7 +505,7 @@ public class SvnConnection implements ScmConnection { } @Override - public String getImagePath(String address, String repositoryRoot) { + public String getFilePath(String address, String repositoryRoot, String username, String password) { return address; } diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/DownloadFileAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/DownloadFileAction.java new file mode 100644 index 0000000..2b439f9 --- /dev/null +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/DownloadFileAction.java @@ -0,0 +1,123 @@ +/* + * #%L + * ScmWebEditor + * %% + * Copyright (C) 2009 - 2015 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.scmwebeditor.uiweb.actions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts2.interceptor.ServletResponseAware; +import org.nuiton.scmwebeditor.api.ScmConnection; +import org.nuiton.scmwebeditor.api.ScmProvider; +import org.nuiton.scmwebeditor.uiweb.ScmWebEditorConfig; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.*; +import java.text.Normalizer; + +/** + * Allows to download the file at the given path + */ +public class DownloadFileAction extends ScmWebEditorMainAction implements ServletResponseAware { + + private static final Log log = LogFactory.getLog(DownloadFileAction.class); + + /** the path to the root of the repository */ + protected String repositoryRoot; + + /** the HTTP response to send to the client */ + protected HttpServletResponse response; + + + public String getRepositoryRoot() { return repositoryRoot; } + + public void setRepositoryRoot(String repositoryRoot) { this.repositoryRoot = repositoryRoot; } + + + public String execute() { + + HttpSession session = request.getSession(); + String sessionId = session.getId(); + String pathToLocalRepos = ScmWebEditorConfig.getLocalRepositoriesPath() + File.separator + sessionId; + + ScmProvider provider = ScmWebEditorConfig.getProvider(scmType); + ScmConnection scmConn = provider.getConnection(address, pathToLocalRepos); + + // getting the authentication information + // if the repository is not protected for writing, we get its UUID + String repositoryUUID = scmConn.getRepositoryId(); + if (repositoryUUID == null) { + repositoryUUID = address.replace(' ', '_'); + repositoryUUID = Normalizer.normalize(repositoryUUID, Normalizer.Form.NFD).replaceAll("[\u0300-\u036F]", ""); + } + + String[] usernamePw = getUsernamePwFromSession(repositoryUUID, username, pw); + username = usernamePw[0]; + pw = usernamePw[1]; + + // getting the path to use to download the file + String filePath = scmConn.getFilePath(address, repositoryRoot, username, pw); + String filename = filePath.substring(filePath.lastIndexOf('/') + 1); + + File fileToDownload = new File(filePath); + + if (fileToDownload.exists()) { + + // getting the file content + response.setContentType("application/octet-stream"); + + String disHeader = "Attachment; Filename=\"" + filename + "\""; + response.setHeader("Content-Disposition", disHeader); + + InputStream in; + ServletOutputStream outs; + + try { + outs = response.getOutputStream(); + + FileInputStream fis = new FileInputStream(fileToDownload); + in = new BufferedInputStream(fis); + + int ch = 0; + while (ch != -1) { + ch = in.read(); + outs.print((char) ch); + } + + outs.flush(); + outs.close(); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + return ERROR; + } + + return SUCCESS; + } + + @Override + public void setServletResponse(HttpServletResponse response) { + this.response = response; + } +} diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/EditAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/EditAction.java index 94d07f6..a01f34c 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/EditAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/EditAction.java @@ -50,6 +50,8 @@ public class EditAction extends ScmWebEditorMainAction { private static final Log log = LogFactory.getLog(EditAction.class); + protected final String NOT_EDITABLE = "notEditable"; + /** the name of the selected branch */ protected String selectedBranch; @@ -74,6 +76,9 @@ public class EditAction extends ScmWebEditorMainAction { /** the selected revision to view */ protected String revision; + /** equals true if this file is directly accessible from its address */ + protected boolean fileDirectlyAccessible; + public String getSelectedBranch() { return selectedBranch; } @@ -108,6 +113,11 @@ public class EditAction extends ScmWebEditorMainAction { public void setRevision(String revision) { this.revision = revision; } + public boolean isFileDirectlyAccessible() { return fileDirectlyAccessible; } + + public void setFileDirectlyAccessible( + boolean fileDirectlyAccessible) { this.fileDirectlyAccessible = fileDirectlyAccessible; } + /** * Execution of the edit action * @return a code interpreted in the file struts.xml @@ -125,6 +135,8 @@ public class EditAction extends ScmWebEditorMainAction { ScmProvider provider = ScmWebEditorConfig.getProvider(scmType); ScmConnection scmConn = provider.getConnection(address, pathToLocalRepos); + fileDirectlyAccessible = provider.filesDirectlyAccessible(); + scmSupportsBranches = provider.supportsBranches(); scmSupportsPush = provider.supportsPush(); @@ -328,7 +340,7 @@ public class EditAction extends ScmWebEditorMainAction { if (log.isErrorEnabled()) { log.error("Can't edit this file, mimetype : " + mimeType); } - return ERROR_PATH; + return NOT_EDITABLE; } origText = originalText; diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/GetImageAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/GetImageAction.java index db836c4..d2a20ec 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/GetImageAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/GetImageAction.java @@ -39,10 +39,13 @@ public class GetImageAction extends ScmWebEditorMainAction implements ServletReq private static final Log log = LogFactory.getLog(GetImageAction.class); + /** the bytes coding the image */ protected byte[] imageInByte = null; + /** the path to the image */ protected String imagePath; + /** the HTTP request sent to the server */ protected HttpServletRequest servletRequest; diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ViewImageAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ViewImageAction.java index 0249d48..24a4a31 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ViewImageAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ViewImageAction.java @@ -242,7 +242,7 @@ public class ViewImageAction extends ScmWebEditorMainAction { return ERROR_PATH; } - imagePath = scmConn.getImagePath(address, repositoryRoot); + imagePath = scmConn.getFilePath(address, repositoryRoot, username, pw); if (log.isInfoEnabled()) { diff --git a/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_en_GB.properties b/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_en_GB.properties index ac8b2db..7cfc935 100644 --- a/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_en_GB.properties +++ b/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_en_GB.properties @@ -1,9 +1,11 @@ scm.FileInEditor=File in editor \: scm.atRevision=at revision +scm.back=You can also get back to scm.badPathOrFileName=Bad repository path or file name, or the file is not editable \! Please correct it. scm.badUsernameOrPassword=Bad username or password scm.beTransferred=You should be transferred automatically to the new page. If not please scm.by=By +scm.canDownload=You can however download it, for this scm.cannotSave=Can't save modification. scm.cantFindRepo=Can't find the repository. scm.clickHere=click here @@ -27,10 +29,12 @@ scm.exitJavascript=Exit ScmWebEditor? scm.exitJavascriptChanges=Exit ScmWebEditor without saving? All modification will be lost. scm.exitTitle=Exit ScmWebEditor without saving. scm.fileModify=File modify while editing. +scm.fileNotEditable=This file is not editable. scm.fileRevision=File revision\: scm.fileToMove=File to move\: scm.forceSave=Force save scm.formTransferred=You should be transferred automatically to the form page. If not please +scm.homepage=the homepage scm.info.ProblemWithRst=For any problem with RestructuredText visit scm.info.rstWebsite=RST documentation website scm.language=Language @@ -55,6 +59,7 @@ scm.moveFileTitle=Move a file on the repository scm.mustBeLog=You must be login to see this repository. scm.newDirectoryName=Name of the new directory\: scm.no=No +scm.notEditable=File not editable scm.openAnotherFile=Open another file scm.outConnection.branches=List of branches scm.outConnection.enterRepo=Please enter your repository address. diff --git a/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_fr_FR.properties b/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_fr_FR.properties index 839afba..97a475c 100644 --- a/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_fr_FR.properties +++ b/swe-ui-web/src/main/resources/i18n/scmwebeditor-ui-web_fr_FR.properties @@ -1,9 +1,11 @@ scm.FileInEditor=Fichier dans l'éditeur \: scm.atRevision=à la révision +scm.back=Vous pouvez également retourner sur scm.badPathOrFileName=L'adresse du dépôt ou le nom du fichier est incorrect, ou le fichier n'est pas éditable \! scm.badUsernameOrPassword=Identifiant ou mot de passe incorrect scm.beTransferred=Vous devriez être redirigé sur une nouvelle page. si non scm.by=Par +scm.canDownload=Vous pouvez cependant le télécharger, pour cela scm.cannotSave=Modification impossible scm.cantFindRepo=Impossible de trouver le dépôt. scm.clickHere=cliquez ici @@ -27,10 +29,12 @@ scm.exitJavascript=Quitter ScmWebEditor ? scm.exitJavascriptChanges=Quitter ScmWebEditor sans sauvegarder ? Toutes les modifications seront perdues. scm.exitTitle=Quitter ScmWebEditor sans sauvegarder. scm.fileModify=Fichier modifié pendant l'édition. +scm.fileNotEditable=Ce fichier n'est pas éditable. scm.fileRevision=Révision du fichier \: scm.fileToMove=Fichier à déplacer \: scm.forceSave=Forcer la sauvegarde scm.formTransferred=Vous devriez être redirigé vers la page du formulaire. si non +scm.homepage=la page d'accueil scm.info.ProblemWithRst=Si vous rencontrez des problèmes avec RestructuredText, visitez le scm.info.rstWebsite=site de la documentation RST scm.language=Langage @@ -55,6 +59,7 @@ scm.moveFileTitle=Déplacer un fichier au sein du dépôt scm.mustBeLog=Vous devez vous identifier pour parcourir ce dépôt. scm.newDirectoryName=Nom du nouveau répertoire \: scm.no=Non +scm.notEditable=Fichier non éditable scm.openAnotherFile=Ouvrir un autre fichier scm.outConnection.branches=Liste des branches scm.outConnection.enterRepo=Entrez l'adresse de votre dépôt. diff --git a/swe-ui-web/src/main/resources/struts.xml b/swe-ui-web/src/main/resources/struts.xml index 783b0e7..192a2fb 100644 --- a/swe-ui-web/src/main/resources/struts.xml +++ b/swe-ui-web/src/main/resources/struts.xml @@ -75,6 +75,7 @@ <result name="login" >/WEB-INF/content/privateScmRedirect.jsp</result> <result name="errorPath" >/WEB-INF/content/badFileRedirect.jsp</result> <result name="editPage" >/WEB-INF/content/modificationViewer.jsp</result> + <result name="notEditable">/WEB-INF/content/fileNotEditable.jsp</result> </action> <action name="viewImage" class="org.nuiton.scmwebeditor.uiweb.actions.ViewImageAction"> @@ -180,6 +181,11 @@ <action name="detectScm" class="org.nuiton.scmwebeditor.uiweb.actions.DetectScmAction"> <result name="success" type="json"/> </action> + + <action name="downloadFile" class="org.nuiton.scmwebeditor.uiweb.actions.DownloadFileAction"> + <result name="success" type="httpheader"/> + <result name="error">/WEB-INF/content/badFileRedirect.jsp</result> + </action> </package> </struts> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/fileNotEditable.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/fileNotEditable.jsp new file mode 100644 index 0000000..070af09 --- /dev/null +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/fileNotEditable.jsp @@ -0,0 +1,58 @@ +<%-- + #%L + ScmWebEditor + %% + Copyright (C) 2009 - 2015 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --%> + +<%@page contentType="text/html" + pageEncoding="UTF-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" +"http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title><s:text name="scm.notEditable"/></title> + <link rel="icon" href="img/machine-a-ecrire_little.png" type="image/png"> + <link rel="stylesheet" type="text/css" href="css/main.css"> +</head> +<body> +<a target="_blank" href="http://maven-site.nuiton.org/scmwebeditor/"><img + src="img/ScmWebEditor_main.png" alt="$alt"/></a> + +<p><s:text name="scm.fileNotEditable"/></p> + +<p><s:text name="scm.canDownload"/> + <s:if test="fileDirectlyAccessible"> + <a href="<%=request.getAttribute("address")%>"> + </s:if> + <s:else> + <a href="downloadFile.action?address=<%=request.getAttribute("address")%>&repositoryRoot=<%=request.getAttribute("repositoryRoot")%>&scmType=<%=request.getAttribute("scmType")%>"> + </s:else> + + <s:text name="scm.clickHere"/></a>.</p> + +<p> + <s:text name="scm.back"/> <a href="checkout.action"><s:text name="scm.homepage"/></a>. +</p> + +<p>©2004-2015 CodeLutin</p> +</body> +</html> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/modificationViewer.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/modificationViewer.jsp index 6c962c5..6f9e19e 100644 --- a/swe-ui-web/src/main/webapp/WEB-INF/content/modificationViewer.jsp +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/modificationViewer.jsp @@ -64,13 +64,15 @@ /* Asks the user if he really wants to exit when changes are made */ function confirmExit() { - var text = '<s:text name="scm.exitJavascript"/>'; + var redirect = true; - if (document.getElementById('newTextId').value != editor.getValue()) { - text = '<s:text name="scm.exitJavascriptChanges"/>'; + if (document.getElementById('newTextId').value == editor.getValue()) { + redirect = cancelRedirect('<s:text name="scm.exitJavascript"/>', document.getElementById('projectUrl')); + } else { + document.location.href = document.getElementById('projectUrl').value; } - return cancelRedirect(text, document.getElementById('projectUrl')); + return redirect; } /* Asks the user if he really wants to close the page when changes are made */ -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.