James Moger
2012-11-27 d83bd6d3acfc88a991a08a15dfa3ac36770bb0b8
commit | author | age
f13c4c 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
f602a2 16 package com.gitblit.wicket.panels;
JM 17
d83bd6 18 import java.util.Collections;
f602a2 19 import java.util.Date;
JM 20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.wicket.markup.html.basic.Label;
24 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
e299e1 25 import org.apache.wicket.markup.html.panel.Fragment;
f602a2 26 import org.apache.wicket.markup.repeater.Item;
JM 27 import org.apache.wicket.markup.repeater.data.DataView;
28 import org.apache.wicket.markup.repeater.data.ListDataProvider;
29 import org.apache.wicket.model.StringResourceModel;
d83bd6 30 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
f602a2 31 import org.eclipse.jgit.lib.ObjectId;
JM 32 import org.eclipse.jgit.lib.Repository;
33 import org.eclipse.jgit.revwalk.RevCommit;
d83bd6 34 import org.eclipse.jgit.treewalk.TreeWalk;
JM 35 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
f602a2 36
33d8d8 37 import com.gitblit.Constants;
f602a2 38 import com.gitblit.GitBlit;
JM 39 import com.gitblit.Keys;
1f9dae 40 import com.gitblit.models.PathModel;
JM 41 import com.gitblit.models.PathModel.PathChangeModel;
4ab184 42 import com.gitblit.models.RefModel;
f602a2 43 import com.gitblit.utils.JGitUtils;
9bc17d 44 import com.gitblit.utils.StringUtils;
f602a2 45 import com.gitblit.wicket.WicketUtils;
JM 46 import com.gitblit.wicket.pages.BlobDiffPage;
e299e1 47 import com.gitblit.wicket.pages.BlobPage;
f602a2 48 import com.gitblit.wicket.pages.CommitDiffPage;
JM 49 import com.gitblit.wicket.pages.CommitPage;
50 import com.gitblit.wicket.pages.HistoryPage;
4e1930 51 import com.gitblit.wicket.pages.GitSearchPage;
e299e1 52 import com.gitblit.wicket.pages.TreePage;
f602a2 53
JM 54 public class HistoryPanel extends BasePanel {
55
56     private static final long serialVersionUID = 1L;
e299e1 57
2a7306 58     private boolean hasMore;
f602a2 59
2a7306 60     public HistoryPanel(String wicketId, final String repositoryName, final String objectId,
1e1b85 61             final String path, Repository r, int limit, int pageOffset, boolean showRemoteRefs) {
f602a2 62         super(wicketId);
JM 63         boolean pageResults = limit <= 0;
2a7306 64         int itemsPerPage = GitBlit.getInteger(Keys.web.itemsPerPage, 50);
f602a2 65         if (itemsPerPage <= 1) {
JM 66             itemsPerPage = 50;
67         }
e299e1 68
JM 69         RevCommit commit = JGitUtils.getCommit(r, objectId);
9bc17d 70         List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit);
e299e1 71
JM 72         PathModel matchingPath = null;
73         for (PathModel p : paths) {
74             if (p.path.equals(path)) {
75                 matchingPath = p;
76                 break;
77             }
78         }
d83bd6 79         if (matchingPath == null) {
JM 80             // path not in commit
81             // manually locate path in tree
82             TreeWalk tw = new TreeWalk(r);
83             tw.reset();
84             tw.setRecursive(true);
85             try {
86                 tw.addTree(commit.getTree());
87                 tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));
88                 while (tw.next()) {
89                     matchingPath = new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw
90                             .getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(),
91                             ChangeType.MODIFY);
92                 }
93             } catch (Exception e) {
94             } finally {
95                 tw.release();
96             }
97         }
98         
e299e1 99         final boolean isTree = matchingPath == null ? true : matchingPath.isTree();
JM 100
1e1b85 101         final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs);
f602a2 102         List<RevCommit> commits;
JM 103         if (pageResults) {
104             // Paging result set
2a7306 105             commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage,
JM 106                     itemsPerPage);
f602a2 107         } else {
JM 108             // Fixed size result set
109             commits = JGitUtils.getRevLog(r, objectId, path, 0, limit);
110         }
e299e1 111
f602a2 112         // inaccurate way to determine if there are more commits.
e299e1 113         // works unless commits.size() represents the exact end.
f602a2 114         hasMore = commits.size() >= itemsPerPage;
JM 115
c1c3c6 116         add(new CommitHeaderPanel("commitHeader", repositoryName, commit));
f602a2 117
JM 118         // breadcrumbs
119         add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, path, objectId));
120
121         ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
122         DataView<RevCommit> logView = new DataView<RevCommit>("commit", dp) {
123             private static final long serialVersionUID = 1L;
2a7306 124             int counter;
f602a2 125
JM 126             public void populateItem(final Item<RevCommit> item) {
127                 final RevCommit entry = item.getModelObject();
128                 final Date date = JGitUtils.getCommitDate(entry);
129
9adf62 130                 item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils()));
f602a2 131
98ce17 132                 // author search link
f602a2 133                 String author = entry.getAuthorIdent().getName();
2a7306 134                 LinkPanel authorLink = new LinkPanel("commitAuthor", "list", author,
4e1930 135                         GitSearchPage.class,
JM 136                         WicketUtils.newSearchParameter(repositoryName, objectId,
33d8d8 137                                 author, Constants.SearchType.AUTHOR));
JM 138                 setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR);
98ce17 139                 item.add(authorLink);
f5d0ad 140
a645ba 141                 // merge icon
JM 142                 if (entry.getParentCount() > 1) {
1e8390 143                     item.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));
a645ba 144                 } else {
1e8390 145                     item.add(WicketUtils.newBlankImage("commitIcon"));
a645ba 146                 }
JM 147
f602a2 148                 String shortMessage = entry.getShortMessage();
a45caa 149                 String trimmedMessage = shortMessage;
JM 150                 if (allRefs.containsKey(entry.getId())) {
151                     trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);
152                 } else {
153                     trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);
154                 }
2a7306 155                 LinkPanel shortlog = new LinkPanel("commitShortMessage", "list subject",
JM 156                         trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(
157                                 repositoryName, entry.getName()));
f602a2 158                 if (!shortMessage.equals(trimmedMessage)) {
1e8390 159                     WicketUtils.setHtmlTooltip(shortlog, shortMessage);
f602a2 160                 }
JM 161                 item.add(shortlog);
162
163                 item.add(new RefsPanel("commitRefs", repositoryName, entry, allRefs));
164
e299e1 165                 if (isTree) {
JM 166                     Fragment links = new Fragment("historyLinks", "treeLinks", this);
2a7306 167                     links.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils
JM 168                             .newObjectParameter(repositoryName, entry.getName())));
169                     links.add(new BookmarkablePageLink<Void>("commitdiff", CommitDiffPage.class,
170                             WicketUtils.newObjectParameter(repositoryName, entry.getName())));
e299e1 171                     item.add(links);
JM 172                 } else {
173                     Fragment links = new Fragment("historyLinks", "blobLinks", this);
2a7306 174                     links.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
JM 175                             .newPathParameter(repositoryName, entry.getName(), path)));
176                     links.add(new BookmarkablePageLink<Void>("commitdiff", CommitDiffPage.class,
177                             WicketUtils.newObjectParameter(repositoryName, entry.getName())));
178                     links.add(new BookmarkablePageLink<Void>("difftocurrent", BlobDiffPage.class,
179                             WicketUtils.newBlobDiffParameter(repositoryName, entry.getName(),
180                                     objectId, path)).setEnabled(counter > 0));
e299e1 181                     item.add(links);
JM 182                 }
f602a2 183
JM 184                 WicketUtils.setAlternatingBackground(item, counter);
185                 counter++;
186             }
187         };
188         add(logView);
189
190         // determine to show pager, more, or neither
191         if (limit <= 0) {
192             // no display limit
193             add(new Label("moreHistory", "").setVisible(false));
194         } else {
195             if (pageResults) {
196                 // paging
197                 add(new Label("moreHistory", "").setVisible(false));
198             } else {
199                 // more
200                 if (commits.size() == limit) {
201                     // show more
2a7306 202                     add(new LinkPanel("moreHistory", "link", new StringResourceModel(
JM 203                             "gb.moreHistory", this, null), HistoryPage.class,
204                             WicketUtils.newPathParameter(repositoryName, objectId, path)));
f602a2 205                 } else {
JM 206                     // no more
207                     add(new Label("moreHistory", "").setVisible(false));
208                 }
209             }
210         }
211     }
e299e1 212
f602a2 213     public boolean hasMore() {
JM 214         return hasMore;
215     }
216 }