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.search.Query;
38 import info.magnolia.cms.core.search.QueryResult;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.jcr.util.NodeTypes;
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 public class SearchResultModel extends AbstractSTKTemplateModel <TemplateDefinition> {
66
67 private static final String SEARCH_QUERY_PATTERN = "select * from nt:base where jcr:path like ''{0}/%'' and contains(*, ''{1}'') order by jcr:path";
68
69
70 protected String repository = RepositoryConstants.WEBSITE;
71 protected List<Content> result = new ArrayList<Content>();
72 protected int count;
73 protected int maxResultsPerPage;
74 protected int currentPage = 1;
75 protected int numPages = 0;
76
77 private static final Logger log = LoggerFactory.getLogger(SearchResultModel.class);
78
79 @Inject
80 public SearchResultModel(Node content, TemplateDefinition definition, RenderingModel<?> parent, STKTemplatingFunctions stkFunctions, TemplatingFunctions templatingFunctions) {
81 super(content, definition, parent, stkFunctions, templatingFunctions);
82 }
83
84 protected int getMaxResultsPerPage() {
85
86 maxResultsPerPage = Integer.MAX_VALUE;
87 try {
88 if (content.hasProperty("maxResultsPerPage")) {
89 maxResultsPerPage = Integer.parseInt(content.getProperty("maxResultsPerPage").getString());
90 }
91 } catch (Exception e) {
92
93 }
94 return maxResultsPerPage;
95 }
96
97 @Override
98 public String execute() {
99
100 Query q = null;
101 String queryString = generateSimpleQuery(this.getQueryStr());
102 if (StringUtils.isBlank(queryString)){
103 return null;
104 }
105 try {
106 maxResultsPerPage = getMaxResultsPerPage();
107 q = MgnlContext.getQueryManager(repository).createQuery(queryString, "sql");
108
109 QueryResult queryResult = q.execute();
110
111 count = pagedQuery(queryResult.getContent(NodeTypes.Page.NAME), getOffset(), maxResultsPerPage);
112
113 numPages = count/maxResultsPerPage;
114 if((count % maxResultsPerPage) > 0 ) {
115 numPages++;
116 }
117
118 } catch (Exception e) {
119 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);
120 }
121
122 return "";
123
124 }
125
126 protected int getOffset() {
127 return ((getCurrentPage() -1) * maxResultsPerPage);
128
129 }
130
131 protected int pagedQuery(Collection<Content> queryResult, int offset, int limit) throws Exception {
132 int total = queryResult.size();
133 int newLimit = limit;
134 if(total > offset) {
135 if(total < offset + limit) {
136 newLimit = total - offset;
137 }
138
139 result = ((List<Content>)queryResult).subList(offset, offset + newLimit);
140 }
141
142 return total;
143 }
144
145 protected String generateSimpleQuery(String input) {
146 if(StringUtils.isBlank(input)){
147 return null;
148 }
149
150
151 String searchString = input.replace("'", "''");
152 return MessageFormat.format(SEARCH_QUERY_PATTERN, new String[]{this.getPath(), searchString});
153 }
154
155 public String getPath() {
156 try {
157 return stkFunctions.siteRoot(content).getPath();
158
159 } catch (Exception e) {
160 log.warn("no site");
161 }
162 return "";
163 }
164
165
166
167
168 public List<Node> getQueryResult(){
169 List<Node> res = new ArrayList<Node>();
170 if(result!=null) {
171 for(Content c:result){
172 res.add(new I18nNodeWrapper(c.getJCRNode()));
173 }
174 }
175 return res;
176 }
177
178 public Collection<SearchResultItem> getResult() {
179 final Collection<SearchResultItem> searchResults = new ArrayList<SearchResultItem>();
180 for (Node content : this.getQueryResult()) {
181 searchResults.add(new SearchResultItem(content, this.getQueryStr(), templatingFunctions));
182 }
183 return searchResults;
184 }
185
186 public String getQueryStr() {
187 return MgnlContext.getParameter("queryStr");
188 }
189
190
191 public int getCount(){
192 return this.count;
193 }
194
195 public int getCurrentPage() {
196
197 if(MgnlContext.getParameter("currentPage") != null) {
198 currentPage = Integer.parseInt(MgnlContext.getParameter("currentPage"));
199 }
200
201 return currentPage;
202 }
203
204 public int getNumPages() {
205 return numPages;
206 }
207
208
209
210
211
212
213
214 public String getPageLink(int i) {
215 String link = "";
216 try {
217 link = stkFunctions.searchPageLink(content);
218 String current = "&currentPage=";
219 link = link + "?queryStr=" + getQueryStr() + current + i;
220 } catch (Exception e) {
221 log.error("could not find search result page");
222 }
223 return link;
224 }
225
226
227
228
229
230 public int getBeginIndex() {
231 if (currentPage - 2 <= 1) {
232 return 1;
233 } else {
234 return currentPage - 2;
235 }
236 }
237
238 public int getEndIndex() {
239 if (currentPage + 2 >= numPages) {
240 return numPages;
241 } else {
242 return currentPage + 2;
243 }
244 }
245
246 public String getPosition() {
247 try {
248 if(content.hasProperty("pager")) {
249 return content.getProperty("pager").getString();
250 }
251 } catch (Exception e) {
252 log.debug("no pagination position found");
253 }
254 return "";
255
256 }
257
258
259 }