commit | author | age
|
4c13bf
|
1 |
/*
|
JM |
2 |
* Copyright 2012 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 |
|
d04009
|
18 |
import java.text.MessageFormat;
|
4c13bf
|
19 |
import java.util.ArrayList;
|
JM |
20 |
import java.util.List;
|
|
21 |
|
31a897
|
22 |
import org.apache.wicket.Component;
|
4c13bf
|
23 |
import org.apache.wicket.PageParameters;
|
JM |
24 |
import org.apache.wicket.markup.html.basic.Label;
|
3d0494
|
25 |
import org.apache.wicket.markup.html.form.ListMultipleChoice;
|
4c13bf
|
26 |
import org.apache.wicket.markup.html.form.TextField;
|
b4d958
|
27 |
import org.apache.wicket.markup.html.form.CheckBox;
|
31a897
|
28 |
import org.apache.wicket.markup.html.panel.Fragment;
|
4c13bf
|
29 |
import org.apache.wicket.markup.repeater.Item;
|
JM |
30 |
import org.apache.wicket.markup.repeater.data.DataView;
|
|
31 |
import org.apache.wicket.markup.repeater.data.ListDataProvider;
|
|
32 |
import org.apache.wicket.model.Model;
|
3f0677
|
33 |
import org.eclipse.jgit.lib.Constants;
|
4c13bf
|
34 |
|
3d0494
|
35 |
import com.gitblit.Constants.SearchType;
|
d04009
|
36 |
import com.gitblit.Keys;
|
672296
|
37 |
import com.gitblit.models.RepositoryModel;
|
4c13bf
|
38 |
import com.gitblit.models.SearchResult;
|
672296
|
39 |
import com.gitblit.models.UserModel;
|
7d97c6
|
40 |
import com.gitblit.utils.ArrayUtils;
|
3f0677
|
41 |
import com.gitblit.utils.StringUtils;
|
672296
|
42 |
import com.gitblit.wicket.GitBlitWebSession;
|
ed295f
|
43 |
import com.gitblit.wicket.SessionlessForm;
|
672296
|
44 |
import com.gitblit.wicket.StringChoiceRenderer;
|
4c13bf
|
45 |
import com.gitblit.wicket.WicketUtils;
|
JM |
46 |
import com.gitblit.wicket.panels.LinkPanel;
|
d04009
|
47 |
import com.gitblit.wicket.panels.PagerPanel;
|
4c13bf
|
48 |
|
4e1930
|
49 |
public class LuceneSearchPage extends RootPage {
|
4c13bf
|
50 |
|
4e1930
|
51 |
public LuceneSearchPage() {
|
4c13bf
|
52 |
super();
|
JM |
53 |
setup(null);
|
|
54 |
}
|
|
55 |
|
4e1930
|
56 |
public LuceneSearchPage(PageParameters params) {
|
4c13bf
|
57 |
super(params);
|
JM |
58 |
setup(params);
|
|
59 |
}
|
|
60 |
|
|
61 |
private void setup(PageParameters params) {
|
|
62 |
setupPage("", "");
|
699e71
|
63 |
|
7d97c6
|
64 |
// default values
|
699e71
|
65 |
ArrayList<String> repositories = new ArrayList<String>();
|
7d97c6
|
66 |
String query = "";
|
d04009
|
67 |
int page = 1;
|
99d0d4
|
68 |
int pageSize = app().settings().getInteger(Keys.web.itemsPerPage, 50);
|
3d0494
|
69 |
|
b4d958
|
70 |
// display user-accessible selections
|
VF |
71 |
UserModel user = GitBlitWebSession.get().getUser();
|
|
72 |
List<String> availableRepositories = new ArrayList<String>();
|
|
73 |
for (RepositoryModel model : app().repositories().getRepositoryModels(user)) {
|
|
74 |
if (model.hasCommits && !ArrayUtils.isEmpty(model.indexedBranches)) {
|
|
75 |
availableRepositories.add(model.name);
|
|
76 |
}
|
|
77 |
}
|
|
78 |
|
3d0494
|
79 |
if (params != null) {
|
7d97c6
|
80 |
String repository = WicketUtils.getRepositoryName(params);
|
JM |
81 |
if (!StringUtils.isEmpty(repository)) {
|
|
82 |
repositories.add(repository);
|
|
83 |
}
|
d04009
|
84 |
|
31a897
|
85 |
page = WicketUtils.getPage(params);
|
699e71
|
86 |
|
7d97c6
|
87 |
if (params.containsKey("repositories")) {
|
JM |
88 |
String value = params.getString("repositories", "");
|
699e71
|
89 |
List<String> list = StringUtils.getStringsFromValue(value);
|
7d97c6
|
90 |
repositories.addAll(list);
|
b4d958
|
91 |
}
|
VF |
92 |
|
|
93 |
if (params.containsKey("allrepos")) {
|
|
94 |
repositories.addAll(availableRepositories);
|
7d97c6
|
95 |
}
|
JM |
96 |
|
|
97 |
if (params.containsKey("query")) {
|
699e71
|
98 |
query = params.getString("query", "");
|
7d97c6
|
99 |
} else {
|
JM |
100 |
String value = WicketUtils.getSearchString(params);
|
|
101 |
String type = WicketUtils.getSearchType(params);
|
|
102 |
com.gitblit.Constants.SearchType searchType = com.gitblit.Constants.SearchType.forName(type);
|
|
103 |
if (!StringUtils.isEmpty(value)) {
|
|
104 |
if (searchType == SearchType.COMMIT) {
|
699e71
|
105 |
query = "type:" + searchType.name().toLowerCase() + " AND \"" + value + "\"";
|
7d97c6
|
106 |
} else {
|
JM |
107 |
query = searchType.name().toLowerCase() + ":\"" + value + "\"";
|
|
108 |
}
|
|
109 |
}
|
|
110 |
}
|
3d0494
|
111 |
}
|
699e71
|
112 |
|
99d0d4
|
113 |
boolean luceneEnabled = app().settings().getBoolean(Keys.web.allowLuceneIndexing, true);
|
7db092
|
114 |
if (luceneEnabled) {
|
JM |
115 |
if (availableRepositories.size() == 0) {
|
|
116 |
info(getString("gb.noIndexedRepositoriesWarning"));
|
|
117 |
}
|
|
118 |
} else {
|
|
119 |
error(getString("gb.luceneDisabled"));
|
40ca5c
|
120 |
}
|
JM |
121 |
|
|
122 |
// enforce user-accessible repository selections
|
|
123 |
ArrayList<String> searchRepositories = new ArrayList<String>();
|
|
124 |
for (String selectedRepository : repositories) {
|
|
125 |
if (availableRepositories.contains(selectedRepository)) {
|
|
126 |
searchRepositories.add(selectedRepository);
|
|
127 |
}
|
|
128 |
}
|
699e71
|
129 |
|
7d97c6
|
130 |
// search form
|
JM |
131 |
final Model<String> queryModel = new Model<String>(query);
|
40ca5c
|
132 |
final Model<ArrayList<String>> repositoriesModel = new Model<ArrayList<String>>(searchRepositories);
|
b4d958
|
133 |
final Model<Boolean> allreposModel = new Model<Boolean>(params != null && params.containsKey("allrepos"));
|
ed295f
|
134 |
SessionlessForm<Void> form = new SessionlessForm<Void>("searchForm", getClass()) {
|
699e71
|
135 |
|
7d97c6
|
136 |
private static final long serialVersionUID = 1L;
|
JM |
137 |
|
|
138 |
@Override
|
|
139 |
public void onSubmit() {
|
|
140 |
String q = queryModel.getObject();
|
|
141 |
if (StringUtils.isEmpty(q)) {
|
40ca5c
|
142 |
error(getString("gb.undefinedQueryWarning"));
|
7d97c6
|
143 |
return;
|
699e71
|
144 |
}
|
b4d958
|
145 |
if (repositoriesModel.getObject().size() == 0 && !allreposModel.getObject()) {
|
40ca5c
|
146 |
error(getString("gb.noSelectedRepositoriesWarning"));
|
7d97c6
|
147 |
return;
|
JM |
148 |
}
|
|
149 |
PageParameters params = new PageParameters();
|
|
150 |
params.put("repositories", StringUtils.flattenStrings(repositoriesModel.getObject()));
|
|
151 |
params.put("query", queryModel.getObject());
|
b4d958
|
152 |
params.put("allrepos", allreposModel.getObject());
|
1b84d3
|
153 |
LuceneSearchPage page = new LuceneSearchPage(params);
|
JM |
154 |
setResponsePage(page);
|
7d97c6
|
155 |
}
|
JM |
156 |
};
|
699e71
|
157 |
|
JM |
158 |
ListMultipleChoice<String> selections = new ListMultipleChoice<String>("repositories",
|
672296
|
159 |
repositoriesModel, availableRepositories, new StringChoiceRenderer());
|
4e1930
|
160 |
selections.setMaxRows(8);
|
7db092
|
161 |
form.add(selections.setEnabled(luceneEnabled));
|
JM |
162 |
form.add(new TextField<String>("query", queryModel).setEnabled(luceneEnabled));
|
b4d958
|
163 |
form.add(new CheckBox("allrepos", allreposModel));
|
7db092
|
164 |
add(form.setEnabled(luceneEnabled));
|
699e71
|
165 |
|
7d97c6
|
166 |
// execute search
|
4c13bf
|
167 |
final List<SearchResult> results = new ArrayList<SearchResult>();
|
40ca5c
|
168 |
if (!ArrayUtils.isEmpty(searchRepositories) && !StringUtils.isEmpty(query)) {
|
99d0d4
|
169 |
results.addAll(app().repositories().search(query, page, pageSize, searchRepositories));
|
d04009
|
170 |
}
|
699e71
|
171 |
|
d04009
|
172 |
// results header
|
JM |
173 |
if (results.size() == 0) {
|
22a8a6
|
174 |
if (!ArrayUtils.isEmpty(searchRepositories) && !StringUtils.isEmpty(query)) {
|
JM |
175 |
add(new Label("resultsHeader", query).setRenderBodyOnly(true));
|
6caa93
|
176 |
add(new Label("resultsCount", getString("gb.noHits")).setRenderBodyOnly(true));
|
22a8a6
|
177 |
} else {
|
JM |
178 |
add(new Label("resultsHeader").setVisible(false));
|
|
179 |
add(new Label("resultsCount").setVisible(false));
|
|
180 |
}
|
d04009
|
181 |
} else {
|
JM |
182 |
add(new Label("resultsHeader", query).setRenderBodyOnly(true));
|
6caa93
|
183 |
add(new Label("resultsCount", MessageFormat.format(getString("gb.queryResults"),
|
d04009
|
184 |
results.get(0).hitId, results.get(results.size() - 1).hitId, results.get(0).totalHits)).
|
JM |
185 |
setRenderBodyOnly(true));
|
d896e6
|
186 |
}
|
699e71
|
187 |
|
7d97c6
|
188 |
// search results view
|
4c13bf
|
189 |
ListDataProvider<SearchResult> resultsDp = new ListDataProvider<SearchResult>(results);
|
JM |
190 |
final DataView<SearchResult> resultsView = new DataView<SearchResult>("searchResults", resultsDp) {
|
|
191 |
private static final long serialVersionUID = 1L;
|
699e71
|
192 |
@Override
|
4c13bf
|
193 |
public void populateItem(final Item<SearchResult> item) {
|
31a897
|
194 |
final SearchResult sr = item.getModelObject();
|
4c13bf
|
195 |
switch(sr.type) {
|
JM |
196 |
case commit: {
|
|
197 |
Label icon = WicketUtils.newIcon("type", "icon-refresh");
|
|
198 |
WicketUtils.setHtmlTooltip(icon, "commit");
|
|
199 |
item.add(icon);
|
98b4ed
|
200 |
item.add(new LinkPanel("summary", null, sr.summary, CommitPage.class, WicketUtils.newObjectParameter(sr.repository, sr.commitId)));
|
31a897
|
201 |
// show tags
|
JM |
202 |
Fragment fragment = new Fragment("tags", "tagsPanel", LuceneSearchPage.this);
|
|
203 |
List<String> tags = sr.tags;
|
|
204 |
if (tags == null) {
|
|
205 |
tags = new ArrayList<String>();
|
|
206 |
}
|
|
207 |
ListDataProvider<String> tagsDp = new ListDataProvider<String>(tags);
|
|
208 |
final DataView<String> tagsView = new DataView<String>("tag", tagsDp) {
|
|
209 |
private static final long serialVersionUID = 1L;
|
699e71
|
210 |
@Override
|
31a897
|
211 |
public void populateItem(final Item<String> item) {
|
JM |
212 |
String tag = item.getModelObject();
|
|
213 |
Component c = new LinkPanel("tagLink", null, tag, TagPage.class,
|
|
214 |
WicketUtils.newObjectParameter(sr.repository, Constants.R_TAGS + tag));
|
699e71
|
215 |
WicketUtils.setCssClass(c, "tagRef");
|
31a897
|
216 |
item.add(c);
|
JM |
217 |
}
|
|
218 |
};
|
|
219 |
fragment.add(tagsView);
|
|
220 |
item.add(fragment);
|
4c13bf
|
221 |
break;
|
JM |
222 |
}
|
|
223 |
case blob: {
|
|
224 |
Label icon = WicketUtils.newIcon("type", "icon-file");
|
|
225 |
WicketUtils.setHtmlTooltip(icon, "blob");
|
|
226 |
item.add(icon);
|
98b4ed
|
227 |
item.add(new LinkPanel("summary", null, sr.path, BlobPage.class, WicketUtils.newPathParameter(sr.repository, sr.branch, sr.path)));
|
31a897
|
228 |
item.add(new Label("tags").setVisible(false));
|
4c13bf
|
229 |
break;
|
JM |
230 |
}
|
|
231 |
}
|
98b4ed
|
232 |
item.add(new Label("fragment", sr.fragment).setEscapeModelStrings(false).setVisible(!StringUtils.isEmpty(sr.fragment)));
|
3f0677
|
233 |
item.add(new LinkPanel("repository", null, sr.repository, SummaryPage.class, WicketUtils.newRepositoryParameter(sr.repository)));
|
d04009
|
234 |
if (StringUtils.isEmpty(sr.branch)) {
|
JM |
235 |
item.add(new Label("branch", "null"));
|
|
236 |
} else {
|
|
237 |
item.add(new LinkPanel("branch", "branch", StringUtils.getRelativePath(Constants.R_HEADS, sr.branch), LogPage.class, WicketUtils.newObjectParameter(sr.repository, sr.branch)));
|
|
238 |
}
|
4c13bf
|
239 |
item.add(new Label("author", sr.author));
|
9adf62
|
240 |
item.add(WicketUtils.createDatestampLabel("date", sr.date, getTimeZone(), getTimeUtils()));
|
4c13bf
|
241 |
}
|
JM |
242 |
};
|
7d97c6
|
243 |
add(resultsView.setVisible(results.size() > 0));
|
699e71
|
244 |
|
d04009
|
245 |
PageParameters pagerParams = new PageParameters();
|
JM |
246 |
pagerParams.put("repositories", StringUtils.flattenStrings(repositoriesModel.getObject()));
|
|
247 |
pagerParams.put("query", queryModel.getObject());
|
699e71
|
248 |
|
697def
|
249 |
boolean showPager = false;
|
d04009
|
250 |
int totalPages = 0;
|
JM |
251 |
if (results.size() > 0) {
|
|
252 |
totalPages = (results.get(0).totalHits / pageSize) + (results.get(0).totalHits % pageSize > 0 ? 1 : 0);
|
697def
|
253 |
showPager = results.get(0).totalHits > pageSize;
|
d04009
|
254 |
}
|
699e71
|
255 |
|
697def
|
256 |
add(new PagerPanel("topPager", page, totalPages, LuceneSearchPage.class, pagerParams).setVisible(showPager));
|
JM |
257 |
add(new PagerPanel("bottomPager", page, totalPages, LuceneSearchPage.class, pagerParams).setVisible(showPager));
|
d04009
|
258 |
}
|
4c13bf
|
259 |
}
|