From: James Moger Date: Tue, 2 Oct 2012 21:23:16 +0000 (-0400) Subject: Moved the fork mechanism from a javascript link to a separate page X-Git-Tag: v1.2.0~197 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1f52c8b5f123b97fc631465479bc2855c12b9ee3;p=gitblit.git Moved the fork mechanism from a javascript link to a separate page --- diff --git a/resources/git-black.png b/resources/git-black.png new file mode 100644 index 00000000..8bc4c439 Binary files /dev/null and b/resources/git-black.png differ diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 51c44f66..4ada7481 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -2637,44 +2637,45 @@ public class GitBlit implements ServletContextListener { * * @param repository * @param user - * @return true, if successful + * @return the repository model of the fork, if successful + * @throws GitBlitException */ - public boolean fork(RepositoryModel repository, UserModel user) { + public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException { String cloneName = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name))); String fromUrl = MessageFormat.format("file://{0}/{1}", repositoriesFolder.getAbsolutePath(), repository.name); + + // clone the repository try { - // clone the repository JGitUtils.cloneRepository(repositoriesFolder, cloneName, fromUrl, true, null); - - // create a Gitblit repository model for the clone - RepositoryModel cloneModel = repository.cloneAs(cloneName); - cloneModel.owner = user.username; - updateRepositoryModel(cloneName, cloneModel, false); - - if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) { - // add the owner of the source repository to the clone's access list - if (!StringUtils.isEmpty(repository.owner)) { - UserModel owner = getUserModel(repository.owner); - if (owner != null) { - owner.repositories.add(cloneName); - updateUserModel(owner.username, owner, false); - } + } catch (Exception e) { + throw new GitBlitException(e); + } + + // create a Gitblit repository model for the clone + RepositoryModel cloneModel = repository.cloneAs(cloneName); + cloneModel.owner = user.username; + updateRepositoryModel(cloneName, cloneModel, false); + + if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) { + // add the owner of the source repository to the clone's access list + if (!StringUtils.isEmpty(repository.owner)) { + UserModel owner = getUserModel(repository.owner); + if (owner != null) { + owner.repositories.add(cloneName); + updateUserModel(owner.username, owner, false); } - - // inherit origin's access lists - List users = getRepositoryUsers(repository); - setRepositoryUsers(cloneModel, users); - - List teams = getRepositoryTeams(repository); - setRepositoryTeams(cloneModel, teams); } - - // add this clone to the cached model - addToCachedRepositoryList(cloneModel.name, cloneModel); - return true; - } catch (Exception e) { - logger.error("failed to fork", e); + + // inherit origin's access lists + List users = getRepositoryUsers(repository); + setRepositoryUsers(cloneModel, users); + + List teams = getRepositoryTeams(repository); + setRepositoryTeams(cloneModel, teams); } - return false; + + // add this clone to the cached model + addToCachedRepositoryList(cloneModel.name, cloneModel); + return cloneModel; } } diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java index 44aba1d8..3148b5b4 100644 --- a/src/com/gitblit/models/RepositoryModel.java +++ b/src/com/gitblit/models/RepositoryModel.java @@ -145,7 +145,10 @@ public class RepositoryModel implements Serializable, Comparable clazz, String... parameters) { diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index d30f5710..e0bb6692 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -323,7 +323,7 @@ gb.fork = fork gb.forks = forks gb.forkRepository = fork {0}? gb.repositoryForked = {0} has been forked -gb.repositoryForkFailed= failed to fork {1} +gb.repositoryForkFailed= fork has failed gb.personalRepositories = personal repositories gb.allowForks = allow forks gb.allowForksDescription = allow authorized users to fork this repository @@ -333,4 +333,7 @@ gb.canForkDescription = user is permitted to fork authorized repositories gb.myFork = view my fork gb.forksProhibited = forks prohibited gb.forksProhibitedWarning = this repository forbids forks -gb.noForks = {0} has no forks \ No newline at end of file +gb.noForks = {0} has no forks +gb.forkNotAuthorized = sorry, you are not authorized to fork {0} +gb.forkInProgress = fork in progress +gb.preparingFork = Gitblit is preparing your fork \ No newline at end of file diff --git a/src/com/gitblit/wicket/GitBlitWebSession.java b/src/com/gitblit/wicket/GitBlitWebSession.java index 7ecc05b2..0e1ae512 100644 --- a/src/com/gitblit/wicket/GitBlitWebSession.java +++ b/src/com/gitblit/wicket/GitBlitWebSession.java @@ -17,6 +17,7 @@ package com.gitblit.wicket; import java.util.Map; import java.util.TimeZone; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.wicket.Page; import org.apache.wicket.PageParameters; @@ -42,8 +43,11 @@ public final class GitBlitWebSession extends WebSession { private String requestUrl; + private AtomicBoolean isForking; + public GitBlitWebSession(Request request) { super(request); + isForking = new AtomicBoolean(); } public void invalidate() { @@ -134,6 +138,14 @@ public final class GitBlitWebSession extends WebSession { errorMessage = null; return msg; } + + public boolean isForking() { + return isForking.get(); + } + + public void isForking(boolean val) { + isForking.set(val); + } public static GitBlitWebSession get() { return (GitBlitWebSession) Session.get(); diff --git a/src/com/gitblit/wicket/pages/ForkPage.html b/src/com/gitblit/wicket/pages/ForkPage.html new file mode 100644 index 00000000..7d2d2aa5 --- /dev/null +++ b/src/com/gitblit/wicket/pages/ForkPage.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + +
+
+
[fork text]
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+ + \ No newline at end of file diff --git a/src/com/gitblit/wicket/pages/ForkPage.java b/src/com/gitblit/wicket/pages/ForkPage.java new file mode 100644 index 00000000..082dab51 --- /dev/null +++ b/src/com/gitblit/wicket/pages/ForkPage.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket.pages; + +import java.text.MessageFormat; + +import org.apache.wicket.PageParameters; +import org.apache.wicket.markup.html.basic.Label; +import org.slf4j.LoggerFactory; + +import com.gitblit.GitBlit; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.UserModel; +import com.gitblit.wicket.GitBlitWebSession; +import com.gitblit.wicket.GitblitRedirectException; +import com.gitblit.wicket.WicketUtils; + +public class ForkPage extends RepositoryPage { + + + public ForkPage(PageParameters params) { + super(params); + + setVersioned(false); + + GitBlitWebSession session = GitBlitWebSession.get(); + + RepositoryModel repository = getRepositoryModel(); + UserModel user = session.getUser(); + boolean canFork = user.canForkRepository(repository); + + if (!canFork) { + // redirect to the summary page if this repository is not empty + GitBlitWebSession.get().cacheErrorMessage( + MessageFormat.format(getString("gb.forkNotAuthorized"), repository.name)); + throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(repository.name)); + } + + String fork = GitBlit.self().getFork(user.username, repository.name); + if (fork != null) { + // redirect to user's fork + throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)); + } + + add(new Label("forkText", getString("gb.preparingFork"))); + + if (!session.isForking()) { + // prepare session + session.isForking(true); + + // fork it + ForkThread forker = new ForkThread(repository, session); + forker.start(); + } + } + + @Override + protected boolean allowForkControls() { + return false; + } + + @Override + protected String getPageName() { + return "fork"; + } + + /** + * ForkThread does the work of working the repository in a background + * thread. The completion status is tracked through a session variable and + * monitored by this page. + */ + private static class ForkThread extends Thread { + + private final RepositoryModel repository; + private final GitBlitWebSession session; + + public ForkThread(RepositoryModel repository, GitBlitWebSession session) { + this.repository = repository; + this.session = session; + } + + @Override + public void run() { + UserModel user = session.getUser(); + try { + GitBlit.self().fork(repository, user); + } catch (Exception e) { + LoggerFactory.getLogger(ForkPage.class).error(MessageFormat.format("Failed to fork {0} for {1}", repository.name, user.username), e); + } finally { + session.isForking(false); + } + } + } +} diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index 8ca2b335..879c4321 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -28,12 +28,10 @@ import java.util.Set; import org.apache.wicket.Component; import org.apache.wicket.PageParameters; -import org.apache.wicket.RedirectException; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.link.ExternalLink; -import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; @@ -62,7 +60,6 @@ import com.gitblit.wicket.PageRegistration; import com.gitblit.wicket.PageRegistration.OtherPageLink; import com.gitblit.wicket.SessionlessForm; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation; import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.NavigationPanel; import com.gitblit.wicket.panels.RefsPanel; @@ -171,6 +168,10 @@ public abstract class RepositoryPage extends BasePage { } return pages; } + + protected boolean allowForkControls() { + return true; + } @Override protected void setupPage(String repositoryName, String pageName) { @@ -230,7 +231,7 @@ public abstract class RepositoryPage extends BasePage { } // fork controls - if (user == null) { + if (!allowForkControls() || user == null) { // must be logged-in to fork, hide all fork controls add(new ExternalLink("forkLink", "").setVisible(false)); add(new ExternalLink("myForkLink", "").setVisible(false)); @@ -268,25 +269,8 @@ public abstract class RepositoryPage extends BasePage { // can fork and we do not have one add(new Label("forksProhibitedIndicator").setVisible(false)); add(new ExternalLink("myForkLink", "").setVisible(false)); - Link forkLink = new Link("forkLink") { - - private static final long serialVersionUID = 1L; - - @Override - public void onClick() { - UserModel user = GitBlitWebSession.get().getUser(); - RepositoryModel model = getRepositoryModel(); - String asFork = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(model.name))); - if (GitBlit.self().fork(model, GitBlitWebSession.get().getUser())) { - throw new RedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(asFork)); - } else { - error(MessageFormat.format(getString("gb.repositoryForkFailed"), model)); - } - } - }; - forkLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( - getString("gb.forkRepository"), getRepositoryModel()))); - add(forkLink); + String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString(); + add(new ExternalLink("forkLink", url)); } } diff --git a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java index 6f693ee0..0a6bc623 100644 --- a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java +++ b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java @@ -22,7 +22,6 @@ import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.Localizer; -import org.apache.wicket.Page; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; @@ -153,7 +152,6 @@ public class ProjectRepositoryPanel extends BasePanel { @Override public void onClick() { if (GitBlit.self().deleteRepositoryModel(entry)) { - info(MessageFormat.format(getString("gb.repositoryDeleted"), entry)); // redirect to the owning page if (entry.isPersonalRepository()) { setResponsePage(getPage().getClass(), WicketUtils.newUsernameParameter(entry.projectPath.substring(1))); diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java index 4c9ed280..1967b501 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java @@ -305,11 +305,11 @@ public class RepositoriesPanel extends BasePanel { @Override public void onClick() { if (GitBlit.self().deleteRepositoryModel(entry)) { - info(MessageFormat.format(getString("gb.repositoryDeleted"), entry)); if (dp instanceof SortableRepositoriesProvider) { + info(MessageFormat.format(getString("gb.repositoryDeleted"), entry)); ((SortableRepositoriesProvider) dp).remove(entry); } else { - ((RepositoriesProvider) dp).remove(entry); + setResponsePage(getPage().getClass(), getPage().getPageParameters()); } } else { error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));