Exemplo n.º 1
0
  private void setSizeAndPosition() {
    String sz = null;
    String pos = null;
    try {
      StoredConfig config = getConfig();
      sz = config.getString("ui", null, "size");
      pos = config.getString("ui", null, "position");
      defaultDuration = config.getInt("new", "duration", 365);
    } catch (Throwable t) {
      t.printStackTrace();
    }

    // try to restore saved window size
    if (StringUtils.isEmpty(sz)) {
      setSize(900, 600);
    } else {
      String[] chunks = sz.split("x");
      int width = Integer.parseInt(chunks[0]);
      int height = Integer.parseInt(chunks[1]);
      setSize(width, height);
    }

    // try to restore saved window position
    if (StringUtils.isEmpty(pos)) {
      setLocationRelativeTo(null);
    } else {
      String[] chunks = pos.split(",");
      int x = Integer.parseInt(chunks[0]);
      int y = Integer.parseInt(chunks[1]);
      setLocation(x, y);
    }
  }
Exemplo n.º 2
0
 /**
  * Returns an int filesize from a string value such as 50m or 50mb
  *
  * @param name
  * @param defaultValue
  * @return an int filesize or defaultValue if the key does not exist or can not be parsed
  */
 public int getFilesize(String name, int defaultValue) {
   String val = getString(name, null);
   if (StringUtils.isEmpty(val)) {
     return defaultValue;
   }
   return com.gitblit.utils.FileUtils.convertSizeToInt(val, defaultValue);
 }
Exemplo n.º 3
0
 public LinkPanel(
     String wicketId,
     String bootstrapIcon,
     String linkCssClass,
     IModel<String> model,
     Class<? extends WebPage> clazz,
     PageParameters parameters,
     boolean newWindow) {
   super(wicketId);
   this.labelModel = model;
   Link<Void> link = null;
   if (parameters == null) {
     link = new BookmarkablePageLink<Void>("link", clazz);
   } else {
     link = new BookmarkablePageLink<Void>("link", clazz, parameters);
   }
   if (newWindow) {
     link.add(new SimpleAttributeModifier("target", "_blank"));
   }
   if (linkCssClass != null) {
     link.add(new SimpleAttributeModifier("class", linkCssClass));
   }
   Label icon = new Label("icon");
   if (StringUtils.isEmpty(bootstrapIcon)) {
     link.add(icon.setVisible(false));
   } else {
     WicketUtils.setCssClass(icon, bootstrapIcon);
     link.add(icon);
   }
   link.add(new Label("label", labelModel).setRenderBodyOnly(true));
   add(link);
 }
Exemplo n.º 4
0
 private void filterUsers(final String fragment) {
   table.clearSelection();
   userCertificatePanel.setUserCertificateModel(null);
   if (StringUtils.isEmpty(fragment)) {
     table.setRowSorter(defaultSorter);
     return;
   }
   RowFilter<UserCertificateTableModel, Object> containsFilter =
       new RowFilter<UserCertificateTableModel, Object>() {
         @Override
         public boolean include(
             Entry<? extends UserCertificateTableModel, ? extends Object> entry) {
           for (int i = entry.getValueCount() - 1; i >= 0; i--) {
             if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
               return true;
             }
           }
           return false;
         }
       };
   TableRowSorter<UserCertificateTableModel> sorter =
       new TableRowSorter<UserCertificateTableModel>(tableModel);
   sorter.setRowFilter(containsFilter);
   table.setRowSorter(sorter);
 }
Exemplo n.º 5
0
 /**
  * Authenticate a user based on a username and password.
  *
  * @param username
  * @param password
  * @return a user object or null
  */
 @Override
 public UserModel authenticate(String username, char[] password) {
   Properties allUsers = read();
   String userInfo = allUsers.getProperty(username);
   if (StringUtils.isEmpty(userInfo)) {
     return null;
   }
   UserModel returnedUser = null;
   UserModel user = getUserModel(username);
   if (user.password.startsWith(StringUtils.MD5_TYPE)) {
     // password digest
     String md5 = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(password));
     if (user.password.equalsIgnoreCase(md5)) {
       returnedUser = user;
     }
   } else if (user.password.startsWith(StringUtils.COMBINED_MD5_TYPE)) {
     // username+password digest
     String md5 =
         StringUtils.COMBINED_MD5_TYPE
             + StringUtils.getMD5(username.toLowerCase() + new String(password));
     if (user.password.equalsIgnoreCase(md5)) {
       returnedUser = user;
     }
   } else if (user.password.equals(new String(password))) {
     // plain-text password
     returnedUser = user;
   }
   return returnedUser;
 }
Exemplo n.º 6
0
 /**
  * Returns an long filesize from a string value such as 50m or 50mb
  *
  * @param n
  * @param defaultValue
  * @return a long filesize or defaultValue if the key does not exist or can not be parsed
  */
 public long getFilesize(String key, long defaultValue) {
   String val = getString(key, null);
   if (StringUtils.isEmpty(val)) {
     return defaultValue;
   }
   return com.gitblit.utils.FileUtils.convertSizeToLong(val, defaultValue);
 }
Exemplo n.º 7
0
 private String readMarkdown(String messageSource, String resource) {
   String message = "";
   if (messageSource.equalsIgnoreCase("gitblit")) {
     // Read default message
     message = readDefaultMarkdown(resource);
   } else {
     // Read user-supplied message
     if (!StringUtils.isEmpty(messageSource)) {
       File file = GitBlit.getFileOrFolder(messageSource);
       if (file.exists()) {
         try {
           FileInputStream fis = new FileInputStream(file);
           InputStreamReader reader = new InputStreamReader(fis, Constants.CHARACTER_ENCODING);
           message = MarkdownUtils.transformMarkdown(reader);
           reader.close();
         } catch (Throwable t) {
           message = getString("gb.failedToRead") + " " + file;
           warn(message, t);
         }
       } else {
         message = messageSource + " " + getString("gb.isNotValidFile");
       }
     }
   }
   return message;
 }
Exemplo n.º 8
0
 public void setUsers(String owner, List<String> all, List<String> selected) {
   ownerField.setModel(new DefaultComboBoxModel(all.toArray()));
   if (!StringUtils.isEmpty(owner)) {
     ownerField.setSelectedItem(owner);
   }
   usersPalette.setObjects(all, selected);
 }
Exemplo n.º 9
0
 /**
  * Retrieve the user object for the specified username.
  *
  * @param username
  * @return a user object or null
  */
 @Override
 public UserModel getUserModel(String username) {
   if (StringUtils.isEmpty(username)) {
     return null;
   }
   String usernameDecoded = StringUtils.decodeUsername(username);
   UserModel user = userService.getUserModel(usernameDecoded);
   return user;
 }
Exemplo n.º 10
0
  /**
   * Construct the Gitblit Git daemon.
   *
   * @param bindInterface the ip address of the interface to bind
   * @param port the port to serve on
   * @param folder the folder to serve from
   */
  public GitDaemon(String bindInterface, int port, File folder) {
    this(
        StringUtils.isEmpty(bindInterface)
            ? new InetSocketAddress(port)
            : new InetSocketAddress(bindInterface, port));

    // set the repository resolver and pack factories
    repositoryResolver = new RepositoryResolver<GitDaemonClient>(folder);
  }
Exemplo n.º 11
0
 public String getURL() throws IOException {
   String url = runtimeManager.getSettings().getString(Plugin.SETTING_URL, null);
   if (StringUtils.isEmpty(url)) {
     throw new IOException(
         String.format(
             "Could not send message to Slack because '%s' is not defined!", Plugin.SETTING_URL));
   }
   return url;
 }
Exemplo n.º 12
0
  private String readDefaultMarkdown(String file) {
    String base = file.substring(0, file.lastIndexOf('.'));
    String ext = file.substring(file.lastIndexOf('.'));
    String lc = getLanguageCode();
    String cc = getCountryCode();

    // try to read file_en-us.ext, file_en.ext, file.ext
    List<String> files = new ArrayList<String>();
    if (!StringUtils.isEmpty(lc)) {
      if (!StringUtils.isEmpty(cc)) {
        files.add(base + "_" + lc + "-" + cc + ext);
        files.add(base + "_" + lc + "_" + cc + ext);
      }
      files.add(base + "_" + lc + ext);
    }
    files.add(file);

    for (String name : files) {
      String message;
      InputStreamReader reader = null;
      try {
        InputStream is = getClass().getResourceAsStream("/" + name);
        if (is == null) {
          continue;
        }
        reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING);
        message = MarkdownUtils.transformMarkdown(reader);
        reader.close();
        return message;
      } catch (Throwable t) {
        message = MessageFormat.format(getString("gb.failedToReadMessage"), file);
        error(message, t, false);
        return message;
      } finally {
        if (reader != null) {
          try {
            reader.close();
          } catch (Exception e) {
          }
        }
      }
    }
    return MessageFormat.format(getString("gb.failedToReadMessage"), file);
  }
Exemplo n.º 13
0
  /**
   * Optionally sets the channel of the payload based on the repository.
   *
   * @param repository
   * @param payload
   */
  public void setChannel(RepositoryModel repository, Payload payload) {
    boolean useProjectChannels =
        runtimeManager.getSettings().getBoolean(Plugin.SETTING_USE_PROJECT_CHANNELS, false);
    if (!useProjectChannels) {
      return;
    }

    if (StringUtils.isEmpty(repository.projectPath)) {
      return;
    }

    String defaultChannel =
        runtimeManager.getSettings().getString(Plugin.SETTING_DEFAULT_CHANNEL, null);
    if (!StringUtils.isEmpty(defaultChannel)) {
      payload.setChannel(defaultChannel + "-" + repository.projectPath);
    } else {
      payload.setChannel(repository.projectPath);
    }
  }
Exemplo n.º 14
0
 /**
  * Returns the boolean value for the specified key. If the key does not exist or the value for the
  * key can not be interpreted as a boolean, the defaultValue is returned.
  *
  * @param key
  * @param defaultValue
  * @return key value or defaultValue
  */
 public boolean getBoolean(String name, boolean defaultValue) {
   Properties props = getSettings();
   if (props.containsKey(name)) {
     String value = props.getProperty(name);
     if (!StringUtils.isEmpty(value)) {
       return Boolean.parseBoolean(value.trim());
     }
   }
   return defaultValue;
 }
Exemplo n.º 15
0
 /**
  * Returns the char value for the specified key. If the key does not exist or the value for the
  * key can not be interpreted as a char, the defaultValue is returned.
  *
  * @param key
  * @param defaultValue
  * @return key value or defaultValue
  */
 public char getChar(String name, char defaultValue) {
   Properties props = getSettings();
   if (props.containsKey(name)) {
     String value = props.getProperty(name);
     if (!StringUtils.isEmpty(value)) {
       return value.trim().charAt(0);
     }
   }
   return defaultValue;
 }
Exemplo n.º 16
0
 protected void setAccountType(UserModel user) {
   if (user != null) {
     if (!StringUtils.isEmpty(user.password)
         && !Constants.EXTERNAL_ACCOUNT.equalsIgnoreCase(user.password)
         && !"StoredInLDAP".equalsIgnoreCase(user.password)) {
       user.accountType = AccountType.LOCAL;
     } else {
       user.accountType = getAccountType();
     }
   }
 }
Exemplo n.º 17
0
 protected String getPageTitle(String repositoryName) {
   String siteName = app().settings().getString(Keys.web.siteName, Constants.NAME);
   if (StringUtils.isEmpty(siteName)) {
     siteName = Constants.NAME;
   }
   if (repositoryName != null && repositoryName.trim().length() > 0) {
     return repositoryName + " - " + siteName;
   } else {
     return siteName;
   }
 }
 /**
  * Sends a status acknowledgment to the origin Gitblit instance. This includes the results of the
  * federated pull.
  *
  * @param registration
  * @throws Exception
  */
 private void sendStatusAcknowledgment(FederationModel registration) throws Exception {
   if (!registration.sendStatus) {
     // skip status acknowledgment
     return;
   }
   InetAddress addr = InetAddress.getLocalHost();
   String federationName = GitBlit.getString(Keys.federation.name, null);
   if (StringUtils.isEmpty(federationName)) {
     federationName = addr.getHostName();
   }
   FederationUtils.acknowledgeStatus(addr.getHostAddress(), registration);
   logger.info(MessageFormat.format("Pull status sent to {0}", registration.url));
 }
Exemplo n.º 19
0
 /**
  * Delete the user object with the specified username
  *
  * @param username
  * @return true if successful
  */
 @Override
 public boolean deleteUser(String username) {
   if (StringUtils.isEmpty(username)) {
     return false;
   }
   String usernameDecoded = StringUtils.decodeUsername(username);
   UserModel user = getUserModel(usernameDecoded);
   if (userService.deleteUser(usernameDecoded)) {
     callDeleteUserListeners(user);
     return true;
   }
   return false;
 }
Exemplo n.º 20
0
 private String transformMarkdown(String markdown) {
   String message = "";
   if (!StringUtils.isEmpty(markdown)) {
     // Read user-supplied message
     try {
       message = MarkdownUtils.transformMarkdown(markdown);
     } catch (Throwable t) {
       message = getString("gb.failedToRead") + " " + markdown;
       warn(message, t);
     }
   }
   return message;
 }
Exemplo n.º 21
0
 /**
  * Returns the long value for the specified key. If the key does not exist or the value for the
  * key can not be interpreted as an long, the defaultValue is returned.
  *
  * @param key
  * @param defaultValue
  * @return key value or defaultValue
  */
 public long getLong(String name, long defaultValue) {
   Properties props = getSettings();
   if (props.containsKey(name)) {
     try {
       String value = props.getProperty(name);
       if (!StringUtils.isEmpty(value)) {
         return Long.parseLong(value.trim());
       }
     } catch (NumberFormatException e) {
       logger.warn("Failed to parse long for " + name + " using default of " + defaultValue);
     }
   }
   return defaultValue;
 }
Exemplo n.º 22
0
 /**
  * Authenticate a user based on their cookie.
  *
  * @param cookie
  * @return a user object or null
  */
 @Override
 public UserModel authenticate(char[] cookie) {
   String hash = new String(cookie);
   if (StringUtils.isEmpty(hash)) {
     return null;
   }
   read();
   UserModel model = null;
   if (cookies.containsKey(hash)) {
     String username = cookies.get(hash);
     model = getUserModel(username);
   }
   return model;
 }
Exemplo n.º 23
0
 /**
  * Returns the list of keys whose name starts with the specified prefix. If the prefix is null or
  * empty, all key names are returned.
  *
  * @param startingWith
  * @return list of keys
  */
 public List<String> getAllKeys(String startingWith) {
   List<String> keys = new ArrayList<String>();
   Properties props = getSettings();
   if (StringUtils.isEmpty(startingWith)) {
     keys.addAll(props.stringPropertyNames());
   } else {
     startingWith = startingWith.toLowerCase();
     for (Object o : props.keySet()) {
       String key = o.toString();
       if (key.toLowerCase().startsWith(startingWith)) {
         keys.add(key);
       }
     }
   }
   return keys;
 }
Exemplo n.º 24
0
 /**
  * Analyze the url and returns the action of the request. Return values are either
  * "/git-receive-pack" or "/git-upload-pack".
  *
  * @param serverUrl
  * @return action of the request
  */
 @Override
 protected String getUrlRequestAction(String suffix) {
   if (!StringUtils.isEmpty(suffix)) {
     if (suffix.startsWith(gitReceivePack)) {
       return gitReceivePack;
     } else if (suffix.startsWith(gitUploadPack)) {
       return gitUploadPack;
     } else if (suffix.contains("?service=git-receive-pack")) {
       return gitReceivePack;
     } else if (suffix.contains("?service=git-upload-pack")) {
       return gitUploadPack;
     } else {
       return gitUploadPack;
     }
   }
   return null;
 }
Exemplo n.º 25
0
  private boolean sendEmail(UserModel user, X509Metadata metadata, File zip) {
    // send email
    try {
      if (mail.isReady()) {
        Message message = mail.createMessage(user.emailAddress);
        message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname);

        // body of email
        String body =
            X509Utils.processTemplate(
                new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata);
        if (StringUtils.isEmpty(body)) {
          body =
              MessageFormat.format(
                  "Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.",
                  user.getDisplayName());
        }
        Multipart mp = new MimeMultipart();
        MimeBodyPart messagePart = new MimeBodyPart();
        messagePart.setText(body);
        mp.addBodyPart(messagePart);

        // attach zip
        MimeBodyPart filePart = new MimeBodyPart();
        FileDataSource fds = new FileDataSource(zip);
        filePart.setDataHandler(new DataHandler(fds));
        filePart.setFileName(fds.getName());
        mp.addBodyPart(filePart);

        message.setContent(mp);

        mail.sendNow(message);
        return true;
      } else {
        JOptionPane.showMessageDialog(
            GitblitAuthority.this,
            "Sorry, the mail server settings are not configured properly.\nCan not send email.",
            Translation.get("gb.error"),
            JOptionPane.ERROR_MESSAGE);
      }
    } catch (Exception e) {
      Utils.showException(GitblitAuthority.this, e);
    }
    return false;
  }
Exemplo n.º 26
0
  @Override
  public String diff(String objectId, String baseObjectId, String blobPath) {
    Repository r = git.getRepository();
    objectId = defaultObjectId(objectId);
    RevCommit commit = JGitUtils.getCommit(r, objectId);

    DiffUtils.DiffOutputType diffType = DiffUtils.DiffOutputType.PLAIN;
    String diff;
    if (StringUtils.isEmpty(baseObjectId)) {
      // use first parent
      diff = DiffUtils.getDiff(r, commit, blobPath, diffType);
    } else {
      // base commit specified
      RevCommit baseCommit = JGitUtils.getCommit(r, baseObjectId);
      diff = DiffUtils.getDiff(r, baseCommit, commit, blobPath, diffType);
    }
    return diff;
  }
  /**
   * Returns the journal for the specified ticket.
   *
   * @param db
   * @param ticketId
   * @return a list of changes
   */
  private List<Change> getJournal(Repository db, long ticketId) {
    RefModel ticketsBranch = getTicketsBranch(db);
    if (ticketsBranch == null) {
      return new ArrayList<Change>();
    }

    if (ticketId <= 0L) {
      return new ArrayList<Change>();
    }

    String journalPath = toTicketPath(ticketId) + "/" + JOURNAL;
    String json = readTicketsFile(db, journalPath);
    if (StringUtils.isEmpty(json)) {
      return new ArrayList<Change>();
    }
    List<Change> list = TicketSerializer.deserializeJournal(json);
    return list;
  }
Exemplo n.º 28
0
  private void setMetadataDefaults(X509Metadata metadata) {
    metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, Constants.NAME);
    if (StringUtils.isEmpty(metadata.serverHostname)) {
      metadata.serverHostname = Constants.NAME;
    }

    // set default values from config file
    File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG);
    FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect());
    if (certificatesConfigFile.exists()) {
      try {
        config.load();
      } catch (Exception e) {
        Utils.showException(GitblitAuthority.this, e);
      }
      NewCertificateConfig certificateConfig = NewCertificateConfig.KEY.parse(config);
      certificateConfig.update(metadata);
    }
  }
Exemplo n.º 29
0
 @Override
 protected void setLastModified() {
   if (getClass().isAnnotationPresent(CacheControl.class)) {
     CacheControl cacheControl = getClass().getAnnotation(CacheControl.class);
     switch (cacheControl.value()) {
       case PROJECT:
         String projectName = WicketUtils.getProjectName(getPageParameters());
         if (!StringUtils.isEmpty(projectName)) {
           ProjectModel project = getProjectModel(projectName);
           if (project != null) {
             setLastModified(project.lastChange);
           }
         }
         break;
       default:
         super.setLastModified();
     }
   }
 }
Exemplo n.º 30
0
  public ComparePage(PageParameters params) {
    super(params);
    Repository r = getRepository();
    RepositoryModel repository = getRepositoryModel();

    if (StringUtils.isEmpty(objectId)) {
      // seleciton form
      add(new Label("comparison").setVisible(false));
    } else {
      // active comparison
      Fragment comparison = new Fragment("comparison", "comparisonFragment", this);
      add(comparison);

      RevCommit fromCommit;
      RevCommit toCommit;

      String[] parts = objectId.split("\\.\\.");
      if (parts[0].startsWith("refs/") && parts[1].startsWith("refs/")) {
        // set the ref models
        fromRefId.setObject(parts[0]);
        toRefId.setObject(parts[1]);

        fromCommit = getCommit(r, fromRefId.getObject());
        toCommit = getCommit(r, toRefId.getObject());
      } else {
        // set the id models
        fromCommitId.setObject(parts[0]);
        toCommitId.setObject(parts[1]);

        fromCommit = getCommit(r, fromCommitId.getObject());
        toCommit = getCommit(r, toCommitId.getObject());
      }

      // prepare submodules
      getSubmodules(toCommit);

      final String startId = fromCommit.getId().getName();
      final String endId = toCommit.getId().getName();

      // commit ids
      fromCommitId.setObject(startId);
      toCommitId.setObject(endId);

      final DiffOutput diff = DiffUtils.getDiff(r, fromCommit, toCommit, DiffOutputType.HTML);

      // add compare diffstat
      int insertions = 0;
      int deletions = 0;
      for (PathChangeModel pcm : diff.stat.paths) {
        insertions += pcm.insertions;
        deletions += pcm.deletions;
      }
      comparison.add(new DiffStatPanel("diffStat", insertions, deletions));

      // compare page links
      //			comparison.add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
      //					WicketUtils.newRangeParameter(repositoryName, fromCommitId.toString(),
      // toCommitId.getObject())));

      // display list of commits
      comparison.add(
          new LogPanel(
              "commitList", repositoryName, objectId, r, 0, 0, repository.showRemoteBranches));

      // changed paths list
      comparison.add(new CommitLegendPanel("commitLegend", diff.stat.paths));
      ListDataProvider<PathChangeModel> pathsDp =
          new ListDataProvider<PathChangeModel>(diff.stat.paths);
      DataView<PathChangeModel> pathsView =
          new DataView<PathChangeModel>("changedPath", pathsDp) {
            private static final long serialVersionUID = 1L;
            int counter;

            @Override
            public void populateItem(final Item<PathChangeModel> item) {
              final PathChangeModel entry = item.getModelObject();
              Label changeType = new Label("changeType", "");
              WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
              setChangeTypeTooltip(changeType, entry.changeType);
              item.add(changeType);
              item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));

              boolean hasSubmodule = false;
              String submodulePath = null;
              if (entry.isTree()) {
                // tree
                item.add(
                    new LinkPanel(
                        "pathName",
                        null,
                        entry.path,
                        TreePage.class,
                        WicketUtils.newPathParameter(repositoryName, endId, entry.path)));
              } else if (entry.isSubmodule()) {
                // submodule
                String submoduleId = entry.objectId;
                SubmoduleModel submodule = getSubmodule(entry.path);
                submodulePath = submodule.gitblitPath;
                hasSubmodule = submodule.hasSubmodule;

                // add relative link
                item.add(
                    new LinkPanel(
                        "pathName",
                        "list",
                        entry.path + " @ " + getShortObjectId(submoduleId),
                        "#" + entry.path));
              } else {
                // add relative link
                item.add(new LinkPanel("pathName", "list", entry.path, "#" + entry.path));
              }

              // quick links
              if (entry.isSubmodule()) {
                // submodule
                item.add(new ExternalLink("patch", "").setEnabled(false));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "view",
                            CommitPage.class,
                            WicketUtils.newObjectParameter(submodulePath, entry.objectId))
                        .setEnabled(hasSubmodule));
                item.add(new ExternalLink("blame", "").setEnabled(false));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "history",
                            HistoryPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
              } else {
                // tree or blob
                item.add(
                    new BookmarkablePageLink<Void>(
                            "patch",
                            PatchPage.class,
                            WicketUtils.newBlobDiffParameter(
                                repositoryName, startId, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "view",
                            BlobPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "raw",
                            RawPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "blame",
                            BlamePage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(
                            !entry.changeType.equals(ChangeType.ADD)
                                && !entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "history",
                            HistoryPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
              }
              WicketUtils.setAlternatingBackground(item, counter);
              counter++;
            }
          };
      comparison.add(pathsView);
      comparison.add(new Label("diffText", diff.content).setEscapeModelStrings(false));
    }

    //
    // ref selection form
    //
    SessionlessForm<Void> refsForm =
        new SessionlessForm<Void>("compareRefsForm", getClass(), getPageParameters()) {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            String from = ComparePage.this.fromRefId.getObject();
            String to = ComparePage.this.toRefId.getObject();

            PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
            String relativeUrl = urlFor(ComparePage.class, params).toString();
            String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
            getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
          }
        };

    List<String> refs = new ArrayList<String>();
    for (RefModel ref : JGitUtils.getLocalBranches(r, true, -1)) {
      refs.add(ref.getName());
    }
    if (repository.showRemoteBranches) {
      for (RefModel ref : JGitUtils.getRemoteBranches(r, true, -1)) {
        refs.add(ref.getName());
      }
    }
    for (RefModel ref : JGitUtils.getTags(r, true, -1)) {
      refs.add(ref.getName());
    }
    refsForm.add(
        new DropDownChoice<String>("fromRef", fromRefId, refs).setEnabled(refs.size() > 0));
    refsForm.add(new DropDownChoice<String>("toRef", toRefId, refs).setEnabled(refs.size() > 0));
    add(refsForm);

    //
    // manual ids form
    //
    SessionlessForm<Void> idsForm =
        new SessionlessForm<Void>("compareIdsForm", getClass(), getPageParameters()) {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            String from = ComparePage.this.fromCommitId.getObject();
            String to = ComparePage.this.toCommitId.getObject();

            PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
            String relativeUrl = urlFor(ComparePage.class, params).toString();
            String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
            getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
          }
        };

    TextField<String> fromIdField = new TextField<String>("fromId", fromCommitId);
    WicketUtils.setInputPlaceholder(fromIdField, getString("gb.from") + "...");
    idsForm.add(fromIdField);

    TextField<String> toIdField = new TextField<String>("toId", toCommitId);
    WicketUtils.setInputPlaceholder(toIdField, getString("gb.to") + "...");
    idsForm.add(toIdField);
    add(idsForm);

    r.close();
  }