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