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