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 92812c0067b9f879ec124caf80c86770c3b0cb6c Author: Hugo PIGEON <hpigeon@codelutin.com> Date: Thu May 21 10:47:44 2015 +0200 Add the ability to create a new branch on repositories that support branches --- .../org/nuiton/scmwebeditor/git/GitConnection.java | 168 +++++++++-------- .../org/nuiton/scmwebeditor/git/GitProvider.java | 129 ++++++++++++- .../org/nuiton/scmwebeditor/api/ScmConnection.java | 1 + .../org/nuiton/scmwebeditor/api/ScmProvider.java | 14 ++ .../scmwebeditor/api/dto/CreateBranchDto.java | 68 +++++++ .../scmwebeditor/api/dto/UploadResultDto.java | 46 ----- .../AbstractResultDto.java} | 30 +-- .../api/dto/{ => result}/BrowseResultDto.java | 19 +- .../api/dto/{ => result}/CommitResultDto.java | 19 +- .../api/dto/{ => result}/RemoveResultDto.java | 19 +- .../UploadResultDto.java} | 34 +--- .../org/nuiton/scmwebeditor/svn/SvnConnection.java | 45 +++-- .../org/nuiton/scmwebeditor/svn/SvnProvider.java | 11 +- .../scmwebeditor/uiweb/actions/BrowseAction.java | 2 +- .../uiweb/actions/CreateBranchAction.java | 201 +++++++++++++++++++++ .../scmwebeditor/uiweb/actions/RemoveAction.java | 2 +- .../uiweb/actions/ScmWebEditorCommitAction.java | 2 +- .../scmwebeditor/uiweb/actions/UploadAction.java | 2 +- .../i18n/scmwebeditor-ui-web_en_GB.properties | 6 +- .../i18n/scmwebeditor-ui-web_fr_FR.properties | 4 + swe-ui-web/src/main/resources/struts.xml | 7 + .../src/main/webapp/WEB-INF/content/browse.jsp | 7 + .../{removeForm.jsp => createBranchForm.jsp} | 65 +------ .../webapp/WEB-INF/content/createBranchSuccess.jsp | 44 +++++ .../src/main/webapp/WEB-INF/content/removeForm.jsp | 3 - swe-ui-web/src/main/webapp/js/popup.js | 2 +- 26 files changed, 629 insertions(+), 321 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 12e2673..221f6e7 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 @@ -39,7 +39,14 @@ import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.eclipse.jgit.treewalk.TreeWalk; import org.nuiton.scmwebeditor.api.RepositoryNotFoundException; import org.nuiton.scmwebeditor.api.ScmConnection; -import org.nuiton.scmwebeditor.api.dto.*; +import org.nuiton.scmwebeditor.api.dto.BrowseDto; +import org.nuiton.scmwebeditor.api.dto.CommitDto; +import org.nuiton.scmwebeditor.api.dto.RemoveDto; +import org.nuiton.scmwebeditor.api.dto.UploadDto; +import org.nuiton.scmwebeditor.api.dto.result.BrowseResultDto; +import org.nuiton.scmwebeditor.api.dto.result.CommitResultDto; +import org.nuiton.scmwebeditor.api.dto.result.RemoveResultDto; +import org.nuiton.scmwebeditor.api.dto.result.UploadResultDto; import javax.naming.AuthenticationException; import java.io.File; @@ -77,6 +84,10 @@ public class GitConnection implements ScmConnection { protected static final String DEFAULT_BRANCH = "master"; + public File getLocalDirectory() { return localDirectory; } + + public Repository getGitRepo() { return gitRepo; } + /** * Creates a new connection to a Git repository * @param address the address of the Git repository to connect to @@ -120,6 +131,7 @@ public class GitConnection implements ScmConnection { BrowseResultDto resultDto = new BrowseResultDto(); + // getting the last version of the repository try { updateRepository(dto.getUsername(), dto.getPassword()); } catch (RepositoryNotFoundException e) { @@ -292,6 +304,7 @@ public class GitConnection implements ScmConnection { CommitResultDto resultDto = new CommitResultDto(); + // getting the last version of the repository try { updateRepository(dto.getUsername(), dto.getPassword()); } catch (RepositoryNotFoundException e) { @@ -365,20 +378,11 @@ public class GitConnection implements ScmConnection { } try { - // commit Git git = Git.open(localDirectory); - if (log.isDebugEnabled()) { - log.debug("Preparing commit"); - } - - CommitCommand commit = git.commit(); - commit.setAll(true); - commit.setAuthor(dto.getUsername(), "unknown"); - commit.setMessage("From scmwebeditor -- " + dto.getCommitMessage()); - + // commit try { - commit.call(); + doCommit(git, dto.getUsername(), "unknown", "From scmwebeditor -- " + dto.getCommitMessage()); } catch (GitAPIException e) { if (log.isErrorEnabled()) { log.error("Can not commit", e); @@ -388,11 +392,11 @@ public class GitConnection implements ScmConnection { return resultDto; } + // push if (log.isDebugEnabled()) { log.debug("Preparing push"); } - // push if (!dto.isCommitOnly()) { PushCommand push = git.push(); push.setRemote(addressGit); @@ -402,23 +406,7 @@ public class GitConnection implements ScmConnection { push.call(); } catch (GitAPIException e) { - String logMessage = "Can not push"; - - if (e instanceof NoHeadException) { - logMessage = "Can not push : the Git repository has no HEAD reference"; - } else if (e instanceof UnmergedPathsException) { - logMessage = "Can not push : conflicts found (unmerged paths)"; - } else if (e instanceof ConcurrentRefUpdateException) { - logMessage = "Can not push : someone else is updating the HEAD or the branch"; - } else if (e instanceof WrongRepositoryStateException) { - logMessage = "Can not push : the repository is not in the right state"; - } else if (e instanceof RejectCommitException) { - logMessage = "Can not push : commit rejected"; - } - - if (log.isErrorEnabled()) { - log.error(logMessage, e); - } + handlePushException(e); if (e.getMessage().endsWith("not authorized")) { resultDto.setError(RemoveResultDto.AUTH_ERROR); @@ -447,6 +435,7 @@ public class GitConnection implements ScmConnection { UploadResultDto resultDto = new UploadResultDto(); + // getting the last version of the repository try { updateRepository(dto.getUsername(), dto.getPassword()); } catch (RepositoryNotFoundException e) { @@ -540,17 +529,8 @@ public class GitConnection implements ScmConnection { } // commit - if (log.isDebugEnabled()) { - log.debug("Preparing commit"); - } - - CommitCommand commit = git.commit(); - commit.setAll(true); - commit.setAuthor(dto.getUsername(), "unknown"); - commit.setMessage("From scmwebeditor -- add the file : " + dto.getUploadFileName()); - try { - commit.call(); + doCommit(git, dto.getUsername(), "unknown", "From scmwebeditor -- add the file : " + dto.getUploadFileName()); } catch (GitAPIException e) { if (log.isErrorEnabled()) { log.error("Can not commit", e); @@ -560,11 +540,11 @@ public class GitConnection implements ScmConnection { return resultDto; } + // push if (log.isDebugEnabled()) { log.debug("Preparing push"); } - // push PushCommand push = git.push(); push.setRemote(addressGit); push.setCredentialsProvider(credentials); @@ -573,25 +553,9 @@ public class GitConnection implements ScmConnection { push.call(); } catch (GitAPIException e) { - String logMessage = "Can not push"; - file.delete(); - if (e instanceof NoHeadException) { - logMessage = "Can not push : the Git repository has no HEAD reference"; - } else if (e instanceof UnmergedPathsException) { - logMessage = "Can not push : conflicts found (unmerged paths)"; - } else if (e instanceof ConcurrentRefUpdateException) { - logMessage = "Can not push : someone else is updating the HEAD or the branch"; - } else if (e instanceof WrongRepositoryStateException) { - logMessage = "Can not push : the repository is not in the right state"; - } else if (e instanceof RejectCommitException) { - logMessage = "Can not push : commit rejected"; - } - - if (log.isErrorEnabled()) { - log.error(logMessage, e); - } + handlePushException(e); if (e.getMessage().endsWith("not authorized")) { resultDto.setError(RemoveResultDto.AUTH_ERROR); @@ -619,6 +583,7 @@ public class GitConnection implements ScmConnection { RemoveResultDto resultDto = new RemoveResultDto(); + // getting the last version of the repository try { updateRepository(dto.getUsername(), dto.getPassword()); } catch (RepositoryNotFoundException e) { @@ -706,17 +671,8 @@ public class GitConnection implements ScmConnection { file.delete(); // commit - if (log.isDebugEnabled()) { - log.debug("Preparing commit"); - } - - CommitCommand commit = git.commit(); - commit.setAll(true); - commit.setAuthor(dto.getUsername(), "unknown"); - commit.setMessage("From scmwebeditor -- remove the file : " + pathOnRepo); - try { - commit.call(); + doCommit(git, dto.getUsername(), "unknown", "From scmwebeditor -- remove the file : " + pathOnRepo); } catch (GitAPIException e) { if (log.isErrorEnabled()) { log.error("Can not commit", e); @@ -726,11 +682,11 @@ public class GitConnection implements ScmConnection { return resultDto; } + // push if (log.isDebugEnabled()) { log.debug("Preparing push"); } - // push PushCommand push = git.push(); push.setRemote(addressGit); push.setCredentialsProvider(credentials); @@ -739,23 +695,7 @@ public class GitConnection implements ScmConnection { push.call(); } catch (GitAPIException e) { - String logMessage = "Can not push"; - - if (e instanceof NoHeadException) { - logMessage = "Can not push : the Git repository has no HEAD reference"; - } else if (e instanceof UnmergedPathsException) { - logMessage = "Can not push : conflicts found (unmerged paths)"; - } else if (e instanceof ConcurrentRefUpdateException) { - logMessage = "Can not push : someone else is updating the HEAD or the branch"; - } else if (e instanceof WrongRepositoryStateException) { - logMessage = "Can not push : the repository is not in the right state"; - } else if (e instanceof RejectCommitException) { - logMessage = "Can not push : commit rejected"; - } - - if (log.isErrorEnabled()) { - log.error(logMessage, e); - } + handlePushException(e); try { cloneRepository(credentials); @@ -793,6 +733,7 @@ public class GitConnection implements ScmConnection { @Override public File getFileContent(String path, String username, String password) throws AuthenticationException { + // getting the last version of the repository try { updateRepository(username, password); } catch (RepositoryNotFoundException e) { @@ -815,6 +756,7 @@ public class GitConnection implements ScmConnection { @Override public String getHeadRevisionNumber(String path, String username, String password) throws AuthenticationException { + // getting the last version of the repository try { updateRepository(username, password); } catch (RepositoryNotFoundException e) { @@ -948,6 +890,11 @@ public class GitConnection implements ScmConnection { log.error("Can't pull the remote repository", e); } cloneRepository(credentials); + } catch (JGitInternalException e) { + if (log.isErrorEnabled()) { + log.error("Can't pull the remote repository", e); + } + cloneRepository(credentials); } if (log.isDebugEnabled()) { @@ -1033,7 +980,7 @@ public class GitConnection implements ScmConnection { * @param algorithm the algorithm to use to hash the String * @return the hashed String */ - private String hash(String toHash, String algorithm) { + protected String hash(String toHash, String algorithm) { String hashed = null; @@ -1059,4 +1006,51 @@ public class GitConnection implements ScmConnection { return hashed; } + + + /** + * Calls the commit command + * @param git the git repository which will receive the commit + * @param authorName the name of the commit's author + * @param authorEmail the e-mail address of the author + * @param commitMessage the message that describes the commit + * @throws GitAPIException if there is a problem during the commit process + */ + protected void doCommit(Git git, String authorName, String authorEmail, String commitMessage) throws GitAPIException { + + if (log.isDebugEnabled()) { + log.debug("Preparing commit"); + } + + CommitCommand commit = git.commit(); + commit.setAll(true); + commit.setAuthor(authorName, authorEmail); + commit.setMessage(commitMessage); + + commit.call(); + } + + /** + * Handles the exception thrown by a push command + * @param e the exception thrown by a push command + */ + protected void handlePushException(GitAPIException e) { + String logMessage = "Can not push"; + + if (e instanceof NoHeadException) { + logMessage = "Can not push : the Git repository has no HEAD reference"; + } else if (e instanceof UnmergedPathsException) { + logMessage = "Can not push : conflicts found (unmerged paths)"; + } else if (e instanceof ConcurrentRefUpdateException) { + logMessage = "Can not push : someone else is updating the HEAD or the branch"; + } else if (e instanceof WrongRepositoryStateException) { + logMessage = "Can not push : the repository is not in the right state"; + } else if (e instanceof RejectCommitException) { + logMessage = "Can not push : commit rejected"; + } + + if (log.isErrorEnabled()) { + log.error(logMessage, e); + } + } } \ No newline at end of file diff --git a/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitProvider.java b/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitProvider.java index 71a1e31..97551f5 100644 --- a/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitProvider.java +++ b/swe-git/src/main/java/org/nuiton/scmwebeditor/git/GitProvider.java @@ -23,15 +23,23 @@ package org.nuiton.scmwebeditor.git; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.eclipse.jgit.api.LsRemoteCommand; -import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.*; +import org.eclipse.jgit.api.errors.*; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.nuiton.scmwebeditor.api.OperationNotSupportedException; +import org.nuiton.scmwebeditor.api.RepositoryNotFoundException; import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; +import org.nuiton.scmwebeditor.api.dto.CreateBranchDto; +import org.nuiton.scmwebeditor.api.dto.result.AbstractResultDto; +import javax.naming.AuthenticationException; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -56,6 +64,13 @@ public class GitProvider implements ScmProvider { @Override public List<String> listBranches(String address, String username, String password) throws OperationNotSupportedException { + if (username == null) { + username = "anonymous"; + } + if (password == null) { + password = "anonymous"; + } + List<String> branches = new ArrayList<String>(); CredentialsProvider credentials = new UsernamePasswordCredentialsProvider(username, password); @@ -80,13 +95,121 @@ public class GitProvider implements ScmProvider { branches.add(name); } } catch (GitAPIException e) { - log.error("The repository at address " + address + " doesn't exist", e); + if (log.isErrorEnabled()) { + log.error("The repository at address " + address + " could not be reached", e); + } } return branches; } @Override + public String createBranch(CreateBranchDto dto) throws OperationNotSupportedException, + AuthenticationException, RepositoryNotFoundException { + + String error = null; + GitConnection conn = (GitConnection) getConnection(address, dto.getPathToLocalRepos()); + + // authentication + if (dto.getUsername() == null) { + dto.setUsername("anonymous"); + } + if (dto.getPassword() == null) { + dto.setPassword("anonymous"); + } + + CredentialsProvider credentials = new UsernamePasswordCredentialsProvider(dto.getUsername(), dto.getPassword()); + + try { + + // setting the local repository in the right state + conn.updateRepository(dto.getUsername(), dto.getPassword()); + File localDirectory = conn.getLocalDirectory(); + conn.changeBranch(dto.getSelectedBranch()); + + // getting the reference to the origin branch + ObjectId id = conn.getGitRepo().resolve(dto.getSelectedBranch()); + RevWalk revWalk = new RevWalk(conn.getGitRepo()); + RevCommit revCommit = revWalk.parseCommit(id); + + Git git = Git.open(localDirectory); + + // creating the local branch + CreateBranchCommand createBranch = git.branchCreate(); + createBranch.setName(dto.getNewBranchName()); + createBranch.setStartPoint(revCommit); + + try { + createBranch.call(); + } catch (GitAPIException e) { + if (log.isErrorEnabled()) { + log.error("Can not create local branch " + dto.getNewBranchName() + " from " + dto.getSelectedBranch(), e); + error = AbstractResultDto.ERROR; + } + } + + conn.changeBranch(dto.getNewBranchName()); + + // push + PushCommand push = git.push(); + push.setRemote(address); + push.setCredentialsProvider(credentials); + + try { + push.call(); + } catch (GitAPIException e) { + + error = AbstractResultDto.ERROR; + + String logMessage = "Can not push"; + + if (e instanceof NoHeadException) { + logMessage = "Can not push : the Git repository has no HEAD reference"; + } else if (e instanceof UnmergedPathsException) { + logMessage = "Can not push : conflicts found (unmerged paths)"; + } else if (e instanceof ConcurrentRefUpdateException) { + logMessage = "Can not push : someone else is updating the HEAD or the branch"; + } else if (e instanceof WrongRepositoryStateException) { + logMessage = "Can not push : the repository is not in the right state"; + } else if (e instanceof RejectCommitException) { + logMessage = "Can not push : commit rejected"; + } + + if (log.isErrorEnabled()) { + log.error(logMessage, e); + } + + // if the branch could not be pushed, we delete it to avoid errors + DeleteBranchCommand deleteBranch = git.branchDelete(); + deleteBranch.setBranchNames(dto.getNewBranchName()); + deleteBranch.setForce(true); + + try { + deleteBranch.call(); + } catch (GitAPIException e1) { + if (log.isErrorEnabled()) { + log.error("Can not delete the new local branch", e1); + } + } + + if (e.getMessage().endsWith("not authorized")) { + throw new AuthenticationException("Authentication error"); + } else { + throw new RepositoryNotFoundException("Can not reach the remote repository"); + } + } + + } catch (IOException e) { + if (log.isErrorEnabled()) { + log.error("Can not open local Git repository", e); + } + error = AbstractResultDto.ERROR; + } + + return error; + } + + @Override public boolean supportsPush() { return true; } 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 bb000b9..8f16989 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 @@ -22,6 +22,7 @@ package org.nuiton.scmwebeditor.api; import org.nuiton.scmwebeditor.api.dto.*; +import org.nuiton.scmwebeditor.api.dto.result.*; import javax.naming.AuthenticationException; import java.io.File; diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmProvider.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmProvider.java index c3c445d..bf053d6 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmProvider.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/ScmProvider.java @@ -21,6 +21,9 @@ */ package org.nuiton.scmwebeditor.api; +import org.nuiton.scmwebeditor.api.dto.CreateBranchDto; + +import javax.naming.AuthenticationException; import java.util.List; /** @@ -45,6 +48,17 @@ public interface ScmProvider { List<String> listBranches(String address, String username, String password) throws OperationNotSupportedException; /** + * Allows to create a new branch on the repository + * @param dto the DTO which contains all the parameters + * @return an error code or null if there was no error during the process + * @throws OperationNotSupportedException if the SCM doesn't support branches + * @throws AuthenticationException if there is an authentication problem + * @throws RepositoryNotFoundException if the repository could not be reached + */ + String createBranch(CreateBranchDto dto) throws OperationNotSupportedException, + AuthenticationException, RepositoryNotFoundException; + + /** * Tells whether the SCM allows to choose when the commits are pushed to the server * @return true if the SCM supports a command to push the commits to the server */ diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CreateBranchDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CreateBranchDto.java new file mode 100644 index 0000000..a09d632 --- /dev/null +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CreateBranchDto.java @@ -0,0 +1,68 @@ +/* + * #%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.api.dto; + +public class CreateBranchDto { + + /** the repository's address */ + protected String address; + + /** the name of the branch to create */ + protected String newBranchName; + + /** the name of the origin branch for the new one */ + protected String selectedBranch; + + /** the username to use to connect to the repository */ + protected String username; + + /** the password to use to connect to the repository */ + protected String password; + + /** the folder which is used to store the repositories */ + protected String pathToLocalRepos; + + + public String getAddress() { return address; } + + public void setAddress(String address) { this.address = address; } + + public String getNewBranchName() { return newBranchName; } + + public void setNewBranchName(String newBranchName) { this.newBranchName = newBranchName; } + + public String getSelectedBranch() { return selectedBranch; } + + public void setSelectedBranch(String selectedBranch) { this.selectedBranch = selectedBranch; } + + public String getUsername() { return username; } + + public void setUsername(String username) { this.username = username; } + + public String getPassword() { return password; } + + public void setPassword(String password) { this.password = password; } + + public String getPathToLocalRepos() { return pathToLocalRepos; } + + public void setPathToLocalRepos(String pathToLocalRepos) { this.pathToLocalRepos = pathToLocalRepos; } +} diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/UploadResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/UploadResultDto.java deleted file mode 100644 index cf1e818..0000000 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/UploadResultDto.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.nuiton.scmwebeditor.api.dto; - -public class UploadResultDto { - - public static String ERROR = "error"; - - public static String REDIRECT = "redirect"; - - public static String CONNECTION_FAILED = "connection failed"; - - public static String AUTH_ERROR = "auth error"; - - /** gives a message about the error if one occured */ - protected String error; - - /** the directory which contains the file */ - protected String fileRoot; - - /** the root direcory of the repository */ - protected String scmRoot; - - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - - public String getFileRoot() { - return fileRoot; - } - - public void setFileRoot(String fileRoot) { - this.fileRoot = fileRoot; - } - - public String getScmRoot() { - return scmRoot; - } - - public void setScmRoot(String scmRoot) { - this.scmRoot = scmRoot; - } -} diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/AbstractResultDto.java similarity index 62% copy from swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java copy to swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/AbstractResultDto.java index 47e264c..5b51007 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/AbstractResultDto.java @@ -19,27 +19,17 @@ * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ -package org.nuiton.scmwebeditor.api.dto; +package org.nuiton.scmwebeditor.api.dto.result; -public class RemoveResultDto { +public class AbstractResultDto { public static String ERROR = "error"; - public static String REDIRECT = "redirect"; - - public static String CONNECTION_FAILED = "connection failed"; - public static String AUTH_ERROR = "auth error"; /** gives a message about the error if one occured */ protected String error; - /** the root directory of the repository */ - protected String scmRoot; - - /** the full path of the file to remove */ - private String fileRoot; - public String getError() { return error; @@ -48,20 +38,4 @@ public class RemoveResultDto { public void setError(String error) { this.error = error; } - - public String getScmRoot() { - return scmRoot; - } - - public void setScmRoot(String scmRoot) { - this.scmRoot = scmRoot; - } - - public String getFileRoot() { - return fileRoot; - } - - public void setFileRoot(String fileRoot) { - this.fileRoot = fileRoot; - } } diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/BrowseResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/BrowseResultDto.java similarity index 77% rename from swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/BrowseResultDto.java rename to swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/BrowseResultDto.java index 679f2d2..4553485 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/BrowseResultDto.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/BrowseResultDto.java @@ -1,4 +1,4 @@ -package org.nuiton.scmwebeditor.api.dto; +package org.nuiton.scmwebeditor.api.dto.result; import java.util.HashMap; @@ -6,18 +6,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -public class BrowseResultDto { - - public static String ERROR = "error"; - - public static String AUTH_ERROR = "auth error"; +public class BrowseResultDto extends AbstractResultDto { public static String ROOT = "root"; - /** gives a message about the error if one occured */ - protected String error; - /** the name of the head branch on the SCM */ protected String headBranchName; @@ -36,14 +29,6 @@ public class BrowseResultDto { directories = new HashMap<String, String>(); } - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - public String getHeadBranchName() { return headBranchName; } diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CommitResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/CommitResultDto.java similarity index 76% rename from swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CommitResultDto.java rename to swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/CommitResultDto.java index 7ef2696..261de67 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/CommitResultDto.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/CommitResultDto.java @@ -1,18 +1,11 @@ -package org.nuiton.scmwebeditor.api.dto; +package org.nuiton.scmwebeditor.api.dto.result; -public class CommitResultDto { - - public static String ERROR = "error"; +public class CommitResultDto extends AbstractResultDto { public static String ERROR_PATH = "error path"; - public static String AUTH_ERROR = "auth error"; - public static String FILE_MODIFY = "file modify"; - /** gives a message about the error if one occured */ - protected String error; - /** the last read text */ protected String lastText; @@ -29,14 +22,6 @@ public class CommitResultDto { protected String numRevision; - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - public String getLastText() { return lastText; } diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/RemoveResultDto.java similarity index 77% copy from swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java copy to swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/RemoveResultDto.java index 47e264c..37917ac 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/RemoveResultDto.java @@ -19,21 +19,14 @@ * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ -package org.nuiton.scmwebeditor.api.dto; +package org.nuiton.scmwebeditor.api.dto.result; -public class RemoveResultDto { - - public static String ERROR = "error"; +public class RemoveResultDto extends AbstractResultDto { public static String REDIRECT = "redirect"; public static String CONNECTION_FAILED = "connection failed"; - public static String AUTH_ERROR = "auth error"; - - /** gives a message about the error if one occured */ - protected String error; - /** the root directory of the repository */ protected String scmRoot; @@ -41,14 +34,6 @@ public class RemoveResultDto { private String fileRoot; - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - public String getScmRoot() { return scmRoot; } diff --git a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/UploadResultDto.java similarity index 70% rename from swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java rename to swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/UploadResultDto.java index 47e264c..0ba235e 100644 --- a/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/RemoveResultDto.java +++ b/swe-scm-api/src/main/java/org/nuiton/scmwebeditor/api/dto/result/UploadResultDto.java @@ -19,34 +19,26 @@ * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ -package org.nuiton.scmwebeditor.api.dto; +package org.nuiton.scmwebeditor.api.dto.result; -public class RemoveResultDto { - - public static String ERROR = "error"; +public class UploadResultDto extends AbstractResultDto { public static String REDIRECT = "redirect"; public static String CONNECTION_FAILED = "connection failed"; - public static String AUTH_ERROR = "auth error"; - - /** gives a message about the error if one occured */ - protected String error; + /** the directory which contains the file */ + protected String fileRoot; - /** the root directory of the repository */ + /** the root direcory of the repository */ protected String scmRoot; - /** the full path of the file to remove */ - private String fileRoot; - - - public String getError() { - return error; + public String getFileRoot() { + return fileRoot; } - public void setError(String error) { - this.error = error; + public void setFileRoot(String fileRoot) { + this.fileRoot = fileRoot; } public String getScmRoot() { @@ -56,12 +48,4 @@ public class RemoveResultDto { public void setScmRoot(String scmRoot) { this.scmRoot = scmRoot; } - - public String getFileRoot() { - return fileRoot; - } - - public void setFileRoot(String fileRoot) { - this.fileRoot = fileRoot; - } } 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 14d66de..1854095 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 @@ -25,7 +25,14 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.scmwebeditor.api.ScmConnection; -import org.nuiton.scmwebeditor.api.dto.*; +import org.nuiton.scmwebeditor.api.dto.BrowseDto; +import org.nuiton.scmwebeditor.api.dto.CommitDto; +import org.nuiton.scmwebeditor.api.dto.RemoveDto; +import org.nuiton.scmwebeditor.api.dto.UploadDto; +import org.nuiton.scmwebeditor.api.dto.result.BrowseResultDto; +import org.nuiton.scmwebeditor.api.dto.result.CommitResultDto; +import org.nuiton.scmwebeditor.api.dto.result.RemoveResultDto; +import org.nuiton.scmwebeditor.api.dto.result.UploadResultDto; import org.nuiton.util.FileUtil; import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; @@ -72,9 +79,7 @@ public class SvnConnection implements ScmConnection { /** the id of the HTTP session */ protected String pathToLocalRepos; - /** - * - */ + /** the manager which allows authentication */ protected SVNClientManager manager; @@ -1059,6 +1064,14 @@ public class SvnConnection implements ScmConnection { } + /** + * Gives the name of the person who made the last commit + * @param address the repository's address + * @param login the username to use to connect to the repository + * @param password the password to use to connect to the repository + * @return the name of the person who made the last commit + * @throws SVNException if there is a problem while accessing the repository + */ public String getHeadcommiter(String address, String login, String password) throws SVNException { ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(login, password); @@ -1077,8 +1090,13 @@ public class SvnConnection implements ScmConnection { } - - + /** + * Makes a list of the files and directories in the repository + * @param repository the repository to use to fetch information + * @param path the path to the directory (in the repository) to make the list from + * @param address the repository's address + * @param resultDto the DTO which will contain the files and directories found + */ public void listEntries(SVNRepository repository, String path, String address, BrowseResultDto resultDto) { Collection entries = null; @@ -1108,17 +1126,18 @@ public class SvnConnection implements ScmConnection { } } } - - } - public String getAddressUnique(String leFichier) { - String result = leFichier.replaceAll("/|:", ""); + /** + * Gives a unique address for the given file name + * @param fileName the name of the file + * @return a unique address for the file name + */ + public String getAddressUnique(String fileName) { + String result = fileName.replaceAll("/|:", ""); if (log.isDebugEnabled()) { - log.debug("Result of getAddressUnique : " + result + " ; " + leFichier); + log.debug("Result of getAddressUnique : " + result + " ; " + fileName); } return result; } - - } \ No newline at end of file diff --git a/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnProvider.java b/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnProvider.java index d69f1ed..f5b6c10 100644 --- a/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnProvider.java +++ b/swe-svn/src/main/java/org/nuiton/scmwebeditor/svn/SvnProvider.java @@ -25,12 +25,15 @@ package org.nuiton.scmwebeditor.svn; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.scmwebeditor.api.OperationNotSupportedException; +import org.nuiton.scmwebeditor.api.RepositoryNotFoundException; import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; +import org.nuiton.scmwebeditor.api.dto.CreateBranchDto; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; +import javax.naming.AuthenticationException; import java.util.List; /** @@ -57,7 +60,13 @@ public class SvnProvider implements ScmProvider { @Override public List<String> listBranches(String address, String username, String password) throws OperationNotSupportedException { - throw new OperationNotSupportedException("SVN repositories don't have branches"); + throw new OperationNotSupportedException("The 'list branches' operation is not available for SVN repositories"); + } + + @Override + public String createBranch(CreateBranchDto dto) throws OperationNotSupportedException, + AuthenticationException, RepositoryNotFoundException { + throw new OperationNotSupportedException("The 'create a branch' operation is not available for SVN repositories"); } @Override diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/BrowseAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/BrowseAction.java index 127837a..e2e790c 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/BrowseAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/BrowseAction.java @@ -31,7 +31,7 @@ import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; import org.nuiton.scmwebeditor.api.ScmWebEditorConfig; import org.nuiton.scmwebeditor.api.dto.BrowseDto; -import org.nuiton.scmwebeditor.api.dto.BrowseResultDto; +import org.nuiton.scmwebeditor.api.dto.result.BrowseResultDto; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/CreateBranchAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/CreateBranchAction.java new file mode 100644 index 0000000..ab66bf4 --- /dev/null +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/CreateBranchAction.java @@ -0,0 +1,201 @@ +/* + * #%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.ServletRequestAware; +import org.nuiton.scmwebeditor.api.*; +import org.nuiton.scmwebeditor.api.dto.CreateBranchDto; +import org.nuiton.scmwebeditor.api.dto.result.AbstractResultDto; + +import javax.naming.AuthenticationException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.io.File; +import java.util.List; + +/** + * Creates a new branch on the repository + */ +public class CreateBranchAction extends AbstractScmWebEditorAction implements ServletRequestAware { + + private static final Log log = LogFactory.getLog(CreateBranchAction.class); + + public static final String REDIRECT = "redirect"; + + /** the username to use to connect to the repository */ + protected String username; + + /** the password to use to connect to the repository */ + protected String pw; + + /** the repository's address */ + protected String address; + + /** equals true if there is a problem during the authentication process */ + protected boolean badLogin; + + /** equals true if an error occurs */ + protected boolean error; + + /** the list of all the repository's branches */ + protected List<String> branches; + + /** the selected branch to make the new branch from */ + protected String selectedBranch; + + /** the name of the new branch */ + protected String newBranchName; + + + public String getUsername() { return username; } + + public void setUsername(String username) { this.username = username; } + + public String getPw() { return pw; } + + public void setPw(String pw) { this.pw = pw; } + + public String getAddress() { return address; } + + public void setAddress(String address) { this.address = address; } + + public boolean isBadLogin() { return badLogin; } + + public void setBadLogin(boolean badLogin) { this.badLogin = badLogin; } + + public boolean isError() { return error; } + + public void setError(boolean error) { this.error = error; } + + public List<String> getBranches() { return branches; } + + public void setBranches(List<String> branches) { this.branches = branches; } + + public String getSelectedBranch() { return selectedBranch; } + + public void setSelectedBranch(String selectedBranch) { this.selectedBranch = selectedBranch; } + + public String getNewBranchName() { return newBranchName; } + + public void setNewBranchName(String newBranchName) { this.newBranchName = newBranchName; } + + /** + * Execution of the create branch action + * @return a code interpreted in the file struts.xml + */ + 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); + + // if the repository is not protected for writing, we get its UUID + if (address.endsWith("/")) { + address = address.substring(0, address.lastIndexOf('/')); + } + + String repositoryUUID = scmConn.getRepositoryId(); + if (repositoryUUID == null) { + repositoryUUID = address.replace(' ', '_'); + } + + String[] usernamePw = getUsernamePwFromSession(repositoryUUID, username, pw); + username = usernamePw[0]; + pw = usernamePw[1]; + + try { + branches = provider.listBranches(address, username, pw); + } catch (OperationNotSupportedException e) { + if (log.isErrorEnabled()) { + log.error("The SCM " + scmType + " does not support branches", e); + } + error = true; + + return ERROR; + } + + if (selectedBranch == null || newBranchName == null) { + + return REDIRECT; + } + + CreateBranchDto dto = new CreateBranchDto(); + dto.setAddress(address); + dto.setNewBranchName(newBranchName); + dto.setUsername(username); + dto.setPassword(pw); + dto.setPathToLocalRepos(pathToLocalRepos); + dto.setSelectedBranch(selectedBranch); + + String createBranchError; + + try { + createBranchError = provider.createBranch(dto); + } catch (OperationNotSupportedException e) { + if (log.isErrorEnabled()) { + log.error("Can not create a branch with SCM '" + scmType + "'", e); + } + error = true; + return ERROR; + } catch (AuthenticationException e) { + if (log.isErrorEnabled()) { + log.error("Authentication problem", e); + } + badLogin = true; + username = null; + pw = null; + return LOGIN; + } catch (RepositoryNotFoundException e) { + if (log.isErrorEnabled()) { + log.error("Can not reach repository at address " + address, e); + } + error = true; + return ERROR; + } + + if (createBranchError != null) { + if (createBranchError.equals(AbstractResultDto.AUTH_ERROR)) { + badLogin = true; + username = null; + pw = null; + return LOGIN; + } else { + error = true; + return ERROR; + } + } + + + return SUCCESS; + } + + @Override + public void setServletRequest(HttpServletRequest request) { + this.request = request; + } +} diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/RemoveAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/RemoveAction.java index 4de4099..4c372de 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/RemoveAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/RemoveAction.java @@ -28,7 +28,7 @@ import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; import org.nuiton.scmwebeditor.api.ScmWebEditorConfig; import org.nuiton.scmwebeditor.api.dto.RemoveDto; -import org.nuiton.scmwebeditor.api.dto.RemoveResultDto; +import org.nuiton.scmwebeditor.api.dto.result.RemoveResultDto; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ScmWebEditorCommitAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ScmWebEditorCommitAction.java index 3d28eb8..14ddd19 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ScmWebEditorCommitAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/ScmWebEditorCommitAction.java @@ -34,7 +34,7 @@ import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; import org.nuiton.scmwebeditor.api.ScmWebEditorConfig; import org.nuiton.scmwebeditor.api.dto.CommitDto; -import org.nuiton.scmwebeditor.api.dto.CommitResultDto; +import org.nuiton.scmwebeditor.api.dto.result.CommitResultDto; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; diff --git a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/UploadAction.java b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/UploadAction.java index f857f4b..a338de8 100644 --- a/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/UploadAction.java +++ b/swe-ui-web/src/main/java/org/nuiton/scmwebeditor/uiweb/actions/UploadAction.java @@ -28,7 +28,7 @@ import org.nuiton.scmwebeditor.api.ScmConnection; import org.nuiton.scmwebeditor.api.ScmProvider; import org.nuiton.scmwebeditor.api.ScmWebEditorConfig; import org.nuiton.scmwebeditor.api.dto.UploadDto; -import org.nuiton.scmwebeditor.api.dto.UploadResultDto; +import org.nuiton.scmwebeditor.api.dto.result.UploadResultDto; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; 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 a1d6e05..bd2d338 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,4 +1,4 @@ -scm.FileInEditor=File in editor \: +scm.FileInEditor=File in editor \: scm.atRevision=at revision scm.badPathOrFileName=Bad repository path or file name, or the file is not editable \! Please correct it. scm.badUsernameOrPassword=Bad username or password @@ -11,6 +11,10 @@ scm.close=Close scm.commitMessage=Commit message scm.commitMessageTitle=let a message for commit scm.connection=Connection +scm.createBranch=Create a new branch +scm.createBranch.branchName=Name of the new branch\: +scm.createBranch.originBranch=Original branch for the new branch\: +scm.createBranchSuccess=Branch successfully created scm.exit=Exit scm.exitJavascript=Exit ScmWebEditor without saving ? All modification will be lost. scm.exitTitle=Exit ScmWebEditor without saving. 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 f28223f..f54a5aa 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 @@ -11,6 +11,10 @@ scm.close=Fermer scm.commitMessage=Message associé au commit scm.commitMessageTitle=laisser un message pour le commit scm.connection=Connexion +scm.createBranch=Créer une nouvelle branche +scm.createBranch.branchName=Nom de la nouvelle branche \: +scm.createBranch.originBranch=Branche d'origine pour la nouvelle branche \: +scm.createBranchSuccess=Branche créée avec succès scm.exit=Quitter scm.exitJavascript=Quitter ScmWebEditor sans sauvegarder ? Toutes les modifications seront perdues. scm.exitTitle=Quitter ScmWebEditor sans sauvegarder. diff --git a/swe-ui-web/src/main/resources/struts.xml b/swe-ui-web/src/main/resources/struts.xml index 087a58d..6f6d65f 100644 --- a/swe-ui-web/src/main/resources/struts.xml +++ b/swe-ui-web/src/main/resources/struts.xml @@ -112,6 +112,13 @@ <result name="login" >/WEB-INF/content/removeForm.jsp</result> <result name="error" >/WEB-INF/content/removeForm.jsp</result> </action> + + <action name="createBranch" class="org.nuiton.scmwebeditor.uiweb.actions.CreateBranchAction"> + <result name="success">/WEB-INF/content/createBranchSuccess.jsp</result> + <result name="redirect">/WEB-INF/content/createBranchForm.jsp</result> + <result name="login">/WEB-INF/content/createBranchForm.jsp</result> + <result name="error">/WEB-INF/content/createBranchForm.jsp</result> + </action> <action name="preview" class="org.nuiton.scmwebeditor.uiweb.actions.PreviewAction"> <result>/WEB-INF/content/preview.jsp</result> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/browse.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/browse.jsp index 27099f0..fffb523 100644 --- a/swe-ui-web/src/main/webapp/WEB-INF/content/browse.jsp +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/browse.jsp @@ -91,6 +91,13 @@ <s:label id="selectedBranchDisplay" name="headBranchName"></s:label> </s:else> + + <s:set id="createBranch"> + <s:text name="scm.createBranch"/> + </s:set> + <s:submit type="button" value="%{createBranch}" + onClick="javascript:open_popup('createBranch.action', 'create branch' , getElementById('addressInput'), '%{scmType}' );"/> + </s:if> <div id="searchTree"> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/createBranchForm.jsp similarity index 52% copy from swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp copy to swe-ui-web/src/main/webapp/WEB-INF/content/createBranchForm.jsp index d22528a..2faf3ee 100644 --- a/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/createBranchForm.jsp @@ -31,10 +31,8 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <title><s:text name="scm.removeFile"/></title> + <title><s:text name="scm.createBranch"/></title> <link rel="stylesheet" type="text/css" href="css/main.css"> - <link rel="stylesheet" type="text/css" href="css/uploadForm.css"> - <script type="text/javascript" src="js/branches.js"></script> </head> @@ -42,67 +40,17 @@ <sj:head debug="true" jquerytheme="default"/> -<script> - var foo; - - $.subscribe('treeClicked', function(event, data) { - var item = event.originalEvent.data.rslt.obj; - - if (item.length == 1) { - var classAttr = item[0].getAttribute("class"); - - if (classAttr.contains("jstree-leaf")) { - window.document.getElementById("scmPath").value = item.attr("id"); - } - } - - }); - - // automatically expand the directory when there is no other file - $.subscribe('treeChanged', function(event, data) { - - var json = event.originalEvent.data.responseJSON; - - if (json.length == 1) { - var object = json[0]; - - if (object.title.startsWith('/')) { - var htmlObject = document.getElementById(object.id); - var children = htmlObject.children; - children.item('ins').click(); - } - } - }); - -</script> - - -<form method="POST" id="removeForm" action="doRemove.action"> +<form method="POST" id="removeForm" action="createBranch.action"> <s:hidden name="scmType" value="%{scmType}"/> - <center><h1><s:text name="scm.removeFile"></s:text></h1></center> - - <label><s:text name="scm.remove.file"/> <s:textfield size="50px" type="text" - name="scmPath" - id="scmPath" - value="%{fileRoot}"/></label> + <center><h1><s:text name="scm.createBranch"/></h1></center> - <div id="searchTree"> - - <s:url id="searchTreeUrl" - action="browse?address=%{scmRoot}&username=%{username}&pw=%{pw}&selectedBranch=%{selectedBranch}&scmType=%{scmType}"/> - <sjt:tree id="scmTree" - htmlTitles="true" - jstreetheme="classic" - href="%{searchTreeUrl}" - onClickTopics="treeClicked" - onSuccessTopics="treeChanged" - /> - - </div> + <label for="branchName"><s:text name="scm.createBranch.branchName"/></label> <input type="text" id="newBranchName" name="newBranchName"/><br/> + <label for="selectedBranch"><s:text name="scm.createBranch.originBranch"/></label> + <s:select id="selectedBranch" name="selectedBranch" list="branches"/><br/> <s:if test="username==null || pw==null"> <label><s:text name="scm.username"/> : <input type="text" name="username"/></label><br/> @@ -122,6 +70,7 @@ <s:elseif test="error"> <p><font color="red"><s:text name="scm.repoError"/></font></p> </s:elseif> + <input type="submit"/> </form> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/createBranchSuccess.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/createBranchSuccess.jsp new file mode 100644 index 0000000..332117b --- /dev/null +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/createBranchSuccess.jsp @@ -0,0 +1,44 @@ +<%-- + #%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 language="java" contentType="text/html; charset=UTF-8" + 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"> + <link rel="stylesheet" type="text/css" href="css/main.css"> + <title><s:text name="scm.titles.success"/></title> +</head> +<body> +<p><s:text name="scm.createBranchSuccess"/></p> + +<s:set id="close"> + <s:text name="scm.close"/> +</s:set> + +<form> + <s:submit type="button" value="%{close}" onclick="window.close()"/> +</form> +</body> +</html> diff --git a/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp b/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp index d22528a..4887412 100644 --- a/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp +++ b/swe-ui-web/src/main/webapp/WEB-INF/content/removeForm.jsp @@ -33,7 +33,6 @@ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><s:text name="scm.removeFile"/></title> <link rel="stylesheet" type="text/css" href="css/main.css"> - <link rel="stylesheet" type="text/css" href="css/uploadForm.css"> <script type="text/javascript" src="js/branches.js"></script> @@ -44,8 +43,6 @@ <script> - var foo; - $.subscribe('treeClicked', function(event, data) { var item = event.originalEvent.data.rslt.obj; diff --git a/swe-ui-web/src/main/webapp/js/popup.js b/swe-ui-web/src/main/webapp/js/popup.js index 343d5bb..2775807 100644 --- a/swe-ui-web/src/main/webapp/js/popup.js +++ b/swe-ui-web/src/main/webapp/js/popup.js @@ -2,7 +2,7 @@ * #%L * ScmWebEditor * %% - * Copyright (C) 2009 - 2011 CodeLutin + * 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 -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.