From e94078b80f2ff1090e62e210baf687d241b32c3a Mon Sep 17 00:00:00 2001 From: James Moger Date: Wed, 3 Oct 2012 09:18:51 -0400 Subject: [PATCH] Display entire fork network. Link as appropriate for user permissions. --- src/com/gitblit/GitBlit.java | 2 +- src/com/gitblit/models/ForkModel.java | 13 +- src/com/gitblit/models/RepositoryModel.java | 17 ++ src/com/gitblit/models/UserModel.java | 7 + src/com/gitblit/wicket/pages/ForksPage.html | 19 +- src/com/gitblit/wicket/pages/ForksPage.java | 197 +++++++++----------- 6 files changed, 122 insertions(+), 133 deletions(-) diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 4ada7481..1ebc4c70 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -1425,7 +1425,7 @@ public class GitBlit implements ServletContextListener { private ForkModel getForkModel(String repository) { RepositoryModel model = repositoryListCache.get(repository); - ForkModel fork = new ForkModel(model.originRepository, model.name); + ForkModel fork = new ForkModel(model); if (!ArrayUtils.isEmpty(model.forks)) { for (String aFork : model.forks) { ForkModel fm = getForkModel(aFork); diff --git a/src/com/gitblit/models/ForkModel.java b/src/com/gitblit/models/ForkModel.java index b394396b..849986c1 100644 --- a/src/com/gitblit/models/ForkModel.java +++ b/src/com/gitblit/models/ForkModel.java @@ -32,20 +32,17 @@ public class ForkModel implements Serializable { private static final long serialVersionUID = 1L; - public final String originRepository; - - public final String repository; + public final RepositoryModel repository; public final List forks; - public ForkModel(String origin, String repository) { - this.originRepository = origin; + public ForkModel(RepositoryModel repository) { this.repository = repository; this.forks = new ArrayList(); } public boolean isRoot() { - return StringUtils.isEmpty(originRepository); + return StringUtils.isEmpty(repository.originRepository); } public boolean isNode() { @@ -57,7 +54,7 @@ public class ForkModel implements Serializable { } public boolean isPersonalRepository() { - return repository.charAt(0) == '~'; + return repository.isPersonalRepository(); } @Override @@ -75,6 +72,6 @@ public class ForkModel implements Serializable { @Override public String toString() { - return repository; + return repository.toString(); } } diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java index 3148b5b4..a28536d1 100644 --- a/src/com/gitblit/models/RepositoryModel.java +++ b/src/com/gitblit/models/RepositoryModel.java @@ -121,6 +121,19 @@ public class RepositoryModel implements Serializable, Comparable private static final long serialVersionUID = 1L; + public static final UserModel ANONYMOUS = new UserModel("anonymous", false); + // field names are reflectively mapped in EditUser page public String username; public String password; @@ -56,6 +58,11 @@ public class UserModel implements Principal, Serializable, Comparable this.isAuthenticated = true; } + private UserModel(String username, boolean authenticated) { + this.username = username; + this.isAuthenticated = authenticated; + } + /** * This method does not take into consideration Ownership where the * administrator has not explicitly granted access to the owner. diff --git a/src/com/gitblit/wicket/pages/ForksPage.html b/src/com/gitblit/wicket/pages/ForksPage.html index f59f9ca2..c18d2a49 100644 --- a/src/com/gitblit/wicket/pages/ForksPage.html +++ b/src/com/gitblit/wicket/pages/ForksPage.html @@ -7,27 +7,14 @@ -
-
- - - [a project] / [a fork] -
-
[origin repository]
-
-
-
- +
+ [a project] / [a fork] - +
- -

[forked from] [origin repository]

-
- \ No newline at end of file diff --git a/src/com/gitblit/wicket/pages/ForksPage.java b/src/com/gitblit/wicket/pages/ForksPage.java index 44f0ed14..2e67e2b7 100644 --- a/src/com/gitblit/wicket/pages/ForksPage.java +++ b/src/com/gitblit/wicket/pages/ForksPage.java @@ -15,14 +15,13 @@ */ package com.gitblit.wicket.pages; -import java.text.MessageFormat; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; @@ -30,9 +29,9 @@ import org.eclipse.jgit.lib.PersonIdent; import com.gitblit.GitBlit; import com.gitblit.Keys; +import com.gitblit.models.ForkModel; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; -import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; @@ -44,132 +43,114 @@ public class ForksPage extends RepositoryPage { public ForksPage(PageParameters params) { super(params); - UserModel user = GitBlitWebSession.get().getUser(); - RepositoryModel model = getRepositoryModel(); - RepositoryModel origin = model; - List list; - if (ArrayUtils.isEmpty(model.forks)) { - if (!StringUtils.isEmpty(model.originRepository)) { - // try origin repository - origin = GitBlit.self().getRepositoryModel(model.originRepository); - } - if (origin == null || origin.forks == null) { - list = new ArrayList(); - } else { - list = new ArrayList(origin.forks); - } - } else { - // this repository has forks - list = new ArrayList(model.forks); - } - - if (origin.isPersonalRepository()) { - // personal repository - UserModel originUser = GitBlit.self().getUserModel(origin.projectPath.substring(1)); - PersonIdent ident = new PersonIdent(originUser.getDisplayName(), originUser.emailAddress); - add(new GravatarImage("forkSourceAvatar", ident, 20)); - add(new Label("forkSourceSwatch").setVisible(false)); - add(new LinkPanel("forkSourceProject", null, originUser.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(originUser.username))); - } else { - // standard repository - add(new GravatarImage("forkSourceAvatar", new PersonIdent("", ""), 20).setVisible(false)); - Component swatch; - if (origin.isBare){ - swatch = new Label("forkSourceSwatch", " ").setEscapeModelStrings(false); - } else { - swatch = new Label("forkSourceSwatch", "!"); - WicketUtils.setHtmlTooltip(swatch, getString("gb.workingCopyWarning")); - } - WicketUtils.setCssBackground(swatch, origin.toString()); - add(swatch); - final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true); - swatch.setVisible(showSwatch); - - String projectName = origin.projectPath; - if (StringUtils.isEmpty(projectName)) { - projectName = GitBlit.getString(Keys.web.repositoryRootGroupName, "main"); - } - add(new LinkPanel("forkSourceProject", null, projectName, ProjectPage.class, WicketUtils.newProjectParameter(origin.projectPath))); - } + final RepositoryModel pageRepository = getRepositoryModel(); - String source = StringUtils.getLastPathElement(origin.name); - if (user != null && user.canViewRepository(origin)) { - // user can view the origin - add(new LinkPanel("forkSource", null, StringUtils.stripDotGit(source), SummaryPage.class, WicketUtils.newRepositoryParameter(origin.name))); - } else { - // user can not view the origin - add(new Label("forkSource", StringUtils.stripDotGit(source))); - } - - // superOrigin? - if (StringUtils.isEmpty(origin.originRepository)) { - // origin is root - add(new Label("forkSourceOrigin").setVisible(false)); - } else { - // origin has an origin - RepositoryModel superOrigin = GitBlit.self().getRepositoryModel(origin.originRepository); - if (!user.canViewRepository(superOrigin)) { - // show superOrigin repository without link - Fragment forkFrag = new Fragment("forkSourceOrigin", "originFragment", this); - forkFrag.add(new Label("originRepository", StringUtils.stripDotGit(superOrigin.name))); - add(forkFrag); - } else { - // link to superOrigin repository - Fragment forkFrag = new Fragment("forkSourceOrigin", "originFragment", this); - forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(superOrigin.name), - SummaryPage.class, WicketUtils.newRepositoryParameter(superOrigin.name))); - add(forkFrag); - } - } - - // only display user-accessible forks - List forks = new ArrayList(); - for (String aFork : list) { - RepositoryModel fork = GitBlit.self().getRepositoryModel(user, aFork); - if (fork != null) { - forks.add(fork); - } - } + ForkModel root = GitBlit.self().getForkNetwork(pageRepository.name); + List network = flatten(root); - ListDataProvider forksDp = new ListDataProvider(forks); - DataView forksList = new DataView("fork", forksDp) { + ListDataProvider forksDp = new ListDataProvider(network); + DataView forksList = new DataView("fork", forksDp) { private static final long serialVersionUID = 1L; - public void populateItem(final Item item) { - RepositoryModel fork = item.getModelObject(); + public void populateItem(final Item item) { + FlatFork fork = item.getModelObject(); + RepositoryModel repository = fork.repository; - if (fork.isPersonalRepository()) { - UserModel user = GitBlit.self().getUserModel(fork.projectPath.substring(1)); + if (repository.isPersonalRepository()) { + UserModel user = GitBlit.self().getUserModel(repository.projectPath.substring(1)); PersonIdent ident = new PersonIdent(user.getDisplayName(), user.emailAddress); item.add(new GravatarImage("anAvatar", ident, 20)); - item.add(new LinkPanel("aProject", null, user.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(user.username))); + if (pageRepository.equals(repository)) { + // do not link to self + item.add(new Label("aProject", user.getDisplayName())); + } else { + item.add(new LinkPanel("aProject", null, user.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(user.username))); + } } else { - PersonIdent ident = new PersonIdent(fork.name, fork.name); - item.add(new GravatarImage("anAvatar", ident, 20)); - item.add(new LinkPanel("aProject", null, fork.projectPath, ProjectPage.class, WicketUtils.newProjectParameter(fork.projectPath))); + Component swatch; + if (repository.isBare){ + swatch = new Label("anAvatar", " ").setEscapeModelStrings(false); + } else { + swatch = new Label("anAvatar", "!"); + WicketUtils.setHtmlTooltip(swatch, getString("gb.workingCopyWarning")); + } + WicketUtils.setCssClass(swatch, "repositorySwatch"); + WicketUtils.setCssBackground(swatch, repository.toString()); + item.add(swatch); + String projectName = repository.projectPath; + if (StringUtils.isEmpty(projectName)) { + projectName = GitBlit.getString(Keys.web.repositoryRootGroupName, "main"); + } + if (pageRepository.equals(repository)) { + // do not link to self + item.add(new Label("aProject", projectName)); + } else { + item.add(new LinkPanel("aProject", null, projectName, ProjectPage.class, WicketUtils.newProjectParameter(projectName))); + } } - String repo = StringUtils.getLastPathElement(fork.name); - item.add(new LinkPanel("aFork", null, StringUtils.stripDotGit(repo), SummaryPage.class, WicketUtils.newRepositoryParameter(fork.name))); + String repo = StringUtils.getLastPathElement(repository.name); + UserModel user = GitBlitWebSession.get().getUser(); + if (user == null) { + user = UserModel.ANONYMOUS; + } + if (user.canViewRepository(repository)) { + if (pageRepository.equals(repository)) { + // do not link to self + item.add(new Label("aFork", StringUtils.stripDotGit(repo))); + } else { + item.add(new LinkPanel("aFork", null, StringUtils.stripDotGit(repo), SummaryPage.class, WicketUtils.newRepositoryParameter(repository.name))); + } + item.add(WicketUtils.createDateLabel("lastChange", repository.lastChange, getTimeZone(), getTimeUtils())); + } else { + item.add(new Label("aFork", repo)); + item.add(new Label("lastChange").setVisible(false)); + } - if (ArrayUtils.isEmpty(fork.forks)) { - // repository is a leaf - Component icon = new Label("anIcon", "").setEscapeModelStrings(false); - WicketUtils.setHtmlTooltip(icon, MessageFormat.format(getString("gb.noForks"), fork.name)); - item.add(icon); + WicketUtils.setCssStyle(item, "margin-left:" + (32*fork.level) + "px;"); + if (fork.level == 0) { + WicketUtils.setCssClass(item, "forkSource"); } else { - // show forks link - item.add(new LinkPanel("anIcon", null, "(" + getString("gb.forks") + ")", ForksPage.class, WicketUtils.newRepositoryParameter(fork.name))); + WicketUtils.setCssClass(item, "forkEntry"); } } }; add(forksList); - } @Override protected String getPageName() { return getString("gb.forks"); } + + protected List flatten(ForkModel root) { + List list = new ArrayList(); + list.addAll(flatten(root, 0)); + return list; + } + + protected List flatten(ForkModel node, int level) { + List list = new ArrayList(); + list.add(new FlatFork(node.repository, level)); + if (!node.isLeaf()) { + for (ForkModel fork : node.forks) { + list.addAll(flatten(fork, level + 1)); + } + } + return list; + } + + private class FlatFork implements Serializable { + + private static final long serialVersionUID = 1L; + + public final RepositoryModel repository; + public final int level; + + public FlatFork(RepositoryModel repository, int level) { + this.repository = repository; + this.level = level; + } + } } -- 2.39.5