James Moger
2012-10-03 f22a0633d08e38ac4bf92b5165a708e11b4d6598
src/com/gitblit/wicket/pages/RepositoryPage.java
@@ -19,9 +19,12 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
@@ -44,7 +47,10 @@
import com.gitblit.Keys;
import com.gitblit.PagesServlet;
import com.gitblit.SyndicationServlet;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
@@ -60,20 +66,31 @@
public abstract class RepositoryPage extends BasePage {
   protected final String projectName;
   protected final String repositoryName;
   protected final String objectId;
   private transient Repository r;
   private RepositoryModel m;
   private Map<String, SubmoduleModel> submodules;
   private final Map<String, PageRegistration> registeredPages;
   private boolean showAdmin;
   private boolean isOwner;
   public RepositoryPage(PageParameters params) {
      super(params);
      repositoryName = WicketUtils.getRepositoryName(params);
      String root =StringUtils.getFirstPathElement(repositoryName);
      if (StringUtils.isEmpty(root)) {
         projectName = GitBlit.getString(Keys.web.repositoryRootGroupName, "main");
      } else {
         projectName = root;
      }
      objectId = WicketUtils.getObject(params);
      if (StringUtils.isEmpty(repositoryName)) {
         error(MessageFormat.format(getString("gb.repositoryNotSpecifiedFor"), getPageName()), true);
      }
@@ -116,6 +133,7 @@
      pages.put("branches", new PageRegistration("gb.branches", BranchesPage.class, params));
      pages.put("tags", new PageRegistration("gb.tags", TagsPage.class, params));
      pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params));
      pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params));
      // conditional links
      Repository r = getRepository();
@@ -135,37 +153,130 @@
      }
      // Conditionally add edit link
      final boolean showAdmin;
      showAdmin = false;
      if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
         boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
         showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
      } else {
         showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
      }
      if (showAdmin
            || GitBlitWebSession.get().isLoggedIn()
      isOwner = GitBlitWebSession.get().isLoggedIn()
            && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get()
                  .getUser().username))) {
                  .getUsername()));
      if (showAdmin || isOwner) {
         pages.put("edit", new PageRegistration("gb.edit", EditRepositoryPage.class, params));
      }
      return pages;
   }
   protected boolean allowForkControls() {
      return true;
   }
   @Override
   protected void setupPage(String repositoryName, String pageName) {
      add(new LinkPanel("repositoryName", null, StringUtils.stripDotGit(repositoryName),
            SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryName)));
      add(new Label("pageName", pageName).setRenderBodyOnly(true));
      if (getRepositoryModel().isBare) {
         add(new Label("workingCopy").setVisible(false));
      String projectName = StringUtils.getFirstPathElement(repositoryName);
      ProjectModel project = GitBlit.self().getProjectModel(projectName);
      if (project.isUserProject()) {
         // user-as-project
         add(new LinkPanel("projectTitle", null, project.getDisplayName(),
               UserPage.class, WicketUtils.newUsernameParameter(project.name.substring(1))));
      } else {
         Fragment fragment = new Fragment("workingCopy", "workingCopyFragment", this);
         Label lbl = new Label("workingCopy", getString("gb.workingCopy"));
         WicketUtils.setHtmlTooltip(lbl,  getString("gb.workingCopyWarning"));
         fragment.add(lbl);
         add(fragment);
         // project
         add(new LinkPanel("projectTitle", null, project.name,
               ProjectPage.class, WicketUtils.newProjectParameter(project.name)));
      }
      String name = StringUtils.stripDotGit(repositoryName);
      if (!StringUtils.isEmpty(projectName) && name.startsWith(projectName)) {
         name = name.substring(projectName.length() + 1);
      }
      add(new LinkPanel("repositoryName", null, name, SummaryPage.class,
            WicketUtils.newRepositoryParameter(repositoryName)));
      add(new Label("pageName", pageName).setRenderBodyOnly(true));
      UserModel user = GitBlitWebSession.get().getUser();
      if (user == null) {
         user = UserModel.ANONYMOUS;
      }
      // indicate origin repository
      RepositoryModel model = getRepositoryModel();
      if (StringUtils.isEmpty(model.originRepository)) {
         add(new Label("originRepository").setVisible(false));
      } else {
         RepositoryModel origin = GitBlit.self().getRepositoryModel(model.originRepository);
         if (origin == null) {
            // no origin repository
            add(new Label("originRepository").setVisible(false));
         } else if (!user.canViewRepository(origin)) {
            // show origin repository without link
            Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
            forkFrag.add(new Label("originRepository", StringUtils.stripDotGit(model.originRepository)));
            add(forkFrag);
         } else {
            // link to origin repository
            Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
            forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository),
                  SummaryPage.class, WicketUtils.newRepositoryParameter(model.originRepository)));
            add(forkFrag);
         }
      }
      if (getRepositoryModel().isBare) {
         add(new Label("workingCopyIndicator").setVisible(false));
      } else {
         Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this);
         Label lbl = new Label("workingCopy", getString("gb.workingCopy"));
         WicketUtils.setHtmlTooltip(lbl,  getString("gb.workingCopyWarning"));
         wc.add(lbl);
         add(wc);
      }
      // fork controls
      if (!allowForkControls() || user == null || !user.isAuthenticated) {
         // must be logged-in to fork, hide all fork controls
         add(new ExternalLink("forkLink", "").setVisible(false));
         add(new ExternalLink("myForkLink", "").setVisible(false));
         add(new Label("forksProhibitedIndicator").setVisible(false));
      } else {
         String fork = GitBlit.self().getFork(user.username, model.name);
         boolean hasFork = fork != null;
         boolean canFork = user.canForkRepository(model);
         if (hasFork || !canFork) {
            // user not allowed to fork or fork already exists or repo forbids forking
            add(new ExternalLink("forkLink", "").setVisible(false));
            if (user.canFork && !model.allowForks) {
               // show forks prohibited indicator
               Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);
               Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));
               WicketUtils.setHtmlTooltip(lbl,  getString("gb.forksProhibitedWarning"));
               wc.add(lbl);
               add(wc);
            } else {
               // can not fork, no need for forks prohibited indicator
               add(new Label("forksProhibitedIndicator").setVisible(false));
            }
            if (hasFork && !fork.equals(model.name)) {
               // user has fork, view my fork link
               String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)).toString();
               add(new ExternalLink("myForkLink", url));
            } else {
               // no fork, hide view my fork link
               add(new ExternalLink("myForkLink", "").setVisible(false));
            }
         } else if (canFork) {
            // can fork and we do not have one
            add(new Label("forksProhibitedIndicator").setVisible(false));
            add(new ExternalLink("myForkLink", "").setVisible(false));
            String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();
            add(new ExternalLink("forkLink", url));
         }
      }
      super.setupPage(repositoryName, pageName);
   }
@@ -192,7 +303,13 @@
         RepositoryModel model = GitBlit.self().getRepositoryModel(
               GitBlitWebSession.get().getUser(), repositoryName);
         if (model == null) {
            authenticationError(getString("gb.unauthorizedAccessForRepository") + " " + repositoryName);
            if (GitBlit.self().hasRepository(repositoryName)) {
               // has repository, but unauthorized
               authenticationError(getString("gb.unauthorizedAccessForRepository") + " " + repositoryName);
            } else {
               // does not have repository
               error(getString("gb.canNotLoadRepository") + " " + repositoryName, true);
            }
            return null;
         }
         m = model;
@@ -206,7 +323,84 @@
         error(MessageFormat.format(getString("gb.failedToFindCommit"),
               objectId, repositoryName, getPageName()), true);
      }
      getSubmodules(commit);
      return commit;
   }
   private Map<String, SubmoduleModel> getSubmodules(RevCommit commit) {
      if (submodules == null) {
         submodules = new HashMap<String, SubmoduleModel>();
         for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {
            submodules.put(model.path, model);
         }
      }
      return submodules;
   }
   protected Map<String, SubmoduleModel> getSubmodules() {
      return submodules;
   }
   protected SubmoduleModel getSubmodule(String path) {
      SubmoduleModel model = submodules.get(path);
      if (model == null) {
         // undefined submodule?!
         model = new SubmoduleModel(path.substring(path.lastIndexOf('/') + 1), path, path);
         model.hasSubmodule = false;
         model.gitblitPath = model.name;
         return model;
      } else {
         // extract the repository name from the clone url
         List<String> patterns = GitBlit.getStrings(Keys.git.submoduleUrlPatterns);
         String submoduleName = StringUtils.extractRepositoryPath(model.url, patterns.toArray(new String[0]));
         // determine the current path for constructing paths relative
         // to the current repository
         String currentPath = "";
         if (repositoryName.indexOf('/') > -1) {
            currentPath = repositoryName.substring(0, repositoryName.lastIndexOf('/') + 1);
         }
         // try to locate the submodule repository
         // prefer bare to non-bare names
         List<String> candidates = new ArrayList<String>();
         // relative
         candidates.add(currentPath + StringUtils.stripDotGit(submoduleName));
         candidates.add(candidates.get(candidates.size() - 1) + ".git");
         // relative, no subfolder
         if (submoduleName.lastIndexOf('/') > -1) {
            String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
            candidates.add(currentPath + StringUtils.stripDotGit(name));
            candidates.add(currentPath + candidates.get(candidates.size() - 1) + ".git");
         }
         // absolute
         candidates.add(StringUtils.stripDotGit(submoduleName));
         candidates.add(candidates.get(candidates.size() - 1) + ".git");
         // absolute, no subfolder
         if (submoduleName.lastIndexOf('/') > -1) {
            String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
            candidates.add(StringUtils.stripDotGit(name));
            candidates.add(candidates.get(candidates.size() - 1) + ".git");
         }
         // create a unique, ordered set of candidate paths
         Set<String> paths = new LinkedHashSet<String>(candidates);
         for (String candidate : paths) {
            if (GitBlit.self().hasRepository(candidate)) {
               model.hasSubmodule = true;
               model.gitblitPath = candidate;
               return model;
            }
         }
         // we do not have a copy of the submodule, but we need a path
         model.gitblitPath = candidates.get(0);
         return model;
      }
   }
   protected String getShortObjectId(String objectId) {
@@ -214,7 +408,7 @@
   }
   protected void addRefs(Repository r, RevCommit c) {
      add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r)));
      add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r, getRepositoryModel().showRemoteBranches)));
   }
   protected void addFullText(String wicketId, String text, boolean substituteRegex) {
@@ -316,6 +510,14 @@
      return WicketUtils.newObjectParameter(repositoryName, commitId);
   }
   public boolean isShowAdmin() {
      return showAdmin;
   }
   public boolean isOwner() {
      return isOwner;
   }
   private class SearchForm extends SessionlessForm<Void> implements Serializable {
      private static final long serialVersionUID = 1L;
@@ -374,4 +576,4 @@
         getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
      }
   }
}
}