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