James Moger
2013-05-15 bca8c5c52554b6aac65b8e2300675ae8f6af1d6d
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                 }
92d477 115                 boolean canAccess = user.canView(getRepositoryModel(),
85f639 116                                 branch.reference.getName());
LM 117                 if (!canAccess) {
13f880 118                     error(getString("gb.accessDenied"), 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));
428b22 157         if (GitBlit.getBoolean(Keys.web.allowForking, true)) {
M 158             pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params));
159         }
9e5bee 160
JM 161         // conditional links
162         Repository r = getRepository();
163         RepositoryModel model = getRepositoryModel();
164
165         // per-repository extra page links
166         if (model.useTickets && TicgitUtils.getTicketsBranch(r) != null) {
167             pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, params));
168         }
169         if (model.useDocs) {
170             pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params));
171         }
11924d 172         if (JGitUtils.getPagesBranch(r) != null) {
JM 173             OtherPageLink pagesLink = new OtherPageLink("gb.pages", PagesServlet.asLink(
174                     getRequest().getRelativePathPrefixToContextRoot(), repositoryName, null));
175             pages.put("pages", pagesLink);
176         }
177
9e5bee 178         // Conditionally add edit link
33622b 179         showAdmin = false;
9e5bee 180         if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
JM 181             boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
182             showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
183         } else {
184             showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
185         }
33622b 186         isOwner = GitBlitWebSession.get().isLoggedIn()
661db6 187                 && (model.isOwner(GitBlitWebSession.get()
33622b 188                         .getUsername()));
JM 189         if (showAdmin || isOwner) {
9e5bee 190             pages.put("edit", new PageRegistration("gb.edit", EditRepositoryPage.class, params));
JM 191         }
192         return pages;
193     }
1f52c8 194     
JM 195     protected boolean allowForkControls() {
428b22 196         return GitBlit.getBoolean(Keys.web.allowForking, true);
1f52c8 197     }
9e5bee 198
1f5915 199     @Override
11924d 200     protected void setupPage(String repositoryName, String pageName) {
1e1b85 201         String projectName = StringUtils.getFirstPathElement(repositoryName);
JM 202         ProjectModel project = GitBlit.self().getProjectModel(projectName);
203         if (project.isUserProject()) {
204             // user-as-project
205             add(new LinkPanel("projectTitle", null, project.getDisplayName(),
206                     UserPage.class, WicketUtils.newUsernameParameter(project.name.substring(1))));
ccab3a 207         } else {
1e1b85 208             // project
JM 209             add(new LinkPanel("projectTitle", null, project.name,
210                     ProjectPage.class, WicketUtils.newProjectParameter(project.name)));
211         }
212         
213         String name = StringUtils.stripDotGit(repositoryName);
214         if (!StringUtils.isEmpty(projectName) && name.startsWith(projectName)) {
215             name = name.substring(projectName.length() + 1);
216         }
217         add(new LinkPanel("repositoryName", null, name, SummaryPage.class,
218                 WicketUtils.newRepositoryParameter(repositoryName)));
219         add(new Label("pageName", pageName).setRenderBodyOnly(true));
220         
eb1405 221         UserModel user = GitBlitWebSession.get().getUser();
616590 222         if (user == null) {
JM 223             user = UserModel.ANONYMOUS;
224         }
eb1405 225
1e1b85 226         // indicate origin repository
JM 227         RepositoryModel model = getRepositoryModel();
228         if (StringUtils.isEmpty(model.originRepository)) {
229             add(new Label("originRepository").setVisible(false));
230         } else {
eb1405 231             RepositoryModel origin = GitBlit.self().getRepositoryModel(model.originRepository);
JM 232             if (origin == null) {
233                 // no origin repository
234                 add(new Label("originRepository").setVisible(false));
20714a 235             } else if (!user.canView(origin)) {
eb1405 236                 // show origin repository without link
JM 237                 Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
238                 forkFrag.add(new Label("originRepository", StringUtils.stripDotGit(model.originRepository)));
239                 add(forkFrag);
240             } else {
241                 // link to origin repository
242                 Fragment forkFrag = new Fragment("originRepository", "originFragment", this);
243                 forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository), 
244                         SummaryPage.class, WicketUtils.newRepositoryParameter(model.originRepository)));
245                 add(forkFrag);
246             }
1e1b85 247         }
JM 248         
249         if (getRepositoryModel().isBare) {
250             add(new Label("workingCopyIndicator").setVisible(false));
251         } else {
252             Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this);
ccab3a 253             Label lbl = new Label("workingCopy", getString("gb.workingCopy"));
JM 254             WicketUtils.setHtmlTooltip(lbl,  getString("gb.workingCopyWarning"));
1e1b85 255             wc.add(lbl);
JM 256             add(wc);
ccab3a 257         }
eb1405 258
JM 259         // fork controls
616590 260         if (!allowForkControls() || user == null || !user.isAuthenticated) {
eb1405 261             // must be logged-in to fork, hide all fork controls
JM 262             add(new ExternalLink("forkLink", "").setVisible(false));
263             add(new ExternalLink("myForkLink", "").setVisible(false));
1e1b85 264             add(new Label("forksProhibitedIndicator").setVisible(false));
JM 265         } else {
eb1405 266             String fork = GitBlit.self().getFork(user.username, model.name);
JM 267             boolean hasFork = fork != null;
20714a 268             boolean canFork = user.canFork(model);
eb1405 269
JM 270             if (hasFork || !canFork) {
271                 // user not allowed to fork or fork already exists or repo forbids forking
272                 add(new ExternalLink("forkLink", "").setVisible(false));
273                 
7f7051 274                 if (user.canFork() && !model.allowForks) {
eb1405 275                     // show forks prohibited indicator
JM 276                     Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);
277                     Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));
278                     WicketUtils.setHtmlTooltip(lbl,  getString("gb.forksProhibitedWarning"));
279                     wc.add(lbl);
280                     add(wc);
281                 } else {
282                     // can not fork, no need for forks prohibited indicator
283                     add(new Label("forksProhibitedIndicator").setVisible(false));
284                 }
285                 
286                 if (hasFork && !fork.equals(model.name)) {
287                     // user has fork, view my fork link
288                     String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)).toString();
289                     add(new ExternalLink("myForkLink", url));
290                 } else {
291                     // no fork, hide view my fork link
292                     add(new ExternalLink("myForkLink", "").setVisible(false));
293                 }
294             } else if (canFork) {
295                 // can fork and we do not have one
296                 add(new Label("forksProhibitedIndicator").setVisible(false));
297                 add(new ExternalLink("myForkLink", "").setVisible(false));
1f52c8 298                 String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();
JM 299                 add(new ExternalLink("forkLink", url));
1e1b85 300             }
JM 301         }
302         
1f5915 303         super.setupPage(repositoryName, pageName);
8c9a20 304     }
JM 305
306     protected void addSyndicationDiscoveryLink() {
307         add(WicketUtils.syndicationDiscoveryLink(SyndicationServlet.getTitle(repositoryName,
308                 objectId), SyndicationServlet.asLink(getRequest()
309                 .getRelativePathPrefixToContextRoot(), repositoryName, objectId, 0)));
5fe7df 310     }
JM 311
312     protected Repository getRepository() {
313         if (r == null) {
f5d0ad 314             Repository r = GitBlit.self().getRepository(repositoryName);
7ba0ec 315             if (r == null) {
6caa93 316                 error(getString("gb.canNotLoadRepository") + " " + repositoryName, true);
7ba0ec 317                 return null;
JM 318             }
319             this.r = r;
5fe7df 320         }
JM 321         return r;
322     }
bc9d4a 323
f97bf0 324     protected RepositoryModel getRepositoryModel() {
JM 325         if (m == null) {
2a7306 326             RepositoryModel model = GitBlit.self().getRepositoryModel(
JM 327                     GitBlitWebSession.get().getUser(), repositoryName);
dfb889 328             if (model == null) {
7b0f30 329                 if (GitBlit.self().hasRepository(repositoryName, true)) {
d97e52 330                     // has repository, but unauthorized
JM 331                     authenticationError(getString("gb.unauthorizedAccessForRepository") + " " + repositoryName);
332                 } else {
333                     // does not have repository
334                     error(getString("gb.canNotLoadRepository") + " " + repositoryName, true);
335                 }
00afd7 336                 return null;
dfb889 337             }
JM 338             m = model;
f97bf0 339         }
JM 340         return m;
bc9d4a 341     }
dfb889 342
bc9d4a 343     protected RevCommit getCommit() {
JM 344         RevCommit commit = JGitUtils.getCommit(r, objectId);
345         if (commit == null) {
6caa93 346             error(MessageFormat.format(getString("gb.failedToFindCommit"),
2a7306 347                     objectId, repositoryName, getPageName()), true);
bc9d4a 348         }
eb870f 349         getSubmodules(commit);
bc9d4a 350         return commit;
f97bf0 351     }
eb870f 352     
JM 353     private Map<String, SubmoduleModel> getSubmodules(RevCommit commit) {    
354         if (submodules == null) {
355             submodules = new HashMap<String, SubmoduleModel>();
356             for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {
357                 submodules.put(model.path, model);
358             }
359         }
360         return submodules;
361     }
362     
363     protected SubmoduleModel getSubmodule(String path) {
364         SubmoduleModel model = submodules.get(path);
365         if (model == null) {
366             // undefined submodule?!
367             model = new SubmoduleModel(path.substring(path.lastIndexOf('/') + 1), path, path);
368             model.hasSubmodule = false;
369             model.gitblitPath = model.name;
370             return model;
371         } else {
372             // extract the repository name from the clone url
373             List<String> patterns = GitBlit.getStrings(Keys.git.submoduleUrlPatterns);
374             String submoduleName = StringUtils.extractRepositoryPath(model.url, patterns.toArray(new String[0]));
375             
376             // determine the current path for constructing paths relative
377             // to the current repository
378             String currentPath = "";
379             if (repositoryName.indexOf('/') > -1) {
380                 currentPath = repositoryName.substring(0, repositoryName.lastIndexOf('/') + 1);
381             }
382
383             // try to locate the submodule repository
384             // prefer bare to non-bare names
385             List<String> candidates = new ArrayList<String>();
386
387             // relative
388             candidates.add(currentPath + StringUtils.stripDotGit(submoduleName));
389             candidates.add(candidates.get(candidates.size() - 1) + ".git");
390
391             // relative, no subfolder
392             if (submoduleName.lastIndexOf('/') > -1) {
393                 String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
394                 candidates.add(currentPath + StringUtils.stripDotGit(name));
395                 candidates.add(currentPath + candidates.get(candidates.size() - 1) + ".git");
396             }
397
398             // absolute
399             candidates.add(StringUtils.stripDotGit(submoduleName));
400             candidates.add(candidates.get(candidates.size() - 1) + ".git");
401
402             // absolute, no subfolder
403             if (submoduleName.lastIndexOf('/') > -1) {
404                 String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);
405                 candidates.add(StringUtils.stripDotGit(name));
406                 candidates.add(candidates.get(candidates.size() - 1) + ".git");
407             }
408
409             // create a unique, ordered set of candidate paths
410             Set<String> paths = new LinkedHashSet<String>(candidates);
411             for (String candidate : paths) {
412                 if (GitBlit.self().hasRepository(candidate)) {
413                     model.hasSubmodule = true;
414                     model.gitblitPath = candidate;
415                     return model;
416                 }
417             }
418             
419             // we do not have a copy of the submodule, but we need a path
420             model.gitblitPath = candidates.get(0);
421             return model;
422         }        
423     }
5fe7df 424
008322 425     protected String getShortObjectId(String objectId) {
e627cf 426         return objectId.substring(0, GitBlit.getInteger(Keys.web.shortCommitIdLength, 6));
008322 427     }
JM 428
5fe7df 429     protected void addRefs(Repository r, RevCommit c) {
1e1b85 430         add(new RefsPanel("refsPanel", repositoryName, c, JGitUtils.getAllRefs(r, getRepositoryModel().showRemoteBranches)));
5fe7df 431     }
JM 432
433     protected void addFullText(String wicketId, String text, boolean substituteRegex) {
bca8c5 434         String html = StringUtils.escapeForHtml(text, false);
5fe7df 435         if (substituteRegex) {
bca8c5 436             html = GitBlit.self().processCommitMessage(repositoryName, html);
f339f5 437         } else {
227736 438             html = StringUtils.breakLinesForHtml(html);
f339f5 439         }
JM 440         add(new Label(wicketId, html).setEscapeModelStrings(false));
5fe7df 441     }
1e47ab 442
cebf45 443     protected abstract String getPageName();
5fe7df 444
2a7306 445     protected Component createPersonPanel(String wicketId, PersonIdent identity,
33d8d8 446             Constants.SearchType searchType) {
e11f48 447         String name = identity == null ? "" : identity.getName();
JM 448         String address = identity == null ? "" : identity.getEmailAddress();
ac7e9a 449         name = StringUtils.removeNewlines(name);
JM 450         address = StringUtils.removeNewlines(address);
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     }
428b22 600 }