1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.templatingkit.search;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.MgnlNodeType;
38 import info.magnolia.cms.core.search.Query;
39 import info.magnolia.cms.core.search.QueryResult;
40 import info.magnolia.context.MgnlContext;
41 import info.magnolia.jcr.wrapper.I18nNodeWrapper;
42 import info.magnolia.module.templatingkit.functions.STKTemplatingFunctions;
43 import info.magnolia.module.templatingkit.templates.AbstractSTKTemplateModel;
44 import info.magnolia.rendering.model.RenderingModel;
45 import info.magnolia.rendering.template.TemplateDefinition;
46 import info.magnolia.repository.RepositoryConstants;
47 import info.magnolia.templating.functions.TemplatingFunctions;
48
49 import java.text.MessageFormat;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.List;
53
54 import javax.inject.Inject;
55 import javax.jcr.Node;
56
57 import org.apache.commons.lang.StringUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67 public class SearchResultModel extends AbstractSTKTemplateModel <TemplateDefinition> {
68
69 private static final String SEARCH_QUERY_PATTERN = "select * from nt:base where jcr:path like ''{0}/%'' and contains(*, ''{1}'') order by jcr:path";
70
71
72 protected String repository = RepositoryConstants.WEBSITE;
73 protected List<Content> result = new ArrayList<Content>();
74 protected int count;
75 protected int maxResultsPerPage;
76 protected int currentPage = 1;
77 protected int numPages = 0;
78
79 private static final Logger log = LoggerFactory.getLogger(SearchResultModel.class);
80
81 @Inject
82 public SearchResultModel(Node content, TemplateDefinition definition, RenderingModel<?> parent, STKTemplatingFunctions stkFunctions, TemplatingFunctions templatingFunctions) {
83 super(content, definition, parent, stkFunctions, templatingFunctions);
84 }
85
86 protected int getMaxResultsPerPage() {
87
88 maxResultsPerPage = Integer.MAX_VALUE;
89 try {
90 if (content.hasProperty("maxResultsPerPage")) {
91 maxResultsPerPage = Integer.parseInt(content.getProperty("maxResultsPerPage").getString());
92 }
93 } catch (Exception e) {
94
95 }
96 return maxResultsPerPage;
97 }
98
99 @Override
100 public String execute() {
101
102 Query q = null;
103 String queryString = generateSimpleQuery(this.getQueryStr());
104 if (StringUtils.isBlank(queryString)){
105 return null;
106 }
107 try {
108 maxResultsPerPage = getMaxResultsPerPage();
109 q = MgnlContext.getQueryManager(repository).createQuery(queryString, "sql");
110
111 QueryResult queryResult = q.execute();
112
113 count = pagedQuery(queryResult.getContent(MgnlNodeType.NT_PAGE), getOffset(), maxResultsPerPage);
114
115 numPages = count/maxResultsPerPage;
116 if((count % maxResultsPerPage) > 0 ) {
117 numPages++;
118 }
119
120 } catch (Exception e) {
121 log.error(MessageFormat.format("{0} caught while parsing query for search term [{1}] - query is [{2}]: {3}", e.getClass().getName(), q, queryString, e.getMessage()), e);
122 }
123
124 return "";
125
126 }
127
128 protected int getOffset() {
129 return ((getCurrentPage() -1) * maxResultsPerPage);
130
131 }
132
133 protected int pagedQuery(Collection<Content> queryResult, int offset, int limit) throws Exception {
134 int total = queryResult.size();
135 int newLimit = limit;
136 if(total > offset) {
137 if(total < offset + limit) {
138 newLimit = total - offset;
139 }
140
141 result = ((List<Content>)queryResult).subList(offset, offset + newLimit);
142 }
143
144 return total;
145 }
146
147 protected String generateSimpleQuery(String input) {
148 if(StringUtils.isBlank(input)){
149 return null;
150 }
151
152
153 String searchString = input.replace("'", "''");
154 return MessageFormat.format(SEARCH_QUERY_PATTERN, new String[]{this.getPath(), searchString});
155 }
156
157 public String getPath() {
158 try {
159 return stkFunctions.siteRoot(content).getPath();
160
161 } catch (Exception e) {
162 log.warn("no site");
163 }
164 return "";
165 }
166
167
168
169
170 public List<Node> getQueryResult(){
171 List<Node> res = new ArrayList<Node>();
172 if(result!=null) {
173 for(Content c:result){
174 res.add(new I18nNodeWrapper(c.getJCRNode()));
175 }
176 }
177 return res;
178 }
179
180 public Collection<SearchResultItem> getResult() {
181 final Collection<SearchResultItem> searchResults = new ArrayList<SearchResultItem>();
182 for (Node content : this.getQueryResult()) {
183 searchResults.add(new SearchResultItem(content, this.getQueryStr(), templatingFunctions));
184 }
185 return searchResults;
186 }
187
188 public String getQueryStr() {
189 return MgnlContext.getParameter("queryStr");
190 }
191
192
193 public int getCount(){
194 return this.count;
195 }
196
197 public int getCurrentPage() {
198
199 if(MgnlContext.getParameter("currentPage") != null) {
200 currentPage = Integer.parseInt(MgnlContext.getParameter("currentPage"));
201 }
202
203 return currentPage;
204 }
205
206 public int getNumPages() {
207 return numPages;
208 }
209
210
211
212
213
214
215
216 public String getPageLink(int i) {
217 String link = "";
218 try {
219 link = stkFunctions.searchPageLink(content);
220 String current = "&currentPage=";
221 link = link + "?queryStr=" + getQueryStr() + current + i;
222 } catch (Exception e) {
223 log.error("could not find search result page");
224 }
225 return link;
226 }
227
228
229
230
231
232 public int getBeginIndex() {
233 if (currentPage - 2 <= 1) {
234 return 1;
235 } else {
236 return currentPage - 2;
237 }
238 }
239
240 public int getEndIndex() {
241 if (currentPage + 2 >= numPages) {
242 return numPages;
243 } else {
244 return currentPage + 2;
245 }
246 }
247
248 public String getPosition() {
249 try {
250 if(content.hasProperty("pager")) {
251 return content.getProperty("pager").getString();
252 }
253 } catch (Exception e) {
254 log.debug("no pagination position found");
255 }
256 return "";
257
258 }
259
260
261 }