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 public String getPageLink(int i) {
209 String link = "";
210 try {
211 link = stkFunctions.searchPageLink(content);
212 String current = "&currentPage=";
213 link = link + "?queryStr=" + getQueryStr() + current + i;
214 } catch (Exception e) {
215 log.error("could not find search result page");
216 }
217 return link;
218 }
219
220 public int getBeginIndex() {
221 if (currentPage - 2 <= 1) {
222 return 1;
223 } else {
224 return currentPage - 2;
225 }
226 }
227
228 public int getEndIndex() {
229 if (currentPage + 2 >= numPages) {
230 return numPages;
231 } else {
232 return currentPage + 2;
233 }
234 }
235
236 public String getPosition() {
237 try {
238 if(content.hasProperty("pager")) {
239 return content.getProperty("pager").getString();
240 }
241 } catch (Exception e) {
242 log.debug("no pagination position found");
243 }
244 return "";
245
246 }
247
248
249 }