001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.dao.search;
016    
017    import com.liferay.portal.kernel.util.DeterminateKeyGenerator;
018    import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.OrderByComparator;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.util.PropsKeys;
023    import com.liferay.portal.kernel.util.PropsUtil;
024    import com.liferay.portal.kernel.util.SearchContainerReference;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.TextFormatter;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.kernel.util.WebKeys;
030    import com.liferay.portal.util.PortalUtil;
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    import java.util.Map;
035    
036    import javax.portlet.PortletRequest;
037    import javax.portlet.PortletURL;
038    
039    import javax.servlet.http.HttpServletRequest;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     */
044    public class SearchContainer<R> {
045    
046            public static final int DEFAULT_CUR = 1;
047    
048            public static final String DEFAULT_CUR_PARAM = "cur";
049    
050            /**
051             * @deprecated As of 6.2.0, replaced by {@link #DEFAULT_CUR}.
052             */
053            public static final int DEFAULT_CUR_VALUE = DEFAULT_CUR;
054    
055            public static final int DEFAULT_DELTA = GetterUtil.getInteger(
056                    PropsUtil.get(PropsKeys.SEARCH_CONTAINER_PAGE_DEFAULT_DELTA));
057    
058            public static final boolean DEFAULT_DELTA_CONFIGURABLE = true;
059    
060            public static final String DEFAULT_DELTA_PARAM = "delta";
061    
062            public static final String DEFAULT_DEPRECATED_TOTAL_VAR = "deprecatedTotal";
063    
064            /**
065             * @deprecated As of 6.2.0, see LPS-6312
066             */
067            public static final int DEFAULT_MAX_PAGES = 25;
068    
069            public static final String DEFAULT_ORDER_BY_COL_PARAM = "orderByCol";
070    
071            public static final String DEFAULT_ORDER_BY_TYPE_PARAM = "orderByType";
072    
073            public static final String DEFAULT_RESULTS_VAR = "results";
074    
075            public static final String DEFAULT_TOTAL_VAR = "total";
076    
077            public static final String DEFAULT_VAR = "searchContainer";
078    
079            public static final int MAX_DELTA = 200;
080    
081            public SearchContainer() {
082            }
083    
084            public SearchContainer(
085                    PortletRequest portletRequest, DisplayTerms displayTerms,
086                    DisplayTerms searchTerms, String curParam, int cur, int delta,
087                    PortletURL iteratorURL, List<String> headerNames,
088                    String emptyResultsMessage) {
089    
090                    _portletRequest = portletRequest;
091                    _displayTerms = displayTerms;
092                    _searchTerms = searchTerms;
093    
094                    _curParam = curParam;
095    
096                    boolean resetCur = ParamUtil.getBoolean(portletRequest, "resetCur");
097    
098                    if (resetCur) {
099                            _cur = DEFAULT_CUR;
100                    }
101                    else {
102                            if (cur < 1) {
103                                    _cur = ParamUtil.getInteger(
104                                            portletRequest, _curParam, DEFAULT_CUR);
105    
106                                    if (_cur < 1) {
107                                            _cur = DEFAULT_CUR;
108                                    }
109                            }
110                            else {
111                                    _cur = cur;
112                            }
113                    }
114    
115                    if (!_curParam.equals(DEFAULT_CUR_PARAM)) {
116                            _deltaParam =
117                                    DEFAULT_DELTA_PARAM +
118                                            StringUtil.replace(
119                                                    _curParam, DEFAULT_CUR_PARAM, StringPool.BLANK);
120                    }
121    
122                    setDelta(ParamUtil.getInteger(portletRequest, _deltaParam, delta));
123    
124                    _iteratorURL = iteratorURL;
125    
126                    _iteratorURL.setParameter(_curParam, String.valueOf(_cur));
127                    _iteratorURL.setParameter(_deltaParam, String.valueOf(_delta));
128                    _iteratorURL.setParameter(
129                            DisplayTerms.KEYWORDS,
130                            ParamUtil.getString(portletRequest, DisplayTerms.KEYWORDS));
131                    _iteratorURL.setParameter(
132                            DisplayTerms.ADVANCED_SEARCH,
133                            String.valueOf(
134                                    ParamUtil.getBoolean(
135                                            portletRequest, DisplayTerms.ADVANCED_SEARCH)));
136                    _iteratorURL.setParameter(
137                            DisplayTerms.AND_OPERATOR,
138                            String.valueOf(
139                                    ParamUtil.getBoolean(
140                                            portletRequest, DisplayTerms.AND_OPERATOR, true)));
141    
142                    if (headerNames != null) {
143                            _headerNames = new ArrayList<String>(headerNames.size());
144    
145                            _headerNames.addAll(headerNames);
146    
147                            _buildNormalizedHeaderNames(_headerNames);
148                    }
149    
150                    _emptyResultsMessage = emptyResultsMessage;
151    
152                    SearchContainerReference searchContainerReference =
153                            (SearchContainerReference)portletRequest.getAttribute(
154                                    WebKeys.SEARCH_CONTAINER_REFERENCE);
155    
156                    if (searchContainerReference != null) {
157                            searchContainerReference.register(this);
158                    }
159            }
160    
161            public SearchContainer(
162                    PortletRequest portletRequest, DisplayTerms displayTerms,
163                    DisplayTerms searchTerms, String curParam, int delta,
164                    PortletURL iteratorURL, List<String> headerNames,
165                    String emptyResultsMessage) {
166    
167                    this (
168                            portletRequest, displayTerms, searchTerms, curParam, 0, delta,
169                            iteratorURL, headerNames, emptyResultsMessage);
170            }
171    
172            public SearchContainer(
173                    PortletRequest portletRequest, PortletURL iteratorURL,
174                    List<String> headerNames, String emptyResultsMessage) {
175    
176                    this(
177                            portletRequest, null, null, DEFAULT_CUR_PARAM, DEFAULT_DELTA,
178                            iteratorURL, headerNames, emptyResultsMessage);
179            }
180    
181            public String getClassName() {
182                    return _className;
183            }
184    
185            public int getCur() {
186                    return _cur;
187            }
188    
189            public String getCurParam() {
190                    return _curParam;
191            }
192    
193            /**
194             * @deprecated As of 6.2.0, replaced by {@link #getCur}
195             */
196            public int getCurValue() {
197                    return getCur();
198            }
199    
200            public int getDelta() {
201                    return _delta;
202            }
203    
204            public String getDeltaParam() {
205                    return _deltaParam;
206            }
207    
208            public DisplayTerms getDisplayTerms() {
209                    return _displayTerms;
210            }
211    
212            public String getEmptyResultsMessage() {
213                    return _emptyResultsMessage;
214            }
215    
216            public int getEnd() {
217                    return _end;
218            }
219    
220            public List<String> getHeaderNames() {
221                    return _headerNames;
222            }
223    
224            public String getId(HttpServletRequest request, String namespace) {
225                    if (_uniqueId) {
226                            return _id;
227                    }
228    
229                    if (Validator.isNotNull(_id)) {
230                            _id = PortalUtil.getUniqueElementId(request, namespace, _id);
231                            _uniqueId = true;
232    
233                            return _id;
234                    }
235    
236                    String id = null;
237    
238                    if (Validator.isNotNull(_className)) {
239                            String simpleClassName = _className;
240    
241                            int pos = simpleClassName.lastIndexOf(StringPool.PERIOD);
242    
243                            if (pos != -1) {
244                                    simpleClassName = simpleClassName.substring(pos + 1);
245                            }
246    
247                            String variableCasingSimpleClassName = TextFormatter.format(
248                                    simpleClassName, TextFormatter.I);
249    
250                            id = TextFormatter.formatPlural(variableCasingSimpleClassName);
251    
252                            id = id.concat("SearchContainer");
253    
254                            _id = PortalUtil.getUniqueElementId(request, namespace, id);
255                            _uniqueId = true;
256    
257                            return _id;
258                    }
259    
260                    id = DeterminateKeyGenerator.generate("taglib_search_container");
261    
262                    _id = id.concat("SearchContainer");
263                    _uniqueId = true;
264    
265                    return _id;
266            }
267    
268            public PortletURL getIteratorURL() {
269                    return _iteratorURL;
270            }
271    
272            /**
273             * @deprecated As of 6.2.0, see LPS-6312
274             */
275            public int getMaxPages() {
276                    return _maxPages;
277            }
278    
279            public List<String> getNormalizedHeaderNames() {
280                    return _normalizedHeaderNames;
281            }
282    
283            public Map<String, String> getOrderableHeaders() {
284                    return _orderableHeaders;
285            }
286    
287            public String getOrderByCol() {
288                    return _orderByCol;
289            }
290    
291            public String getOrderByColParam() {
292                    return _orderByColParam;
293            }
294    
295            public OrderByComparator getOrderByComparator() {
296                    return _orderByComparator;
297            }
298    
299            public String getOrderByJS() {
300                    return _orderByJS;
301            }
302    
303            public String getOrderByType() {
304                    return _orderByType;
305            }
306    
307            public String getOrderByTypeParam() {
308                    return _orderByTypeParam;
309            }
310    
311            public PortletRequest getPortletRequest() {
312                    return _portletRequest;
313            }
314    
315            public int getResultEnd() {
316                    return _resultEnd;
317            }
318    
319            public List<ResultRow> getResultRows() {
320                    return _resultRows;
321            }
322    
323            public List<R> getResults() {
324                    return _results;
325            }
326    
327            public RowChecker getRowChecker() {
328                    return _rowChecker;
329            }
330    
331            public DisplayTerms getSearchTerms() {
332                    return _searchTerms;
333            }
334    
335            public int getStart() {
336                    return _start;
337            }
338    
339            public int getTotal() {
340                    return _total;
341            }
342    
343            public String getTotalVar() {
344                    return _totalVar;
345            }
346    
347            public boolean isDeltaConfigurable() {
348                    return _deltaConfigurable;
349            }
350    
351            public boolean isHover() {
352                    return _hover;
353            }
354    
355            public boolean isRecalculateCur() {
356                    if ((_total == 0) && (_cur == DEFAULT_CUR)) {
357                            return false;
358                    }
359    
360                    if (((_cur - 1) * _delta) >= _total) {
361                            return true;
362                    }
363    
364                    return false;
365            }
366    
367            public void setClassName(String className) {
368                    _className = className;
369            }
370    
371            public void setDelta(int delta) {
372                    if (delta <= 0) {
373                            _delta = DEFAULT_DELTA;
374                    }
375                    else if (delta > MAX_DELTA) {
376                            _delta = MAX_DELTA;
377                    }
378                    else {
379                            _delta = delta;
380                    }
381    
382                    _calculateStartAndEnd();
383            }
384    
385            public void setDeltaConfigurable(boolean deltaConfigurable) {
386                    _deltaConfigurable = deltaConfigurable;
387            }
388    
389            public void setDeltaParam(String deltaParam) {
390                    _deltaParam = deltaParam;
391            }
392    
393            public void setEmptyResultsMessage(String emptyResultsMessage) {
394                    _emptyResultsMessage = emptyResultsMessage;
395            }
396    
397            public void setHeaderNames(List<String> headerNames) {
398                    _headerNames = headerNames;
399    
400                    _buildNormalizedHeaderNames(headerNames);
401            }
402    
403            public void setHover(boolean hover) {
404                    _hover = hover;
405            }
406    
407            public void setId(String id) {
408                    _id = id;
409            }
410    
411            public void setIteratorURL(PortletURL iteratorURL) {
412                    _iteratorURL = iteratorURL;
413            }
414    
415            /**
416             * @deprecated As of 6.2.0, see LPS-6312
417             */
418            public void setMaxPages(int maxPages) {
419                    _maxPages = maxPages;
420            }
421    
422            public void setOrderableHeaders(Map<String, String> orderableHeaders) {
423                    _orderableHeaders = orderableHeaders;
424            }
425    
426            public void setOrderByCol(String orderByCol) {
427                    _orderByCol = orderByCol;
428    
429                    _iteratorURL.setParameter(_orderByColParam, _orderByCol);
430            }
431    
432            public void setOrderByColParam(String orderByColParam) {
433                    _orderByColParam = orderByColParam;
434            }
435    
436            public void setOrderByComparator(OrderByComparator orderByComparator) {
437                    _orderByComparator = orderByComparator;
438            }
439    
440            public void setOrderByJS(String orderByJS) {
441                    _orderByJS = orderByJS;
442            }
443    
444            public void setOrderByType(String orderByType) {
445                    _orderByType = orderByType;
446    
447                    _iteratorURL.setParameter(_orderByTypeParam, _orderByType);
448            }
449    
450            public void setOrderByTypeParam(String orderByTypeParam) {
451                    _orderByTypeParam = orderByTypeParam;
452            }
453    
454            public void setResults(List<R> results) {
455                    _results = results;
456            }
457    
458            public void setRowChecker(RowChecker rowChecker) {
459                    _rowChecker = rowChecker;
460            }
461    
462            public void setTotal(int total) {
463                    _total = total;
464    
465                    _calculateCur();
466                    _calculateStartAndEnd();
467            }
468    
469            public void setTotalVar(String totalVar) {
470                    _totalVar = totalVar;
471            }
472    
473            private void _buildNormalizedHeaderNames(List<String> headerNames) {
474                    if (headerNames == null) {
475                            return;
476                    }
477    
478                    _normalizedHeaderNames = new ArrayList<String>(headerNames.size());
479    
480                    for (String headerName : headerNames) {
481                            _normalizedHeaderNames.add(
482                                    FriendlyURLNormalizerUtil.normalize(headerName));
483                    }
484            }
485    
486            private void _calculateCur() {
487                    if (_total == 0) {
488                            _cur = DEFAULT_CUR;
489    
490                            return;
491                    }
492    
493                    if (isRecalculateCur()) {
494                            if ((_total % _delta) == 0) {
495                                    _cur = (_total / _delta);
496                            }
497                            else {
498                                    _cur = (_total / _delta) + 1;
499                            }
500                    }
501            }
502    
503            private void _calculateStartAndEnd() {
504                    int[] startAndEnd = SearchPaginationUtil.calculateStartAndEnd(
505                            _cur, _delta);
506    
507                    _start = startAndEnd[0];
508                    _end = startAndEnd[1];
509    
510                    _resultEnd = _end;
511    
512                    if (_resultEnd > _total) {
513                            _resultEnd = _total;
514                    }
515            }
516    
517            private String _className;
518            private int _cur;
519            private String _curParam = DEFAULT_CUR_PARAM;
520            private int _delta = DEFAULT_DELTA;
521            private boolean _deltaConfigurable = DEFAULT_DELTA_CONFIGURABLE;
522            private String _deltaParam = DEFAULT_DELTA_PARAM;
523            private DisplayTerms _displayTerms;
524            private String _emptyResultsMessage;
525            private int _end;
526            private List<String> _headerNames;
527            private boolean _hover = true;
528            private String _id;
529            private PortletURL _iteratorURL;
530    
531            /**
532             * @deprecated As of 6.2.0, see LPS-6312
533             */
534            private int _maxPages = DEFAULT_MAX_PAGES;
535    
536            private List<String> _normalizedHeaderNames;
537            private Map<String, String> _orderableHeaders;
538            private String _orderByCol;
539            private String _orderByColParam = DEFAULT_ORDER_BY_COL_PARAM;
540            private OrderByComparator _orderByComparator;
541            private String _orderByJS;
542            private String _orderByType;
543            private String _orderByTypeParam = DEFAULT_ORDER_BY_TYPE_PARAM;
544            private PortletRequest _portletRequest;
545            private int _resultEnd;
546            private List<ResultRow> _resultRows = new ArrayList<ResultRow>();
547            private List<R> _results = new ArrayList<R>();
548            private RowChecker _rowChecker;
549            private DisplayTerms _searchTerms;
550            private int _start;
551            private int _total;
552            private String _totalVar;
553            private boolean _uniqueId;
554    
555    }