]> source.dussan.org Git - gitblit.git/commitdiff
Moved the fork mechanism from a javascript link to a separate page
authorJames Moger <james.moger@gitblit.com>
Tue, 2 Oct 2012 21:23:16 +0000 (17:23 -0400)
committerJames Moger <james.moger@gitblit.com>
Tue, 2 Oct 2012 21:23:16 +0000 (17:23 -0400)
resources/git-black.png [new file with mode: 0644]
src/com/gitblit/GitBlit.java
src/com/gitblit/models/RepositoryModel.java
src/com/gitblit/wicket/GitBlitWebApp.java
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/GitBlitWebSession.java
src/com/gitblit/wicket/pages/ForkPage.html [new file with mode: 0644]
src/com/gitblit/wicket/pages/ForkPage.java [new file with mode: 0644]
src/com/gitblit/wicket/pages/RepositoryPage.java
src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
src/com/gitblit/wicket/panels/RepositoriesPanel.java

diff --git a/resources/git-black.png b/resources/git-black.png
new file mode 100644 (file)
index 0000000..8bc4c43
Binary files /dev/null and b/resources/git-black.png differ
index 51c44f662bd394506fa81c8c0c602a8ab1052a3f..4ada74814120f20e30b61b088ec002a8fec5aef5 100644 (file)
@@ -2637,44 +2637,45 @@ public class GitBlit implements ServletContextListener {
         * \r
         * @param repository\r
         * @param user\r
-        * @return true, if successful\r
+        * @return the repository model of the fork, if successful\r
+        * @throws GitBlitException\r
         */\r
-       public boolean fork(RepositoryModel repository, UserModel user) {\r
+       public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {\r
                String cloneName = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));\r
                String fromUrl = MessageFormat.format("file://{0}/{1}", repositoriesFolder.getAbsolutePath(), repository.name);\r
+\r
+               // clone the repository\r
                try {\r
-                       // clone the repository\r
                        JGitUtils.cloneRepository(repositoriesFolder, cloneName, fromUrl, true, null);\r
-                       \r
-                       // create a Gitblit repository model for the clone\r
-                       RepositoryModel cloneModel = repository.cloneAs(cloneName);\r
-                       cloneModel.owner = user.username;\r
-                       updateRepositoryModel(cloneName, cloneModel, false);\r
-                       \r
-                       if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {\r
-                               // add the owner of the source repository to the clone's access list\r
-                               if (!StringUtils.isEmpty(repository.owner)) {\r
-                                       UserModel owner = getUserModel(repository.owner);\r
-                                       if (owner != null) {\r
-                                               owner.repositories.add(cloneName);\r
-                                               updateUserModel(owner.username, owner, false);\r
-                                       }\r
+               } catch (Exception e) {\r
+                       throw new GitBlitException(e);\r
+               }\r
+\r
+               // create a Gitblit repository model for the clone\r
+               RepositoryModel cloneModel = repository.cloneAs(cloneName);\r
+               cloneModel.owner = user.username;\r
+               updateRepositoryModel(cloneName, cloneModel, false);\r
+\r
+               if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {\r
+                       // add the owner of the source repository to the clone's access list\r
+                       if (!StringUtils.isEmpty(repository.owner)) {\r
+                               UserModel owner = getUserModel(repository.owner);\r
+                               if (owner != null) {\r
+                                       owner.repositories.add(cloneName);\r
+                                       updateUserModel(owner.username, owner, false);\r
                                }\r
-                               \r
-                               // inherit origin's access lists\r
-                               List<String> users = getRepositoryUsers(repository);\r
-                               setRepositoryUsers(cloneModel, users);\r
-                               \r
-                               List<String> teams = getRepositoryTeams(repository);\r
-                               setRepositoryTeams(cloneModel, teams);\r
                        }\r
-                       \r
-                       // add this clone to the cached model\r
-                       addToCachedRepositoryList(cloneModel.name, cloneModel);\r
-                       return true;\r
-               } catch (Exception e) {\r
-                       logger.error("failed to fork", e);\r
+\r
+                       // inherit origin's access lists\r
+                       List<String> users = getRepositoryUsers(repository);\r
+                       setRepositoryUsers(cloneModel, users);\r
+\r
+                       List<String> teams = getRepositoryTeams(repository);\r
+                       setRepositoryTeams(cloneModel, teams);\r
                }\r
-               return false;\r
+\r
+               // add this clone to the cached model\r
+               addToCachedRepositoryList(cloneModel.name, cloneModel);\r
+               return cloneModel;\r
        }\r
 }\r
index 44aba1d8698615a14988974d4516debf708602ba..3148b5b4b2fb9876ea93fd063e2c40b76c066f49 100644 (file)
@@ -145,7 +145,10 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel
        \r
        public RepositoryModel cloneAs(String cloneName) {\r
                RepositoryModel clone = new RepositoryModel();\r
+               clone.originRepository = name;\r
                clone.name = cloneName;\r
+               clone.projectPath = StringUtils.getFirstPathElement(cloneName);\r
+               clone.isBare = true;\r
                clone.description = description;\r
                clone.accessRestriction = accessRestriction;\r
                clone.authorizationControl = authorizationControl;\r
index b691cea41dc6c6cb9ae375bca6312ff6e70b2509..245b1e056a2b931bdcce8fdbe0909a7c93548d4c 100644 (file)
@@ -34,6 +34,7 @@ import com.gitblit.wicket.pages.CommitDiffPage;
 import com.gitblit.wicket.pages.CommitPage;\r
 import com.gitblit.wicket.pages.DocsPage;\r
 import com.gitblit.wicket.pages.FederationRegistrationPage;\r
+import com.gitblit.wicket.pages.ForkPage;\r
 import com.gitblit.wicket.pages.ForksPage;\r
 import com.gitblit.wicket.pages.GitSearchPage;\r
 import com.gitblit.wicket.pages.GravatarProfilePage;\r
@@ -120,6 +121,7 @@ public class GitBlitWebApp extends WebApplication {
                mount("/projects", ProjectsPage.class);\r
                mount("/user", UserPage.class, "user");\r
                mount("/forks", ForksPage.class, "r");\r
+               mount("/fork", ForkPage.class, "r");\r
        }\r
 \r
        private void mount(String location, Class<? extends WebPage> clazz, String... parameters) {\r
index d30f57103af0398320b8b1619f957378be818ac1..e0bb66927666fbea242f6ec1c94825a9423cbc49 100644 (file)
@@ -323,7 +323,7 @@ gb.fork = fork
 gb.forks = forks\r
 gb.forkRepository = fork {0}?\r
 gb.repositoryForked = {0} has been forked\r
-gb.repositoryForkFailed= failed to fork {1}\r
+gb.repositoryForkFailed= fork has failed\r
 gb.personalRepositories = personal repositories\r
 gb.allowForks = allow forks\r
 gb.allowForksDescription = allow authorized users to fork this repository\r
@@ -333,4 +333,7 @@ gb.canForkDescription = user is permitted to fork authorized repositories
 gb.myFork = view my fork\r
 gb.forksProhibited = forks prohibited\r
 gb.forksProhibitedWarning = this repository forbids forks\r
-gb.noForks = {0} has no forks
\ No newline at end of file
+gb.noForks = {0} has no forks\r
+gb.forkNotAuthorized = sorry, you are not authorized to fork {0}\r
+gb.forkInProgress = fork in progress\r
+gb.preparingFork = Gitblit is preparing your fork
\ No newline at end of file
index 7ecc05b2ab497f9e2c57d8cc98d2a76efb9578e1..0e1ae5123f1ea17bc7c33674f1c3144e374831a4 100644 (file)
@@ -17,6 +17,7 @@ package com.gitblit.wicket;
 \r
 import java.util.Map;\r
 import java.util.TimeZone;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
 \r
 import org.apache.wicket.Page;\r
 import org.apache.wicket.PageParameters;\r
@@ -42,8 +43,11 @@ public final class GitBlitWebSession extends WebSession {
        \r
        private String requestUrl;\r
        \r
+       private AtomicBoolean isForking;\r
+       \r
        public GitBlitWebSession(Request request) {\r
                super(request);\r
+               isForking = new AtomicBoolean();\r
        }\r
 \r
        public void invalidate() {\r
@@ -134,6 +138,14 @@ public final class GitBlitWebSession extends WebSession {
                errorMessage = null;\r
                return msg;\r
        }\r
+       \r
+       public boolean isForking() {\r
+               return isForking.get();\r
+       }\r
+       \r
+       public void isForking(boolean val) {\r
+               isForking.set(val);\r
+       }\r
 \r
        public static GitBlitWebSession get() {\r
                return (GitBlitWebSession) Session.get();\r
diff --git a/src/com/gitblit/wicket/pages/ForkPage.html b/src/com/gitblit/wicket/pages/ForkPage.html
new file mode 100644 (file)
index 0000000..7d2d2aa
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml"  \r
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  \r
+      xml:lang="en"  \r
+      lang="en"> \r
+\r
+<body>\r
+<wicket:head>\r
+       <noscript>\r
+               <meta http-equiv="refresh" content="5"></meta>\r
+       </noscript>\r
+       <script type="text/javascript"">\r
+               function doLoad() { setTimeout( "refresh()", 5*1000 ); }\r
+               function refresh() { window.location.reload(); }\r
+       </script>\r
+</wicket:head>\r
+<wicket:extend>\r
+<!-- need to specify body.onload -->\r
+<body onload="doLoad()">\r
+\r
+       <div class="row">\r
+               <div class="span6 offset3">\r
+                       <div wicket:id="forkText" class="pageTitle project" style="border:0;font-weight:bold; text-align:center;">[fork text]</div>\r
+               </div>\r
+               <div class="span4 offset4">\r
+                       <div class="progress progress-striped active">\r
+                               <div class="bar" style="width: 100%;"></div>\r
+                       </div>\r
+               </div>\r
+               <div class="span6 offset3">\r
+                       <div style="opacity:0.2;">\r
+                               <center><img style="padding:10px" src="git-black.png"></img></center>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+</body>\r
+\r
+</wicket:extend>       \r
+</body>\r
+</html>
\ 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 (file)
index 0000000..082dab5
--- /dev/null
@@ -0,0 +1,107 @@
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.pages;\r
+\r
+import java.text.MessageFormat;\r
+\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.GitblitRedirectException;\r
+import com.gitblit.wicket.WicketUtils;\r
+\r
+public class ForkPage extends RepositoryPage {\r
+\r
+\r
+       public ForkPage(PageParameters params) {\r
+               super(params);\r
+\r
+               setVersioned(false);\r
+               \r
+               GitBlitWebSession session = GitBlitWebSession.get();\r
+\r
+               RepositoryModel repository = getRepositoryModel();\r
+               UserModel user = session.getUser();\r
+               boolean canFork = user.canForkRepository(repository);\r
+\r
+               if (!canFork) {\r
+                       // redirect to the summary page if this repository is not empty\r
+                       GitBlitWebSession.get().cacheErrorMessage(\r
+                                       MessageFormat.format(getString("gb.forkNotAuthorized"), repository.name));\r
+                       throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(repository.name));\r
+               }\r
+\r
+               String fork = GitBlit.self().getFork(user.username, repository.name);\r
+               if (fork != null) {\r
+                       // redirect to user's fork\r
+                       throw new GitblitRedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(fork));\r
+               }\r
+\r
+               add(new Label("forkText", getString("gb.preparingFork")));\r
+\r
+               if (!session.isForking()) {\r
+                       // prepare session\r
+                       session.isForking(true);\r
+\r
+                       // fork it\r
+                       ForkThread forker = new ForkThread(repository, session);\r
+                       forker.start();\r
+               }\r
+       }\r
+\r
+       @Override\r
+       protected boolean allowForkControls() {\r
+               return false;\r
+       }\r
+\r
+       @Override\r
+       protected String getPageName() {\r
+               return "fork";\r
+       }\r
+\r
+       /**\r
+        * ForkThread does the work of working the repository in a background\r
+        * thread. The completion status is tracked through a session variable and\r
+        * monitored by this page.\r
+        */\r
+       private static class ForkThread extends Thread {\r
+\r
+               private final RepositoryModel repository;\r
+               private final GitBlitWebSession session;\r
+\r
+               public ForkThread(RepositoryModel repository, GitBlitWebSession session) {\r
+                       this.repository = repository;\r
+                       this.session = session;\r
+               }\r
+\r
+               @Override\r
+               public void run() {\r
+                       UserModel user = session.getUser();\r
+                       try {\r
+                               GitBlit.self().fork(repository, user);\r
+                       } catch (Exception e) {\r
+                               LoggerFactory.getLogger(ForkPage.class).error(MessageFormat.format("Failed to fork {0} for {1}", repository.name, user.username), e);\r
+                       } finally {\r
+                               session.isForking(false);\r
+                       }\r
+               }\r
+       }\r
+}\r
index 8ca2b335e499325ea08729369e2ef27687b6ec65..879c43212a9525e8433820f041554cee7476cc90 100644 (file)
@@ -28,12 +28,10 @@ import java.util.Set;
 \r
 import org.apache.wicket.Component;\r
 import org.apache.wicket.PageParameters;\r
-import org.apache.wicket.RedirectException;\r
 import org.apache.wicket.markup.html.basic.Label;\r
 import org.apache.wicket.markup.html.form.DropDownChoice;\r
 import org.apache.wicket.markup.html.form.TextField;\r
 import org.apache.wicket.markup.html.link.ExternalLink;\r
-import org.apache.wicket.markup.html.link.Link;\r
 import org.apache.wicket.markup.html.panel.Fragment;\r
 import org.apache.wicket.model.IModel;\r
 import org.apache.wicket.model.Model;\r
@@ -62,7 +60,6 @@ import com.gitblit.wicket.PageRegistration;
 import com.gitblit.wicket.PageRegistration.OtherPageLink;\r
 import com.gitblit.wicket.SessionlessForm;\r
 import com.gitblit.wicket.WicketUtils;\r
-import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation;\r
 import com.gitblit.wicket.panels.LinkPanel;\r
 import com.gitblit.wicket.panels.NavigationPanel;\r
 import com.gitblit.wicket.panels.RefsPanel;\r
@@ -171,6 +168,10 @@ public abstract class RepositoryPage extends BasePage {
                }\r
                return pages;\r
        }\r
+       \r
+       protected boolean allowForkControls() {\r
+               return true;\r
+       }\r
 \r
        @Override\r
        protected void setupPage(String repositoryName, String pageName) {\r
@@ -230,7 +231,7 @@ public abstract class RepositoryPage extends BasePage {
                }\r
 \r
                // fork controls\r
-               if (user == null) {\r
+               if (!allowForkControls() || user == null) {\r
                        // must be logged-in to fork, hide all fork controls\r
                        add(new ExternalLink("forkLink", "").setVisible(false));\r
                        add(new ExternalLink("myForkLink", "").setVisible(false));\r
@@ -268,25 +269,8 @@ public abstract class RepositoryPage extends BasePage {
                                // can fork and we do not have one\r
                                add(new Label("forksProhibitedIndicator").setVisible(false));\r
                                add(new ExternalLink("myForkLink", "").setVisible(false));\r
-                               Link<Void> forkLink = new Link<Void>("forkLink") {\r
-\r
-                                       private static final long serialVersionUID = 1L;\r
-\r
-                                       @Override\r
-                                       public void onClick() {\r
-                                               UserModel user = GitBlitWebSession.get().getUser();\r
-                                               RepositoryModel model = getRepositoryModel();\r
-                                               String asFork = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(model.name)));\r
-                                               if (GitBlit.self().fork(model, GitBlitWebSession.get().getUser())) {\r
-                                                       throw new RedirectException(SummaryPage.class, WicketUtils.newRepositoryParameter(asFork));\r
-                                               } else {\r
-                                                       error(MessageFormat.format(getString("gb.repositoryForkFailed"), model));\r
-                                               }\r
-                                       }\r
-                               };\r
-                               forkLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(\r
-                                               getString("gb.forkRepository"), getRepositoryModel())));\r
-                               add(forkLink);\r
+                               String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();\r
+                               add(new ExternalLink("forkLink", url));\r
                        }\r
                }\r
                \r
index 6f693ee043cb76c9cbecaa5c29f527b8a03b67a6..0a6bc62368e1e83dee4c435657b4d861adea37a8 100644 (file)
@@ -22,7 +22,6 @@ import java.util.Map;
 \r
 import org.apache.wicket.Component;\r
 import org.apache.wicket.Localizer;\r
-import org.apache.wicket.Page;\r
 import org.apache.wicket.PageParameters;\r
 import org.apache.wicket.markup.html.basic.Label;\r
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
@@ -153,7 +152,6 @@ public class ProjectRepositoryPanel extends BasePanel {
                                        @Override\r
                                        public void onClick() {\r
                                                if (GitBlit.self().deleteRepositoryModel(entry)) {\r
-                                                       info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));\r
                                                        // redirect to the owning page\r
                                                        if (entry.isPersonalRepository()) {\r
                                                                setResponsePage(getPage().getClass(), WicketUtils.newUsernameParameter(entry.projectPath.substring(1)));\r
index 4c9ed280149a96bedc49b19f13ac174a707e85cf..1967b501b7893a30cf8ffc3d9a83f8f99b9635dc 100644 (file)
@@ -305,11 +305,11 @@ public class RepositoriesPanel extends BasePanel {
                                                @Override\r
                                                public void onClick() {\r
                                                        if (GitBlit.self().deleteRepositoryModel(entry)) {\r
-                                                               info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));\r
                                                                if (dp instanceof SortableRepositoriesProvider) {\r
+                                                                       info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));\r
                                                                        ((SortableRepositoriesProvider) dp).remove(entry);\r
                                                                } else {\r
-                                                                       ((RepositoriesProvider) dp).remove(entry);\r
+                                                                       setResponsePage(getPage().getClass(), getPage().getPageParameters());\r
                                                                }\r
                                                        } else {\r
                                                                error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));\r