/* | |
* Copyright 2011 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.panels; | |
import java.io.IOException; | |
import java.text.MessageFormat; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
import org.apache.wicket.PageParameters; | |
import org.apache.wicket.markup.html.basic.Label; | |
import org.apache.wicket.markup.html.link.BookmarkablePageLink; | |
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.markup.repeater.Item; | |
import org.apache.wicket.markup.repeater.data.DataView; | |
import org.apache.wicket.markup.repeater.data.ListDataProvider; | |
import org.apache.wicket.model.StringResourceModel; | |
import org.apache.wicket.protocol.http.RequestUtils; | |
import org.apache.wicket.request.target.basic.RedirectRequestTarget; | |
import org.eclipse.jgit.lib.Ref; | |
import org.eclipse.jgit.lib.Repository; | |
import com.gitblit.Constants; | |
import com.gitblit.models.RefModel; | |
import com.gitblit.models.RepositoryModel; | |
import com.gitblit.models.UserModel; | |
import com.gitblit.servlet.RawServlet; | |
import com.gitblit.servlet.SyndicationServlet; | |
import com.gitblit.utils.CommitCache; | |
import com.gitblit.utils.JGitUtils; | |
import com.gitblit.utils.RefLogUtils; | |
import com.gitblit.utils.StringUtils; | |
import com.gitblit.wicket.GitBlitWebSession; | |
import com.gitblit.wicket.WicketUtils; | |
import com.gitblit.wicket.pages.BranchesPage; | |
import com.gitblit.wicket.pages.CommitPage; | |
import com.gitblit.wicket.pages.GitSearchPage; | |
import com.gitblit.wicket.pages.LogPage; | |
import com.gitblit.wicket.pages.MetricsPage; | |
import com.gitblit.wicket.pages.TreePage; | |
public class BranchesPanel extends BasePanel { | |
private static final long serialVersionUID = 1L; | |
private final boolean hasBranches; | |
public BranchesPanel(String wicketId, final RepositoryModel model, Repository r, | |
final int maxCount, final boolean showAdmin) { | |
super(wicketId); | |
// branches | |
List<RefModel> branches = new ArrayList<RefModel>(); | |
UserModel user = GitBlitWebSession.get().getUser(); | |
if (user == null) { | |
user = UserModel.ANONYMOUS; | |
} | |
List<RefModel> localBranches = JGitUtils.getLocalBranches(r, false, -1); | |
for (RefModel refModel : localBranches) { | |
if (user.canView(model, refModel.reference.getName())) { | |
branches.add(refModel); | |
} | |
} | |
if (model.showRemoteBranches) { | |
List<RefModel> remoteBranches = JGitUtils.getRemoteBranches(r, false, -1); | |
for (RefModel refModel : remoteBranches) { | |
if (user.canView(model, refModel.reference.getName())) { | |
branches.add(refModel); | |
} | |
} | |
} | |
Collections.sort(branches); | |
Collections.reverse(branches); | |
if (maxCount > 0 && branches.size() > maxCount) { | |
branches = new ArrayList<RefModel>(branches.subList(0, maxCount)); | |
} | |
if (maxCount > 0) { | |
// summary page | |
// show branches page link | |
add(new LinkPanel("branches", "title", new StringResourceModel("gb.branches", this, | |
null), BranchesPage.class, WicketUtils.newRepositoryParameter(model.name))); | |
} else { | |
// branches page | |
add(new Label("branches", new StringResourceModel("gb.branches", this, null))); | |
} | |
// only allow delete if we have multiple branches | |
final boolean showDelete = showAdmin && branches.size() > 1; | |
ListDataProvider<RefModel> branchesDp = new ListDataProvider<RefModel>(branches); | |
DataView<RefModel> branchesView = new DataView<RefModel>("branch", branchesDp) { | |
private static final long serialVersionUID = 1L; | |
int counter; | |
@Override | |
public void populateItem(final Item<RefModel> item) { | |
final RefModel entry = item.getModelObject(); | |
item.add(WicketUtils.createDateLabel("branchDate", entry.getDate(), getTimeZone(), getTimeUtils())); | |
item.add(new LinkPanel("branchName", "list name", StringUtils.trimString( | |
entry.displayName, 28), LogPage.class, WicketUtils.newObjectParameter( | |
model.name, entry.getName()))); | |
String author = entry.getAuthorIdent().getName(); | |
LinkPanel authorLink = new LinkPanel("branchAuthor", "list", author, | |
GitSearchPage.class, WicketUtils.newSearchParameter(model.name, | |
entry.getName(), author, Constants.SearchType.AUTHOR)); | |
setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR); | |
item.add(authorLink); | |
// short message | |
String shortMessage = entry.getShortMessage(); | |
String trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); | |
LinkPanel shortlog = new LinkPanel("branchLog", "list subject", trimmedMessage, | |
CommitPage.class, WicketUtils.newObjectParameter(model.name, | |
entry.getName())); | |
if (!shortMessage.equals(trimmedMessage)) { | |
shortlog.setTooltip(shortMessage); | |
} | |
item.add(shortlog); | |
if (maxCount <= 0) { | |
Fragment fragment = new Fragment("branchLinks", showDelete? "branchPageAdminLinks" : "branchPageLinks", this); | |
fragment.add(new BookmarkablePageLink<Void>("log", LogPage.class, WicketUtils | |
.newObjectParameter(model.name, entry.getName()))); | |
fragment.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils | |
.newObjectParameter(model.name, entry.getName()))); | |
String rawUrl = RawServlet.asLink(getContextUrl(), model.name, Repository.shortenRefName(entry.getName()), null); | |
fragment.add(new ExternalLink("raw", rawUrl)); | |
fragment.add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class, | |
WicketUtils.newObjectParameter(model.name, entry.getName()))); | |
fragment.add(new ExternalLink("syndication", SyndicationServlet.asLink( | |
getRequest().getRelativePathPrefixToContextRoot(), model.name, | |
entry.getName(), 0))); | |
if (showDelete) { | |
fragment.add(createDeleteBranchLink(model, entry)); | |
} | |
item.add(fragment); | |
} else { | |
Fragment fragment = new Fragment("branchLinks", "branchPanelLinks", this); | |
fragment.add(new BookmarkablePageLink<Void>("log", LogPage.class, WicketUtils | |
.newObjectParameter(model.name, entry.getName()))); | |
fragment.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils | |
.newObjectParameter(model.name, entry.getName()))); | |
String rawUrl = RawServlet.asLink(getContextUrl(), model.name, Repository.shortenRefName(entry.getName()), null); | |
fragment.add(new ExternalLink("raw", rawUrl)); | |
item.add(fragment); | |
} | |
WicketUtils.setAlternatingBackground(item, counter); | |
counter++; | |
} | |
}; | |
add(branchesView); | |
if (branches.size() < maxCount || maxCount <= 0) { | |
add(new Label("allBranches", "").setVisible(false)); | |
} else { | |
add(new LinkPanel("allBranches", "link", new StringResourceModel("gb.allBranches", | |
this, null), BranchesPage.class, WicketUtils.newRepositoryParameter(model.name))); | |
} | |
// We always have 1 branch | |
hasBranches = (branches.size() > 1) | |
|| ((branches.size() == 1) && !branches.get(0).displayName | |
.equalsIgnoreCase("master")); | |
} | |
public BranchesPanel hideIfEmpty() { | |
setVisible(hasBranches); | |
return this; | |
} | |
private Link<Void> createDeleteBranchLink(final RepositoryModel repositoryModel, final RefModel entry) | |
{ | |
Link<Void> deleteLink = new Link<Void>("deleteBranch") { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public void onClick() { | |
Repository r = app().repositories().getRepository(repositoryModel.name); | |
if (r == null) { | |
if (app().repositories().isCollectingGarbage(repositoryModel.name)) { | |
error(MessageFormat.format(getString("gb.busyCollectingGarbage"), repositoryModel.name)); | |
} else { | |
error(MessageFormat.format("Failed to find repository {0}", repositoryModel.name)); | |
} | |
return; | |
} | |
final String branch = entry.getName(); | |
Ref ref = null; | |
try { | |
ref = r.getRef(branch); | |
if (ref == null && !branch.startsWith(Constants.R_HEADS)) { | |
ref = r.getRef(Constants.R_HEADS + branch); | |
} | |
} catch (IOException e) { | |
} | |
if (ref != null) { | |
boolean success = JGitUtils.deleteBranchRef(r, ref.getName()); | |
if (success) { | |
// clear commit cache | |
CommitCache.instance().clear(repositoryModel.name, branch); | |
// optionally update reflog | |
if (RefLogUtils.hasRefLogBranch(r)) { | |
UserModel user = GitBlitWebSession.get().getUser(); | |
RefLogUtils.deleteRef(user, r, ref); | |
} | |
} | |
if (success) { | |
info(MessageFormat.format("Branch \"{0}\" deleted", branch)); | |
} else { | |
error(MessageFormat.format("Failed to delete branch \"{0}\"", branch)); | |
} | |
} | |
r.close(); | |
// redirect to the owning page | |
PageParameters params = WicketUtils.newRepositoryParameter(repositoryModel.name); | |
String relativeUrl = urlFor(getPage().getClass(), params).toString(); | |
String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl); | |
getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl)); | |
} | |
}; | |
deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( | |
"Delete branch \"{0}\"?", entry.displayName ))); | |
return deleteLink; | |
} | |
} |