James Moger
2012-11-06 798581cab5817310a1b9991dac3b10cd7813f86a
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  */
1f9dae 16 package com.gitblit.wicket.pages;
5fe7df 17
85c2e6 18 import java.io.Serializable;
bc9d4a 19 import java.text.MessageFormat;
3e087a 20 import java.util.ArrayList;
JM 21 import java.util.Arrays;
eb870f 22 import java.util.HashMap;
9e5bee 23 import java.util.LinkedHashMap;
eb870f 24 import java.util.LinkedHashSet;
5fe7df 25 import java.util.List;
JM 26 import java.util.Map;
eb870f 27 import java.util.Set;
5fe7df 28
98ce17 29 import org.apache.wicket.Component;
5fe7df 30 import org.apache.wicket.PageParameters;
JM 31 import org.apache.wicket.markup.html.basic.Label;
3e087a 32 import org.apache.wicket.markup.html.form.DropDownChoice;
JM 33 import org.apache.wicket.markup.html.form.TextField;
c22722 34 import org.apache.wicket.markup.html.link.ExternalLink;
98ce17 35 import org.apache.wicket.markup.html.panel.Fragment;
3e087a 36 import org.apache.wicket.model.IModel;
JM 37 import org.apache.wicket.model.Model;
77e1d2 38 import org.apache.wicket.protocol.http.RequestUtils;
JM 39 import org.apache.wicket.request.target.basic.RedirectRequestTarget;
9bc17d 40 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
98ce17 41 import org.eclipse.jgit.lib.PersonIdent;
5fe7df 42 import org.eclipse.jgit.lib.Repository;
JM 43 import org.eclipse.jgit.revwalk.RevCommit;
44
33d8d8 45 import com.gitblit.Constants;
fc948c 46 import com.gitblit.GitBlit;
87cc1e 47 import com.gitblit.Keys;
11924d 48 import com.gitblit.PagesServlet;
c22722 49 import com.gitblit.SyndicationServlet;
1e1b85 50 import com.gitblit.models.ProjectModel;
85f639 51 import com.gitblit.models.RefModel;
1f9dae 52 import com.gitblit.models.RepositoryModel;
eb870f 53 import com.gitblit.models.SubmoduleModel;
1e1b85 54 import com.gitblit.models.UserModel;
4e1930 55 import com.gitblit.utils.ArrayUtils;
5fe7df 56 import com.gitblit.utils.JGitUtils;
f5d0ad 57 import com.gitblit.utils.StringUtils;
793f76 58 import com.gitblit.utils.TicgitUtils;
1f9dae 59 import com.gitblit.wicket.GitBlitWebSession;
9e5bee 60 import com.gitblit.wicket.PageRegistration;
11924d 61 import com.gitblit.wicket.PageRegistration.OtherPageLink;
ed295f 62 import com.gitblit.wicket.SessionlessForm;
1f9dae 63 import com.gitblit.wicket.WicketUtils;
JM 64 import com.gitblit.wicket.panels.LinkPanel;
9e5bee 65 import com.gitblit.wicket.panels.NavigationPanel;
5fe7df 66 import com.gitblit.wicket.panels.RefsPanel;
JM 67
68 public abstract class RepositoryPage extends BasePage {
69
13a3f5 70     protected final String projectName;
5fe7df 71     protected final String repositoryName;
bc9d4a 72     protected final String objectId;
eb870f 73     
2a7306 74     private transient Repository r;
bc9d4a 75
2a7306 76     private RepositoryModel m;
5fe7df 77
eb870f 78     private Map<String, SubmoduleModel> submodules;
JM 79     
9e5bee 80     private final Map<String, PageRegistration> registeredPages;
eb9979 81     private boolean showAdmin;
33622b 82     private boolean isOwner;
JM 83     
cebf45 84     public RepositoryPage(PageParameters params) {
5fe7df 85         super(params);
7d35e2 86         repositoryName = WicketUtils.getRepositoryName(params);
1e1b85 87         String root =StringUtils.getFirstPathElement(repositoryName);
JM 88         if (StringUtils.isEmpty(root)) {
13a3f5 89             projectName = GitBlit.getString(Keys.web.repositoryRootGroupName, "main");
1e1b85 90         } else {
JM 91             projectName = root;
13a3f5 92         }
7d35e2 93         objectId = WicketUtils.getObject(params);
eb870f 94         
e92c6d 95         if (StringUtils.isEmpty(repositoryName)) {
JM 96             error(MessageFormat.format(getString("gb.repositoryNotSpecifiedFor"), getPageName()), true);
97         }
98
99         if (!getRepositoryModel().hasCommits) {
100             setResponsePage(EmptyRepositoryPage.class, params);
101         }
102         
103         if (getRepositoryModel().isCollectingGarbage) {
104             error(MessageFormat.format(getString("gb.busyCollectingGarbage"), getRepositoryModel().name), true);
105         }
106
85f639 107         if (objectId != null) {
LM 108             RefModel branch = null;
109             if ((branch = JGitUtils.getBranch(getRepository(), objectId)) != null) {
6d23ca 110                 UserModel user = GitBlitWebSession.get().getUser();
JM 111                 if (user == null) {
112                     // workaround until get().getUser() is reviewed throughout the app
113                     user = UserModel.ANONYMOUS;
114                 }
115                 boolean canAccess = user.hasBranchPermission(repositoryName,
85f639 116                                 branch.reference.getName());
LM 117                 if (!canAccess) {
e92c6d 118                     error(getString("gb.accessDeined"), true);
85f639 119                 }
LM 120             }
82df52 121         }
JM 122
9e5bee 123         // register the available page links for this page and user
JM 124         registeredPages = registerPages();
2a7306 125
3e087a 126         // standard page links
9e5bee 127         List<PageRegistration> pages = new ArrayList<PageRegistration>(registeredPages.values());
JM 128         NavigationPanel navigationPanel = new NavigationPanel("navPanel", getClass(), pages);
129         add(navigationPanel);
8c9a20 130
c22722 131         add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()
JM 132                 .getRelativePathPrefixToContextRoot(), repositoryName, null, 0)));
3e087a 133
JM 134         // add floating search form
135         SearchForm searchForm = new SearchForm("searchForm", repositoryName);
136         add(searchForm);
137         searchForm.setTranslatedAttributes();
bc9d4a 138
3e087a 139         // set stateless page preference
5fe7df 140         setStatelessHint(true);
3e087a 141     }
9e5bee 142
JM 143     private Map<String, PageRegistration> registerPages() {
144         PageParameters params = null;
145         if (!StringUtils.isEmpty(repositoryName)) {
146             params = WicketUtils.newRepositoryParameter(repositoryName);
147         }
148         Map<String, PageRegistration> pages = new LinkedHashMap<String, PageRegistration>();
149
150         // standard links
151         pages.put("repositories", new PageRegistration("gb.repositories", RepositoriesPage.class));
152         pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));
153         pages.put("log", new PageRegistration("gb.log", LogPage.class, params));
154         pages.put("branches", new PageRegistration("gb.branches", BranchesPage.class, params));
155         pages.put("tags", new PageRegistration("gb.tags", TagsPage.class, params));
156         pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params));
eb1405 157         pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params));
9e5bee 158
JM 159         // conditional links
160         Repository r = getRepository();
161         RepositoryModel model = getRepositoryModel();
162
163         // per-repository extra page links
164         if (model.useTickets && TicgitUtils.getTicketsBranch(r) != null) {
165             pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, params));
166         }
167         if (model.useDocs) {
168             pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params));
169         }
11924d 170         if (JGitUtils.getPagesBranch(r) != null) {
JM 171             OtherPageLink pagesLink = new OtherPageLink("gb.pages", PagesServlet.asLink(
172                     getRequest().getRelativePathPrefixToContextRoot(), repositoryName, null));
173             pages.put("pages", pagesLink);
174         }
175
9e5bee 176         // Conditionally add edit link
33622b 177         showAdmin = false;
9e5bee 178         if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
JM 179             boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
180             showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
181         } else {
182             showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
183         }
33622b 184         isOwner = GitBlitWebSession.get().isLoggedIn()
9e5bee 185                 && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get()
33622b 186                         .getUsername()));
JM 187         if (showAdmin || isOwner) {
9e5bee 188             pages.put("edit", new PageRegistration("gb.edit", EditRepositoryPage.class, params));
JM 189         }
190         return pages;
191     }
1f52c8 192     
JM 193     protected boolean allowForkControls() {
194         return true;
195     }
9e5bee 196
1f5915 197     @Override
11924d 198     protected void setupPage(String repositoryName, String pageName) {
1e1b85 199         String projectName = StringUtils.getFirstPathElement(repositoryName);
JM 200         ProjectModel project = GitBlit.self().getProjectModel(projectName);
201         if (project.isUserProject()) {
202             // user-as-project
203             add(new LinkPanel("projectTitle", null, project.getDisplayName(),
204                     UserPage.class, WicketUtils.newUsernameParameter(project.name.substring(1))));
ccab3a 205         } else {
1e1b85 206             // project
JM 207             add(new LinkPanel("projectTitle", null, project.name,
208                     ProjectPage.class, WicketUtils.newProjectParameter(project.name)));
209         }
210         
211         String name = StringUtils.stripDotGit(repositoryName);
212         if (!StringUtils.isEmpty(projectName) && name.startsWith(projectName)) {
213             name = name.substring(projectName.length() + 1);
214         }
215         add(new LinkPanel("repositoryName", null, name, SummaryPage.class,
216                 WicketUtils.newRepositoryParameter(repositoryName)));
217         add(new Label("pageName", pageName).setRenderBodyOnly(true));
218         
eb1405 219         UserModel user = GitBlitWebSession.get().getUser();
616590 220         if (user == null) {
JM 221             user = UserModel.ANONYMOUS;
222         }
eb1405 223
1e1b85 224         // indicate origin repository
JM 225         RepositoryModel model = getRepositoryModel();
226         if (StringUtils.isEmpty(model.originRepository)) {
227             add(new Label("originRepository").setVisible(false));
228         } else {
eb1405 229             RepositoryModel origin = GitBlit.self().getRepositoryModel(model.originRepository);
JM 230             if (origin == null) {
231                 // no origin repository
232                 add(new Label("originRepository").setVisible(false));
20714a 233             } else if (!user.canView(origin)) {
eb1405 234                 // show origin repository without link
JM 235                 Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
236                 forkFrag.add(new Label("originRepository", StringUtils.stripDotGit(model.originRepository)));
237                 add(forkFrag);
238             } else {
239                 // link to origin repository
240                 Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
241                 forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository), 
242                         SummaryPage.class, WicketUtils.newRepositoryParameter(model.originRepository)));
243                 add(forkFrag);
244             }
1e1b85 245         }
JM 246         
247         if (getRepositoryModel().isBare) {
248             add(new Label("workingCopyIndicator").setVisible(false));
249         } else {
250             Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this);
ccab3a 251             Label lbl = new Label("workingCopy", getString("gb.workingCopy"));
JM 252             WicketUtils.setHtmlTooltip(lbl,  getString("gb.workingCopyWarning"));
1e1b85 253             wc.add(lbl);
JM 254             add(wc);
ccab3a 255         }
eb1405 256
JM 257         // fork controls
616590 258         if (!allowForkControls() || user == null || !user.isAuthenticated) {
eb1405 259             // must be logged-in to fork, hide all fork controls
JM 260             add(new ExternalLink("forkLink", "").setVisible(false));
261             add(new ExternalLink("myForkLink", "").setVisible(false));
1e1b85 262             add(new Label("forksProhibitedIndicator").setVisible(false));
JM 263         } else {
eb1405 264             String fork = GitBlit.self().getFork(user.username, model.name);
JM 265             boolean hasFork = fork != null;
20714a 266             boolean canFork = user.canFork(model);
eb1405 267
JM 268             if (hasFork || !canFork) {
269                 // user not allowed to fork or fork already exists or repo forbids forking
270                 add(new ExternalLink("forkLink", "").setVisible(false));
271                 
7f7051 272                 if (user.canFork() && !model.allowForks) {
eb1405 273                     // show forks prohibited indicator
JM 274                     Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);
275                     Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));
276                     WicketUtils.setHtmlTooltip(lbl,  getString("gb.forksProhibitedWarning"));
277                     wc.add(lbl);
278                     add(wc);
279                 } else {
280                     // can not fork, no need for forks prohibited indicator
281                     add(new Label("forksProhibitedIndicator").setVisible(false));
282                 }
283                 
284                 if (hasFork && !fork.equals(model.name)) {
285                     // user has fork, view my fork link
286                     String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)).toString();
287                     add(new ExternalLink("myForkLink", url));
288                 } else {
289                     // no fork, hide view my fork link
290                     add(new ExternalLink("myForkLink", "").setVisible(false));
291                 }
292             } else if (canFork) {
293                 // can fork and we do not have one
294                 add(new Label("forksProhibitedIndicator").setVisible(false));
295                 add(new ExternalLink("myForkLink", "").setVisible(false));
1f52c8 296                 String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();
JM 297                 add(new ExternalLink("forkLink", url));
1e1b85 298             }
JM 299         }
300         
1f5915 301         super.setupPage(repositoryName, pageName);
8c9a20 302     }
JM 303
304     protected void addSyndicationDiscoveryLink() {
305         add(WicketUtils.syndicationDiscoveryLink(SyndicationServlet.getTitle(repositoryName,
306                 objectId), SyndicationServlet.asLink(getRequest()
307                 .getRelativePathPrefixToContextRoot(), repositoryName, objectId, 0)));
5fe7df 308     }
JM 309
310     protected Repository getRepository() {
311         if (r == null) {
f5d0ad 312             Repository r = GitBlit.self().getRepository(repositoryName);
7ba0ec 313             if (r == null) {
6caa93 314                 error(getString("gb.canNotLoadRepository") + " " + repositoryName, true);
7ba0ec 315                 return null;
JM 316             }
317             this.r = r;
5fe7df 318         }
JM 319         return r;
320     }
bc9d4a 321
f97bf0 322     protected RepositoryModel getRepositoryModel() {
JM 323         if (m == null) {
2a7306 324             RepositoryModel model = GitBlit.self().getRepositoryModel(
JM 325                     GitBlitWebSession.get().getUser(), repositoryName);
dfb889 326             if (model == null) {
d97e52 327                 if (GitBlit.self().hasRepository(repositoryName)) {
JM 328                     // has repository, but unauthorized
329                     authenticationError(getString("gb.unauthorizedAccessForRepository") + " " + repositoryName);
330                 } else {
331                     // does not have repository
332                     error(getString("gb.canNotLoadRepository") + " " + repositoryName, true);
333                 }
00afd7 334                 return null;
dfb889 335             }
JM 336             m = model;
f97bf0 337         }
JM 338         return m;
bc9d4a 339     }
dfb889 340
bc9d4a 341     protected RevCommit getCommit() {
JM 342         RevCommit commit = JGitUtils.getCommit(r, objectId);
343         if (commit == null) {
6caa93 344             error(MessageFormat.format(getString("gb.failedToFindCommit"),
2a7306 345                     objectId, repositoryName, getPageName()), true);
bc9d4a 346         }
eb870f 347         getSubmodules(commit);
bc9d4a 348         return commit;
f97bf0 349     }
eb870f 350     
JM 351     private Map<String, SubmoduleModel> getSubmodules(RevCommit commit) {    
352         if (submodules == null) {
353             submodules = new HashMap<String, SubmoduleModel>();
354             for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {
355                 submodules.put(model.path, model);
356             }
357         }
358         return submodules;
359     }
360     
361     protected Map<String, SubmoduleModel> getSubmodules() {
362         return submodules;
363     }
364     
365     protected SubmoduleModel getSubmodule(String path) {
366         SubmoduleModel model = submodules.get(path);
367         if (model == null) {
368             // undefined submodule?!
369             model = new SubmoduleModel(path.substring(path.lastIndexOf('/') + 1), path, path);
370             model.hasSubmodule = false;
371             model.gitblitPath = model.name;
372             return model;
373         } else {
374             // extract the repository name from the clone url
375             List<String> patterns = GitBlit.getStrings(Keys.git.submoduleUrlPatterns);
376             String submoduleName = StringUtils.extractRepositoryPath(model.url, patterns.toArray(new String[0]));
377             
378             // determine the current path for constructing paths relative
379             // to the current repository
380             String currentPath = "";
381             if (repositoryName.indexOf('/') > -1) {
382                 currentPath = repositoryName.substring(0, repositoryName.lastIndexOf('/') + 1);
383             }
384
385             // try to locate the submodule repository
386             // prefer bare to non-bare names
387             List<String> candidates = new ArrayList<String>();
388
389             // relative
390             candidates.add(currentPath + StringUtils.stripDotGit(submoduleName));
391             candidates.add(candidates.get(candidates.size() - 1) + ".git");
392
393             // relative, no subfolder
394             if (submoduleName.lastIndexOf('/') > -1) {
395                 String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
396                 candidates.add(currentPath + StringUtils.stripDotGit(name));
397                 candidates.add(currentPath + candidates.get(candidates.size() - 1) + ".git");
398             }
399
400             // absolute
401             candidates.add(StringUtils.stripDotGit(submoduleName));
402             candidates.add(candidates.get(candidates.size() - 1) + ".git");
403
404             // absolute, no subfolder
405             if (submoduleName.lastIndexOf('/') > -1) {
406                 String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
407                 candidates.add(StringUtils.stripDotGit(name));
408                 candidates.add(candidates.get(candidates.size() - 1) + ".git");
409             }
410
411             // create a unique, ordered set of candidate paths
412             Set<String> paths = new LinkedHashSet<String>(candidates);
413             for (String candidate : paths) {
414                 if (GitBlit.self().hasRepository(candidate)) {
415                     model.hasSubmodule = true;
416                     model.gitblitPath = candidate;
417                     return model;
418                 }
419             }
420             
421             // we do not have a copy of the submodule, but we need a path
422             model.gitblitPath = candidates.get(0);
423             return model;
424         }        
425     }
5fe7df 426
008322 427     protected String getShortObjectId(String objectId) {
798581 428         return objectId.substring(0, GitBlit.getInteger(Keys.web.shortCommitIdLength, 8));
008322 429     }
JM 430
5fe7df 431     protected void addRefs(Repository r, RevCommit c) {
1e1b85 432         add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r, getRepositoryModel().showRemoteBranches)));
5fe7df 433     }
JM 434
435     protected void addFullText(String wicketId, String text, boolean substituteRegex) {
227736 436         String html = StringUtils.escapeForHtml(text, true);
5fe7df 437         if (substituteRegex) {
8c9a20 438             html = GitBlit.self().processCommitMessage(repositoryName, text);
f339f5 439         } else {
227736 440             html = StringUtils.breakLinesForHtml(html);
f339f5 441         }
JM 442         add(new Label(wicketId, html).setEscapeModelStrings(false));
5fe7df 443     }
1e47ab 444
cebf45 445     protected abstract String getPageName();
5fe7df 446
2a7306 447     protected Component createPersonPanel(String wicketId, PersonIdent identity,
33d8d8 448             Constants.SearchType searchType) {
e11f48 449         String name = identity == null ? "" : identity.getName();
JM 450         String address = identity == null ? "" : identity.getEmailAddress();
2a7306 451         boolean showEmail = GitBlit.getBoolean(Keys.web.showEmailAddresses, false);
e11f48 452         if (!showEmail || StringUtils.isEmpty(name) || StringUtils.isEmpty(address)) {
JM 453             String value = name;
98ce17 454             if (StringUtils.isEmpty(value)) {
f5d0ad 455                 if (showEmail) {
e11f48 456                     value = address;
f5d0ad 457                 } else {
JM 458                     value = getString("gb.missingUsername");
459                 }
98ce17 460             }
JM 461             Fragment partial = new Fragment(wicketId, "partialPersonIdent", this);
4e1930 462             LinkPanel link = new LinkPanel("personName", "list", value, GitSearchPage.class,
2a7306 463                     WicketUtils.newSearchParameter(repositoryName, objectId, value, searchType));
98ce17 464             setPersonSearchTooltip(link, value, searchType);
JM 465             partial.add(link);
466             return partial;
467         } else {
468             Fragment fullPerson = new Fragment(wicketId, "fullPersonIdent", this);
4e1930 469             LinkPanel nameLink = new LinkPanel("personName", "list", name, GitSearchPage.class,
e11f48 470                     WicketUtils.newSearchParameter(repositoryName, objectId, name, searchType));
JM 471             setPersonSearchTooltip(nameLink, name, searchType);
98ce17 472             fullPerson.add(nameLink);
3e087a 473
227736 474             LinkPanel addressLink = new LinkPanel("personAddress", "hidden-phone list", "<" + address + ">",
4e1930 475                     GitSearchPage.class, WicketUtils.newSearchParameter(repositoryName, objectId,
e11f48 476                             address, searchType));
JM 477             setPersonSearchTooltip(addressLink, address, searchType);
98ce17 478             fullPerson.add(addressLink);
JM 479             return fullPerson;
480         }
481     }
3e087a 482
11924d 483     protected void setPersonSearchTooltip(Component component, String value,
JM 484             Constants.SearchType searchType) {
33d8d8 485         if (searchType.equals(Constants.SearchType.AUTHOR)) {
1e8390 486             WicketUtils.setHtmlTooltip(component, getString("gb.searchForAuthor") + " " + value);
33d8d8 487         } else if (searchType.equals(Constants.SearchType.COMMITTER)) {
1e8390 488             WicketUtils.setHtmlTooltip(component, getString("gb.searchForCommitter") + " " + value);
98ce17 489         }
JM 490     }
3e087a 491
9bc17d 492     protected void setChangeTypeTooltip(Component container, ChangeType type) {
JM 493         switch (type) {
494         case ADD:
1e8390 495             WicketUtils.setHtmlTooltip(container, getString("gb.addition"));
9bc17d 496             break;
JM 497         case COPY:
498         case RENAME:
1e8390 499             WicketUtils.setHtmlTooltip(container, getString("gb.rename"));
9bc17d 500             break;
JM 501         case DELETE:
1e8390 502             WicketUtils.setHtmlTooltip(container, getString("gb.deletion"));
9bc17d 503             break;
JM 504         case MODIFY:
1e8390 505             WicketUtils.setHtmlTooltip(container, getString("gb.modification"));
9bc17d 506             break;
JM 507         }
508     }
3e087a 509
1e47ab 510     @Override
JM 511     protected void onBeforeRender() {
512         // dispose of repository object
513         if (r != null) {
514             r.close();
515             r = null;
516         }
517         // setup page header and footer
cebf45 518         setupPage(repositoryName, "/ " + getPageName());
1e47ab 519         super.onBeforeRender();
5fe7df 520     }
JM 521
522     protected PageParameters newRepositoryParameter() {
698678 523         return WicketUtils.newRepositoryParameter(repositoryName);
5fe7df 524     }
7ba0ec 525
5fe7df 526     protected PageParameters newCommitParameter() {
ef5c58 527         return WicketUtils.newObjectParameter(repositoryName, objectId);
5fe7df 528     }
7ba0ec 529
5fe7df 530     protected PageParameters newCommitParameter(String commitId) {
ef5c58 531         return WicketUtils.newObjectParameter(repositoryName, commitId);
5fe7df 532     }
JM 533
33622b 534     public boolean isShowAdmin() {
JM 535         return showAdmin;
536     }
537     
538     public boolean isOwner() {
539         return isOwner;
eb9979 540     }
A 541     
ed295f 542     private class SearchForm extends SessionlessForm<Void> implements Serializable {
3e087a 543         private static final long serialVersionUID = 1L;
JM 544
545         private final String repositoryName;
546
547         private final IModel<String> searchBoxModel = new Model<String>("");
548
11924d 549         private final IModel<Constants.SearchType> searchTypeModel = new Model<Constants.SearchType>(
JM 550                 Constants.SearchType.COMMIT);
3e087a 551
JM 552         public SearchForm(String id, String repositoryName) {
ed295f 553             super(id, RepositoryPage.this.getClass(), RepositoryPage.this.getPageParameters());
3e087a 554             this.repositoryName = repositoryName;
11924d 555             DropDownChoice<Constants.SearchType> searchType = new DropDownChoice<Constants.SearchType>(
JM 556                     "searchType", Arrays.asList(Constants.SearchType.values()));
3e087a 557             searchType.setModel(searchTypeModel);
2a7306 558             add(searchType.setVisible(GitBlit.getBoolean(Keys.web.showSearchTypeSelection, false)));
3e087a 559             TextField<String> searchBox = new TextField<String>("searchBox", searchBoxModel);
JM 560             add(searchBox);
561         }
bc9d4a 562
JM 563         void setTranslatedAttributes() {
3e087a 564             WicketUtils.setHtmlTooltip(get("searchType"), getString("gb.searchTypeTooltip"));
9e5bee 565             WicketUtils.setHtmlTooltip(get("searchBox"),
JM 566                     MessageFormat.format(getString("gb.searchTooltip"), repositoryName));
bc9d4a 567             WicketUtils.setInputPlaceholder(get("searchBox"), getString("gb.search"));
3e087a 568         }
JM 569
570         @Override
571         public void onSubmit() {
33d8d8 572             Constants.SearchType searchType = searchTypeModel.getObject();
3e087a 573             String searchString = searchBoxModel.getObject();
8c5d72 574             if (searchString == null) {
JM 575                 return;
576             }
33d8d8 577             for (Constants.SearchType type : Constants.SearchType.values()) {
3e087a 578                 if (searchString.toLowerCase().startsWith(type.name().toLowerCase() + ":")) {
JM 579                     searchType = type;
2a7306 580                     searchString = searchString.substring(type.name().toLowerCase().length() + 1)
JM 581                             .trim();
3e087a 582                     break;
JM 583                 }
584             }
4e1930 585             Class<? extends BasePage> searchPageClass = GitSearchPage.class;
JM 586             RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);
7db092 587             if (GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true)
JM 588                     && !ArrayUtils.isEmpty(model.indexedBranches)) {
4e1930 589                 // this repository is Lucene-indexed
JM 590                 searchPageClass = LuceneSearchPage.class;
591             }
77e1d2 592             // use an absolute url to workaround Wicket-Tomcat problems with
JM 593             // mounted url parameters (issue-111)
594             PageParameters params = WicketUtils.newSearchParameter(repositoryName, null, searchString, searchType);
595             String relativeUrl = urlFor(searchPageClass, params).toString();
596             String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
597             getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
3e087a 598         }
JM 599     }
85f639 600 }