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