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                    else {
260                            id = DeterminateKeyGenerator.generate("taglib_search_container");
261    
262                            _id = id.concat("SearchContainer");
263                            _uniqueId = true;
264    
265                            return _id;
266                    }
267            }
268    
269            public PortletURL getIteratorURL() {
270                    return _iteratorURL;
271            }
272    
273            /**
274             * @deprecated As of 6.2.0, see LPS-6312
275             */
276            public int getMaxPages() {
277                    return _maxPages;
278            }
279    
280            public List<String> getNormalizedHeaderNames() {
281                    return _normalizedHeaderNames;
282            }
283    
284            public Map<String, String> getOrderableHeaders() {
285                    return _orderableHeaders;
286            }
287    
288            public String getOrderByCol() {
289                    return _orderByCol;
290            }
291    
292            public String getOrderByColParam() {
293                    return _orderByColParam;
294            }
295    
296            public OrderByComparator getOrderByComparator() {
297                    return _orderByComparator;
298            }
299    
300            public String getOrderByJS() {
301                    return _orderByJS;
302            }
303    
304            public String getOrderByType() {
305                    return _orderByType;
306            }
307    
308            public String getOrderByTypeParam() {
309                    return _orderByTypeParam;
310            }
311    
312            public PortletRequest getPortletRequest() {
313                    return _portletRequest;
314            }
315    
316            public int getResultEnd() {
317                    return _resultEnd;
318            }
319    
320            public List<ResultRow> getResultRows() {
321                    return _resultRows;
322            }
323    
324            public List<R> getResults() {
325                    return _results;
326            }
327    
328            public RowChecker getRowChecker() {
329                    return _rowChecker;
330            }
331    
332            public DisplayTerms getSearchTerms() {
333                    return _searchTerms;
334            }
335    
336            public int getStart() {
337                    return _start;
338            }
339    
340            public int getTotal() {
341                    return _total;
342            }
343    
344            public String getTotalVar() {
345                    return _totalVar;
346            }
347    
348            public boolean isDeltaConfigurable() {
349                    return _deltaConfigurable;
350            }
351    
352            public boolean isHover() {
353                    return _hover;
354            }
355    
356            public boolean isRecalculateCur() {
357                    if ((_total == 0) && (_cur == DEFAULT_CUR)) {
358                            return false;
359                    }
360    
361                    if (((_cur - 1) * _delta) >= _total) {
362                            return true;
363                    }
364    
365                    return false;
366            }
367    
368            public void setClassName(String className) {
369                    _className = className;
370            }
371    
372            public void setDelta(int delta) {
373                    if (delta <= 0) {
374                            _delta = DEFAULT_DELTA;
375                    }
376                    else if (delta > MAX_DELTA) {
377                            _delta = MAX_DELTA;
378                    }
379                    else {
380                            _delta = delta;
381                    }
382    
383                    _calculateStartAndEnd();
384            }
385    
386            public void setDeltaConfigurable(boolean deltaConfigurable) {
387                    _deltaConfigurable = deltaConfigurable;
388            }
389    
390            public void setDeltaParam(String deltaParam) {
391                    _deltaParam = deltaParam;
392            }
393    
394            public void setEmptyResultsMessage(String emptyResultsMessage) {
395                    _emptyResultsMessage = emptyResultsMessage;
396            }
397    
398            public void setHeaderNames(List<String> headerNames) {
399                    _headerNames = headerNames;
400    
401                    _buildNormalizedHeaderNames(headerNames);
402            }
403    
404            public void setHover(boolean hover) {
405                    _hover = hover;
406            }
407    
408            public void setId(String id) {
409                    _id = id;
410            }
411    
412            public void setIteratorURL(PortletURL iteratorURL) {
413                    _iteratorURL = iteratorURL;
414            }
415    
416            /**
417             * @deprecated As of 6.2.0, see LPS-6312
418             */
419            public void setMaxPages(int maxPages) {
420                    _maxPages = maxPages;
421            }
422    
423            public void setOrderableHeaders(Map<String, String> orderableHeaders) {
424                    _orderableHeaders = orderableHeaders;
425            }
426    
427            public void setOrderByCol(String orderByCol) {
428                    _orderByCol = orderByCol;
429    
430                    _iteratorURL.setParameter(_orderByColParam, _orderByCol);
431            }
432    
433            public void setOrderByColParam(String orderByColParam) {
434                    _orderByColParam = orderByColParam;
435            }
436    
437            public void setOrderByComparator(OrderByComparator orderByComparator) {
438                    _orderByComparator = orderByComparator;
439            }
440    
441            public void setOrderByJS(String orderByJS) {
442                    _orderByJS = orderByJS;
443            }
444    
445            public void setOrderByType(String orderByType) {
446                    _orderByType = orderByType;
447    
448                    _iteratorURL.setParameter(_orderByTypeParam, _orderByType);
449            }
450    
451            public void setOrderByTypeParam(String orderByTypeParam) {
452                    _orderByTypeParam = orderByTypeParam;
453            }
454    
455            public void setResults(List<R> results) {
456                    _results = results;
457            }
458    
459            public void setRowChecker(RowChecker rowChecker) {
460                    _rowChecker = rowChecker;
461            }
462    
463            public void setTotal(int total) {
464                    _total = total;
465    
466                    _calculateCur();
467                    _calculateStartAndEnd();
468            }
469    
470            public void setTotalVar(String totalVar) {
471                    _totalVar = totalVar;
472            }
473    
474            private void _buildNormalizedHeaderNames(List<String> headerNames) {
475                    if (headerNames == null) {
476                            return;
477                    }
478    
479                    _normalizedHeaderNames = new ArrayList<String>(headerNames.size());
480    
481                    for (String headerName : headerNames) {
482                            _normalizedHeaderNames.add(
483                                    FriendlyURLNormalizerUtil.normalize(headerName));
484                    }
485            }
486    
487            private void _calculateCur() {
488                    if (_total == 0) {
489                            _cur = DEFAULT_CUR;
490    
491                            return;
492                    }
493    
494                    if (isRecalculateCur()) {
495                            if ((_total % _delta) == 0) {
496                                    _cur = (_total / _delta);
497                            }
498                            else {
499                                    _cur = (_total / _delta) + 1;
500                            }
501                    }
502            }
503    
504            private void _calculateStartAndEnd() {
505                    int[] startAndEnd = SearchPaginationUtil.calculateStartAndEnd(
506                            _cur, _delta);
507    
508                    _start = startAndEnd[0];
509                    _end = startAndEnd[1];
510    
511                    _resultEnd = _end;
512    
513                    if (_resultEnd > _total) {
514                            _resultEnd = _total;
515                    }
516            }
517    
518            private String _className;
519            private int _cur;
520            private String _curParam = DEFAULT_CUR_PARAM;
521            private int _delta = DEFAULT_DELTA;
522            private boolean _deltaConfigurable = DEFAULT_DELTA_CONFIGURABLE;
523            private String _deltaParam = DEFAULT_DELTA_PARAM;
524            private DisplayTerms _displayTerms;
525            private String _emptyResultsMessage;
526            private int _end;
527            private List<String> _headerNames;
528            private boolean _hover = true;
529            private String _id;
530            private PortletURL _iteratorURL;
531    
532            /**
533             * @deprecated As of 6.2.0, see LPS-6312
534             */
535            private int _maxPages = DEFAULT_MAX_PAGES;
536    
537            private List<String> _normalizedHeaderNames;
538            private Map<String, String> _orderableHeaders;
539            private String _orderByCol;
540            private String _orderByColParam = DEFAULT_ORDER_BY_COL_PARAM;
541            private OrderByComparator _orderByComparator;
542            private String _orderByJS;
543            private String _orderByType;
544            private String _orderByTypeParam = DEFAULT_ORDER_BY_TYPE_PARAM;
545            private PortletRequest _portletRequest;
546            private int _resultEnd;
547            private List<ResultRow> _resultRows = new ArrayList<ResultRow>();
548            private List<R> _results = new ArrayList<R>();
549            private RowChecker _rowChecker;
550            private DisplayTerms _searchTerms;
551            private int _start;
552            private int _total;
553            private String _totalVar;
554            private boolean _uniqueId;
555    
556    }