You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommitPage.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  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. */
  16. package com.gitblit.wicket.pages;
  17. import java.io.OutputStream;
  18. import java.util.ArrayList;
  19. import java.util.Arrays;
  20. import java.util.List;
  21. import org.apache.wicket.PageParameters;
  22. import org.apache.wicket.markup.html.basic.Label;
  23. import org.apache.wicket.markup.html.link.BookmarkablePageLink;
  24. import org.apache.wicket.markup.html.link.ExternalLink;
  25. import org.apache.wicket.markup.html.link.Link;
  26. import org.apache.wicket.markup.repeater.Item;
  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;
  30. import org.apache.wicket.request.target.resource.ResourceStreamRequestTarget;
  31. import org.apache.wicket.util.resource.AbstractResourceStreamWriter;
  32. import org.apache.wicket.util.resource.IResourceStream;
  33. import org.eclipse.jgit.diff.DiffEntry.ChangeType;
  34. import org.eclipse.jgit.lib.Repository;
  35. import org.eclipse.jgit.revwalk.RevCommit;
  36. import com.gitblit.Constants;
  37. import com.gitblit.models.GitNote;
  38. import com.gitblit.models.PathModel.PathChangeModel;
  39. import com.gitblit.models.SubmoduleModel;
  40. import com.gitblit.models.UserModel;
  41. import com.gitblit.servlet.RawServlet;
  42. import com.gitblit.utils.JGitUtils;
  43. import com.gitblit.wicket.CacheControl;
  44. import com.gitblit.wicket.GitBlitWebSession;
  45. import com.gitblit.wicket.CacheControl.LastModified;
  46. import com.gitblit.wicket.WicketUtils;
  47. import com.gitblit.wicket.panels.CommitHeaderPanel;
  48. import com.gitblit.wicket.panels.CommitLegendPanel;
  49. import com.gitblit.wicket.panels.CompressedDownloadsPanel;
  50. import com.gitblit.wicket.panels.DiffStatPanel;
  51. import com.gitblit.wicket.panels.AvatarImage;
  52. import com.gitblit.wicket.panels.LinkPanel;
  53. import com.gitblit.wicket.panels.RefsPanel;
  54. @CacheControl(LastModified.BOOT)
  55. public class CommitPage extends RepositoryPage {
  56. public CommitPage(PageParameters params) {
  57. super(params);
  58. Repository r = getRepository();
  59. RevCommit c = getCommit();
  60. List<String> parents = new ArrayList<String>();
  61. if (c.getParentCount() > 0) {
  62. for (RevCommit parent : c.getParents()) {
  63. parents.add(parent.name());
  64. }
  65. }
  66. // commit page links
  67. if (parents.size() == 0) {
  68. add(new Label("parentLink", "none"));
  69. add(new Label("commitdiffLink", getString("gb.commitdiff")));
  70. } else {
  71. add(new LinkPanel("parentLink", null, getShortObjectId(parents.get(0)),
  72. CommitPage.class, newCommitParameter(parents.get(0))));
  73. add(new LinkPanel("commitdiffLink", null, new StringResourceModel("gb.commitdiff",
  74. this, null), CommitDiffPage.class, WicketUtils.newObjectParameter(
  75. repositoryName, objectId)));
  76. }
  77. add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
  78. WicketUtils.newObjectParameter(repositoryName, objectId)));
  79. add(new CommitHeaderPanel("commitHeader", repositoryName, c));
  80. addRefs(r, c);
  81. // author
  82. add(createPersonPanel("commitAuthor", c.getAuthorIdent(), Constants.SearchType.AUTHOR));
  83. add(WicketUtils.createTimestampLabel("commitAuthorDate", c.getAuthorIdent().getWhen(),
  84. getTimeZone(), getTimeUtils()));
  85. // committer
  86. add(createPersonPanel("commitCommitter", c.getCommitterIdent(), Constants.SearchType.COMMITTER));
  87. add(WicketUtils.createTimestampLabel("commitCommitterDate",
  88. c.getCommitterIdent().getWhen(), getTimeZone(), getTimeUtils()));
  89. add(new Label("commitId", c.getName()));
  90. add(new LinkPanel("commitTree", "list", c.getTree().getName(), TreePage.class,
  91. newCommitParameter()));
  92. add(new BookmarkablePageLink<Void>("treeLink", TreePage.class, newCommitParameter()));
  93. final String baseUrl = WicketUtils.getGitblitURL(getRequest());
  94. add(new CompressedDownloadsPanel("compressedLinks", baseUrl, repositoryName, objectId, null));
  95. // Parent Commits
  96. ListDataProvider<String> parentsDp = new ListDataProvider<String>(parents);
  97. DataView<String> parentsView = new DataView<String>("commitParents", parentsDp) {
  98. private static final long serialVersionUID = 1L;
  99. @Override
  100. public void populateItem(final Item<String> item) {
  101. String entry = item.getModelObject();
  102. item.add(new LinkPanel("commitParent", "list", entry, CommitPage.class,
  103. newCommitParameter(entry)));
  104. item.add(new BookmarkablePageLink<Void>("view", CommitPage.class,
  105. newCommitParameter(entry)));
  106. item.add(new BookmarkablePageLink<Void>("diff", CommitDiffPage.class,
  107. newCommitParameter(entry)));
  108. }
  109. };
  110. add(parentsView);
  111. addFullText("fullMessage", c.getFullMessage());
  112. // git notes
  113. List<GitNote> notes = JGitUtils.getNotesOnCommit(r, c);
  114. ListDataProvider<GitNote> notesDp = new ListDataProvider<GitNote>(notes);
  115. DataView<GitNote> notesView = new DataView<GitNote>("notes", notesDp) {
  116. private static final long serialVersionUID = 1L;
  117. @Override
  118. public void populateItem(final Item<GitNote> item) {
  119. GitNote entry = item.getModelObject();
  120. item.add(new RefsPanel("refName", repositoryName, Arrays.asList(entry.notesRef)));
  121. item.add(createPersonPanel("authorName", entry.notesRef.getAuthorIdent(),
  122. Constants.SearchType.AUTHOR));
  123. item.add(new AvatarImage("noteAuthorAvatar", entry.notesRef.getAuthorIdent()));
  124. item.add(WicketUtils.createTimestampLabel("authorDate", entry.notesRef
  125. .getAuthorIdent().getWhen(), getTimeZone(), getTimeUtils()));
  126. item.add(new Label("noteContent", bugtraqProcessor().processPlainCommitMessage(getRepository(), repositoryName,
  127. entry.content)).setEscapeModelStrings(false));
  128. }
  129. };
  130. add(notesView.setVisible(notes.size() > 0));
  131. // changed paths list
  132. List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, c);
  133. // add commit diffstat
  134. int insertions = 0;
  135. int deletions = 0;
  136. for (PathChangeModel pcm : paths) {
  137. insertions += pcm.insertions;
  138. deletions += pcm.deletions;
  139. }
  140. add(new DiffStatPanel("diffStat", insertions, deletions));
  141. add(new CommitLegendPanel("commitLegend", paths));
  142. ListDataProvider<PathChangeModel> pathsDp = new ListDataProvider<PathChangeModel>(paths);
  143. DataView<PathChangeModel> pathsView = new DataView<PathChangeModel>("changedPath", pathsDp) {
  144. private static final long serialVersionUID = 1L;
  145. int counter;
  146. @Override
  147. public void populateItem(final Item<PathChangeModel> item) {
  148. final PathChangeModel entry = item.getModelObject();
  149. Label changeType = new Label("changeType", "");
  150. WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
  151. setChangeTypeTooltip(changeType, entry.changeType);
  152. item.add(changeType);
  153. item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));
  154. item.add(WicketUtils.setHtmlTooltip(new Label("filestore", ""), getString("gb.filestore"))
  155. .setVisible(entry.isFilestoreItem()));
  156. boolean hasSubmodule = false;
  157. String submodulePath = null;
  158. if (entry.isTree()) {
  159. // tree
  160. item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
  161. WicketUtils
  162. .newPathParameter(repositoryName, entry.commitId, entry.path)));
  163. } else if (entry.isSubmodule()) {
  164. // submodule
  165. String submoduleId = entry.objectId;
  166. SubmoduleModel submodule = getSubmodule(entry.path);
  167. submodulePath = submodule.gitblitPath;
  168. hasSubmodule = submodule.hasSubmodule;
  169. item.add(new LinkPanel("pathName", "list", entry.path + " @ " +
  170. getShortObjectId(submoduleId), TreePage.class,
  171. WicketUtils.newPathParameter(submodulePath, submoduleId, "")).setEnabled(hasSubmodule));
  172. } else {
  173. // blob
  174. String displayPath = entry.path;
  175. String path = entry.path;
  176. if (entry.isSymlink()) {
  177. path = JGitUtils.getStringContent(getRepository(), getCommit().getTree(), path);
  178. displayPath = entry.path + " -> " + path;
  179. }
  180. if (entry.isFilestoreItem()) {
  181. item.add(new LinkPanel("pathName", "list", entry.path, new Link<Object>("link", null) {
  182. private static final long serialVersionUID = 1L;
  183. @Override
  184. public void onClick() {
  185. IResourceStream resourceStream = new AbstractResourceStreamWriter() {
  186. private static final long serialVersionUID = 1L;
  187. @Override
  188. public void write(OutputStream output) {
  189. UserModel user = GitBlitWebSession.get().getUser();
  190. user = user == null ? UserModel.ANONYMOUS : user;
  191. app().filestore().downloadBlob(entry.getFilestoreOid(), user, getRepositoryModel(), output);
  192. }
  193. };
  194. getRequestCycle().setRequestTarget(new ResourceStreamRequestTarget(resourceStream, entry.path));
  195. }}));
  196. } else {
  197. item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,
  198. WicketUtils.newPathParameter(repositoryName, entry.commitId, path)));
  199. }
  200. }
  201. // quick links
  202. if (entry.isSubmodule()) {
  203. item.add(new ExternalLink("raw", "").setEnabled(false));
  204. // submodule
  205. item.add(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
  206. .newPathParameter(repositoryName, entry.commitId, entry.path))
  207. .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
  208. item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
  209. .newObjectParameter(submodulePath, entry.objectId)).setEnabled(hasSubmodule));
  210. item.add(new ExternalLink("blame", "").setEnabled(false));
  211. item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
  212. .newPathParameter(repositoryName, entry.commitId, entry.path))
  213. .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
  214. } else {
  215. // tree or blob
  216. item.add(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
  217. .newPathParameter(repositoryName, entry.commitId, entry.path))
  218. .setEnabled(!entry.changeType.equals(ChangeType.ADD)
  219. && !entry.changeType.equals(ChangeType.DELETE)));
  220. if (entry.isFilestoreItem()) {
  221. item.add(new Link<Object>("view", null) {
  222. private static final long serialVersionUID = 1L;
  223. @Override
  224. public void onClick() {
  225. IResourceStream resourceStream = new AbstractResourceStreamWriter() {
  226. private static final long serialVersionUID = 1L;
  227. @Override
  228. public void write(OutputStream output) {
  229. UserModel user = GitBlitWebSession.get().getUser();
  230. user = user == null ? UserModel.ANONYMOUS : user;
  231. app().filestore().downloadBlob(entry.getFilestoreOid(), user, getRepositoryModel(), output);
  232. }
  233. };
  234. getRequestCycle().setRequestTarget(new ResourceStreamRequestTarget(resourceStream, entry.path));
  235. }});
  236. item.add(new Link<Object>("raw", null) {
  237. private static final long serialVersionUID = 1L;
  238. @Override
  239. public void onClick() {
  240. IResourceStream resourceStream = new AbstractResourceStreamWriter() {
  241. private static final long serialVersionUID = 1L;
  242. @Override
  243. public void write(OutputStream output) {
  244. UserModel user = GitBlitWebSession.get().getUser();
  245. user = user == null ? UserModel.ANONYMOUS : user;
  246. app().filestore().downloadBlob(entry.getFilestoreOid(), user, getRepositoryModel(), output);
  247. }
  248. };
  249. getRequestCycle().setRequestTarget(new ResourceStreamRequestTarget(resourceStream, entry.path));
  250. }});
  251. } else {
  252. item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
  253. .newPathParameter(repositoryName, entry.commitId, entry.path))
  254. .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
  255. String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path);
  256. item.add(new ExternalLink("raw", rawUrl)
  257. .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
  258. }
  259. item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
  260. .newPathParameter(repositoryName, entry.commitId, entry.path))
  261. .setEnabled(!entry.changeType.equals(ChangeType.ADD)
  262. && !entry.changeType.equals(ChangeType.DELETE)));
  263. item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
  264. .newPathParameter(repositoryName, entry.commitId, entry.path))
  265. .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
  266. }
  267. WicketUtils.setAlternatingBackground(item, counter);
  268. counter++;
  269. }
  270. };
  271. add(pathsView);
  272. }
  273. @Override
  274. protected String getPageName() {
  275. return getString("gb.commit");
  276. }
  277. @Override
  278. protected boolean isCommitPage() {
  279. return true;
  280. }
  281. @Override
  282. protected Class<? extends BasePage> getRepoNavPageClass() {
  283. return LogPage.class;
  284. }
  285. }