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.portlet.asset.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.portlet.LiferayPortletRequest;
021    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
022    import com.liferay.portal.kernel.portlet.LiferayWindowState;
023    import com.liferay.portal.kernel.search.BaseModelSearchResult;
024    import com.liferay.portal.kernel.search.Document;
025    import com.liferay.portal.kernel.search.DocumentImpl;
026    import com.liferay.portal.kernel.search.Field;
027    import com.liferay.portal.kernel.search.Hits;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.SearchContext;
030    import com.liferay.portal.kernel.search.SearchContextFactory;
031    import com.liferay.portal.kernel.search.Sort;
032    import com.liferay.portal.kernel.search.SortFactoryUtil;
033    import com.liferay.portal.kernel.util.ArrayUtil;
034    import com.liferay.portal.kernel.util.CharPool;
035    import com.liferay.portal.kernel.util.GetterUtil;
036    import com.liferay.portal.kernel.util.HttpUtil;
037    import com.liferay.portal.kernel.util.ListUtil;
038    import com.liferay.portal.kernel.util.LocaleUtil;
039    import com.liferay.portal.kernel.util.ParamUtil;
040    import com.liferay.portal.kernel.util.PredicateFilter;
041    import com.liferay.portal.kernel.util.StringPool;
042    import com.liferay.portal.kernel.util.StringUtil;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.kernel.util.WebKeys;
045    import com.liferay.portal.model.Layout;
046    import com.liferay.portal.model.LayoutTypePortletConstants;
047    import com.liferay.portal.model.Portlet;
048    import com.liferay.portal.security.permission.ActionKeys;
049    import com.liferay.portal.security.permission.PermissionChecker;
050    import com.liferay.portal.security.permission.comparator.ModelResourceComparator;
051    import com.liferay.portal.service.PortletLocalServiceUtil;
052    import com.liferay.portal.theme.PortletDisplay;
053    import com.liferay.portal.theme.ThemeDisplay;
054    import com.liferay.portal.util.PortalUtil;
055    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
056    import com.liferay.portlet.asset.model.AssetCategory;
057    import com.liferay.portlet.asset.model.AssetCategoryProperty;
058    import com.liferay.portlet.asset.model.AssetEntry;
059    import com.liferay.portlet.asset.model.AssetRendererFactory;
060    import com.liferay.portlet.asset.model.AssetTag;
061    import com.liferay.portlet.asset.model.AssetVocabulary;
062    import com.liferay.portlet.asset.model.ClassType;
063    import com.liferay.portlet.asset.model.ClassTypeReader;
064    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
065    import com.liferay.portlet.asset.service.AssetCategoryPropertyLocalServiceUtil;
066    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
067    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
068    import com.liferay.portlet.asset.service.permission.AssetCategoryPermission;
069    import com.liferay.portlet.asset.service.permission.AssetVocabularyPermission;
070    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
071    import com.liferay.portlet.dynamicdatamapping.DDMStructure;
072    import com.liferay.portlet.dynamicdatamapping.DDMStructureManager;
073    import com.liferay.portlet.dynamicdatamapping.DDMStructureManagerUtil;
074    
075    import java.io.Serializable;
076    
077    import java.util.ArrayList;
078    import java.util.Collections;
079    import java.util.HashMap;
080    import java.util.HashSet;
081    import java.util.List;
082    import java.util.Locale;
083    import java.util.Map;
084    import java.util.Set;
085    import java.util.TreeMap;
086    
087    import javax.portlet.PortletMode;
088    import javax.portlet.PortletURL;
089    
090    import javax.servlet.http.HttpServletRequest;
091    
092    /**
093     * @author Brian Wing Shun Chan
094     * @author Jorge Ferrer
095     */
096    public class AssetUtil {
097    
098            public static final int ASSET_ENTRY_ABSTRACT_LENGTH = 200;
099    
100            public static final String CLASSNAME_SEPARATOR = "_CLASSNAME_";
101    
102            public static final char[] INVALID_CHARACTERS = new char[] {
103                    CharPool.AMPERSAND, CharPool.APOSTROPHE, CharPool.AT,
104                    CharPool.BACK_SLASH, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
105                    CharPool.COLON, CharPool.COMMA, CharPool.EQUAL, CharPool.GREATER_THAN,
106                    CharPool.FORWARD_SLASH, CharPool.LESS_THAN, CharPool.NEW_LINE,
107                    CharPool.OPEN_BRACKET, CharPool.OPEN_CURLY_BRACE, CharPool.PERCENT,
108                    CharPool.PIPE, CharPool.PLUS, CharPool.POUND, CharPool.PRIME,
109                    CharPool.QUESTION, CharPool.QUOTE, CharPool.RETURN, CharPool.SEMICOLON,
110                    CharPool.SLASH, CharPool.STAR, CharPool.TILDE
111            };
112    
113            public static Set<String> addLayoutTags(
114                    HttpServletRequest request, List<AssetTag> tags) {
115    
116                    Set<String> layoutTags = getLayoutTagNames(request);
117    
118                    for (AssetTag tag : tags) {
119                            layoutTags.add(tag.getName());
120                    }
121    
122                    return layoutTags;
123            }
124    
125            public static void addPortletBreadcrumbEntries(
126                            long assetCategoryId, HttpServletRequest request,
127                            PortletURL portletURL)
128                    throws Exception {
129    
130                    AssetCategory assetCategory = AssetCategoryLocalServiceUtil.getCategory(
131                            assetCategoryId);
132    
133                    List<AssetCategory> ancestorCategories = assetCategory.getAncestors();
134    
135                    Collections.reverse(ancestorCategories);
136    
137                    for (AssetCategory ancestorCategory : ancestorCategories) {
138                            portletURL.setParameter(
139                                    "categoryId", String.valueOf(ancestorCategory.getCategoryId()));
140    
141                            PortalUtil.addPortletBreadcrumbEntry(
142                                    request, ancestorCategory.getTitleCurrentValue(),
143                                    portletURL.toString());
144                    }
145    
146                    portletURL.setParameter("categoryId", String.valueOf(assetCategoryId));
147    
148                    PortalUtil.addPortletBreadcrumbEntry(
149                            request, assetCategory.getTitleCurrentValue(),
150                            portletURL.toString());
151            }
152    
153            public static String checkViewURL(
154                    AssetEntry assetEntry, boolean viewInContext, String viewURL,
155                    String currentURL, ThemeDisplay themeDisplay) {
156    
157                    if (Validator.isNull(viewURL)) {
158                            return viewURL;
159                    }
160    
161                    viewURL = HttpUtil.setParameter(
162                            viewURL, "inheritRedirect", viewInContext);
163    
164                    Layout layout = themeDisplay.getLayout();
165    
166                    String assetEntryLayoutUuid = assetEntry.getLayoutUuid();
167    
168                    if (!viewInContext ||
169                            (Validator.isNotNull(assetEntryLayoutUuid) &&
170                             !assetEntryLayoutUuid.equals(layout.getUuid()))) {
171    
172                            viewURL = HttpUtil.setParameter(viewURL, "redirect", currentURL);
173                    }
174    
175                    return viewURL;
176            }
177    
178            public static long[] filterCategoryIds(
179                            PermissionChecker permissionChecker, long[] categoryIds)
180                    throws PortalException {
181    
182                    List<Long> viewableCategoryIds = new ArrayList<>();
183    
184                    for (long categoryId : categoryIds) {
185                            AssetCategory category =
186                                    AssetCategoryLocalServiceUtil.fetchCategory(categoryId);
187    
188                            if ((category != null) &&
189                                    AssetCategoryPermission.contains(
190                                            permissionChecker, categoryId, ActionKeys.VIEW)) {
191    
192                                    viewableCategoryIds.add(categoryId);
193                            }
194                    }
195    
196                    return ArrayUtil.toArray(
197                            viewableCategoryIds.toArray(new Long[viewableCategoryIds.size()]));
198            }
199    
200            public static List<AssetVocabulary> filterVocabularies(
201                    List<AssetVocabulary> vocabularies, String className,
202                    final long classTypePK) {
203    
204                    final long classNameId = PortalUtil.getClassNameId(className);
205    
206                    PredicateFilter<AssetVocabulary> predicateFilter =
207                            new PredicateFilter<AssetVocabulary>() {
208    
209                                    @Override
210                                    public boolean filter(AssetVocabulary assetVocabulary) {
211                                            return
212                                                    assetVocabulary.isAssociatedToClassNameIdAndClassTypePK(
213                                                            classNameId, classTypePK);
214                                    }
215    
216                            };
217    
218                    return ListUtil.filter(vocabularies, predicateFilter);
219            }
220    
221            public static long[] filterVocabularyIds(
222                            PermissionChecker permissionChecker, long[] vocabularyIds)
223                    throws PortalException {
224    
225                    List<Long> viewableVocabularyIds = new ArrayList<>();
226    
227                    for (long vocabularyId : vocabularyIds) {
228                            if (AssetVocabularyPermission.contains(
229                                            permissionChecker, vocabularyId, ActionKeys.VIEW)) {
230    
231                                    viewableVocabularyIds.add(vocabularyId);
232                            }
233                    }
234    
235                    return ArrayUtil.toArray(
236                            viewableVocabularyIds.toArray(
237                                    new Long[viewableVocabularyIds.size()]));
238            }
239    
240            public static PortletURL getAddPortletURL(
241                            LiferayPortletRequest liferayPortletRequest,
242                            LiferayPortletResponse liferayPortletResponse, long groupId,
243                            String className, long classTypeId, long[] allAssetCategoryIds,
244                            String[] allAssetTagNames, String redirect)
245                    throws Exception {
246    
247                    ThemeDisplay themeDisplay =
248                            (ThemeDisplay)liferayPortletRequest.getAttribute(
249                                    WebKeys.THEME_DISPLAY);
250    
251                    AssetRendererFactory<?> assetRendererFactory =
252                            AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
253                                    className);
254    
255                    if ((assetRendererFactory == null) ||
256                            !assetRendererFactory.hasAddPermission(
257                                    themeDisplay.getPermissionChecker(), groupId, classTypeId)) {
258    
259                            return null;
260                    }
261    
262                    PortletURL addPortletURL = assetRendererFactory.getURLAdd(
263                            liferayPortletRequest, liferayPortletResponse, classTypeId);
264    
265                    if (addPortletURL == null) {
266                            return null;
267                    }
268    
269                    if (redirect != null) {
270                            addPortletURL.setParameter("redirect", redirect);
271                    }
272    
273                    String referringPortletResource = ParamUtil.getString(
274                            liferayPortletRequest, "portletResource");
275    
276                    if (Validator.isNotNull(referringPortletResource)) {
277                            addPortletURL.setParameter(
278                                    "referringPortletResource", referringPortletResource);
279                    }
280                    else {
281                            PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
282    
283                            addPortletURL.setParameter(
284                                    "referringPortletResource", portletDisplay.getId());
285    
286                            if (allAssetCategoryIds != null) {
287                                    Map<Long, String> assetVocabularyAssetCategoryIds =
288                                            new HashMap<>();
289    
290                                    for (long assetCategoryId : allAssetCategoryIds) {
291                                            AssetCategory assetCategory =
292                                                    AssetCategoryLocalServiceUtil.fetchAssetCategory(
293                                                            assetCategoryId);
294    
295                                            if (assetCategory == null) {
296                                                    continue;
297                                            }
298    
299                                            long assetVocabularyId = assetCategory.getVocabularyId();
300    
301                                            if (assetVocabularyAssetCategoryIds.containsKey(
302                                                            assetVocabularyId)) {
303    
304                                                    String assetCategoryIds =
305                                                            assetVocabularyAssetCategoryIds.get(
306                                                                    assetVocabularyId);
307    
308                                                    assetVocabularyAssetCategoryIds.put(
309                                                            assetVocabularyId,
310                                                            assetCategoryIds + StringPool.COMMA +
311                                                                    assetCategoryId);
312                                            }
313                                            else {
314                                                    assetVocabularyAssetCategoryIds.put(
315                                                            assetVocabularyId, String.valueOf(assetCategoryId));
316                                            }
317                                    }
318    
319                                    for (Map.Entry<Long, String> entry :
320                                                    assetVocabularyAssetCategoryIds.entrySet()) {
321    
322                                            long assetVocabularyId = entry.getKey();
323                                            String assetCategoryIds = entry.getValue();
324    
325                                            addPortletURL.setParameter(
326                                                    "assetCategoryIds_" + assetVocabularyId,
327                                                    assetCategoryIds);
328                                    }
329                            }
330    
331                            if (allAssetTagNames != null) {
332                                    addPortletURL.setParameter(
333                                            "assetTagNames", StringUtil.merge(allAssetTagNames));
334                            }
335                    }
336    
337                    addPortletURL.setPortletMode(PortletMode.VIEW);
338                    addPortletURL.setWindowState(LiferayWindowState.POP_UP);
339    
340                    return addPortletURL;
341            }
342    
343            /**
344             * @deprecated As of 7.0.0, replaced by {@link
345             *             #getAddPortletURL(LiferayPortletRequest,
346             *             LiferayPortletResponse, long, String, long, long[], String[],
347             *             String)}
348             */
349            @Deprecated
350            public static PortletURL getAddPortletURL(
351                            LiferayPortletRequest liferayPortletRequest,
352                            LiferayPortletResponse liferayPortletResponse, String className,
353                            long classTypeId, long[] allAssetCategoryIds,
354                            String[] allAssetTagNames, String redirect)
355                    throws Exception {
356    
357                    ThemeDisplay themeDisplay =
358                            (ThemeDisplay)liferayPortletRequest.getAttribute(
359                                    WebKeys.THEME_DISPLAY);
360    
361                    return getAddPortletURL(
362                            liferayPortletRequest, liferayPortletResponse,
363                            themeDisplay.getScopeGroupId(), className, classTypeId,
364                            allAssetCategoryIds, allAssetTagNames, redirect);
365            }
366    
367            public static Map<String, PortletURL> getAddPortletURLs(
368                            LiferayPortletRequest liferayPortletRequest,
369                            LiferayPortletResponse liferayPortletResponse, long groupId,
370                            long[] classNameIds, long[] classTypeIds,
371                            long[] allAssetCategoryIds, String[] allAssetTagNames,
372                            String redirect)
373                    throws Exception {
374    
375                    ThemeDisplay themeDisplay =
376                            (ThemeDisplay)liferayPortletRequest.getAttribute(
377                                    WebKeys.THEME_DISPLAY);
378    
379                    Map<String, PortletURL> addPortletURLs = new TreeMap<>(
380                            new ModelResourceComparator(themeDisplay.getLocale()));
381    
382                    for (long classNameId : classNameIds) {
383                            String className = PortalUtil.getClassName(classNameId);
384    
385                            AssetRendererFactory<?> assetRendererFactory =
386                                    AssetRendererFactoryRegistryUtil.
387                                            getAssetRendererFactoryByClassName(className);
388    
389                            if (Validator.isNull(assetRendererFactory.getPortletId())) {
390                                    continue;
391                            }
392    
393                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
394                                    themeDisplay.getCompanyId(),
395                                    assetRendererFactory.getPortletId());
396    
397                            if (!portlet.isActive()) {
398                                    continue;
399                            }
400    
401                            ClassTypeReader classTypeReader =
402                                    assetRendererFactory.getClassTypeReader();
403    
404                            List<ClassType> classTypes = classTypeReader.getAvailableClassTypes(
405                                    PortalUtil.getCurrentAndAncestorSiteGroupIds(
406                                            themeDisplay.getScopeGroupId()),
407                                    themeDisplay.getLocale());
408    
409                            if ((classTypeIds.length == 0) || classTypes.isEmpty()) {
410                                    PortletURL addPortletURL = getAddPortletURL(
411                                            liferayPortletRequest, liferayPortletResponse, groupId,
412                                            className, 0, allAssetCategoryIds, allAssetTagNames,
413                                            redirect);
414    
415                                    if (addPortletURL != null) {
416                                            addPortletURLs.put(className, addPortletURL);
417                                    }
418                            }
419    
420                            for (ClassType classType : classTypes) {
421                                    long classTypeId = classType.getClassTypeId();
422    
423                                    if (ArrayUtil.contains(classTypeIds, classTypeId) ||
424                                            (classTypeIds.length == 0)) {
425    
426                                            PortletURL addPortletURL = getAddPortletURL(
427                                                    liferayPortletRequest, liferayPortletResponse, groupId,
428                                                    className, classTypeId, allAssetCategoryIds,
429                                                    allAssetTagNames, redirect);
430    
431                                            if (addPortletURL != null) {
432                                                    String mesage =
433                                                            className + CLASSNAME_SEPARATOR +
434                                                                    classType.getName();
435    
436                                                    addPortletURLs.put(mesage, addPortletURL);
437                                            }
438                                    }
439                            }
440                    }
441    
442                    return addPortletURLs;
443            }
444    
445            /**
446             * @deprecated As of 7.0.0, replaced by {@link
447             *             #getAddPortletURLs(LiferayPortletRequest,
448             *             LiferayPortletResponse, long, long[], long[], long[],
449             *             String[], String)}
450             */
451            @Deprecated
452            public static Map<String, PortletURL> getAddPortletURLs(
453                            LiferayPortletRequest liferayPortletRequest,
454                            LiferayPortletResponse liferayPortletResponse, long[] classNameIds,
455                            long[] classTypeIds, long[] allAssetCategoryIds,
456                            String[] allAssetTagNames, String redirect)
457                    throws Exception {
458    
459                    ThemeDisplay themeDisplay =
460                            (ThemeDisplay)liferayPortletRequest.getAttribute(
461                                    WebKeys.THEME_DISPLAY);
462    
463                    return getAddPortletURLs(
464                            liferayPortletRequest, liferayPortletResponse,
465                            themeDisplay.getScopeGroupId(), classNameIds, classTypeIds,
466                            allAssetCategoryIds, allAssetTagNames, redirect);
467            }
468    
469            public static List<AssetEntry> getAssetEntries(Hits hits) {
470                    List<AssetEntry> assetEntries = new ArrayList<>();
471    
472                    if (hits.getDocs() == null) {
473                            return assetEntries;
474                    }
475    
476                    for (Document document : hits.getDocs()) {
477                            String className = GetterUtil.getString(
478                                    document.get(Field.ENTRY_CLASS_NAME));
479                            long classPK = GetterUtil.getLong(
480                                    document.get(Field.ENTRY_CLASS_PK));
481    
482                            try {
483                                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
484                                            className, classPK);
485    
486                                    assetEntries.add(assetEntry);
487                            }
488                            catch (Exception e) {
489                            }
490                    }
491    
492                    return assetEntries;
493            }
494    
495            public static String getAssetKeywords(String className, long classPK) {
496                    List<AssetTag> tags = AssetTagLocalServiceUtil.getTags(
497                            className, classPK);
498                    List<AssetCategory> categories =
499                            AssetCategoryLocalServiceUtil.getCategories(className, classPK);
500    
501                    StringBuffer sb = new StringBuffer();
502    
503                    sb.append(ListUtil.toString(tags, AssetTag.NAME_ACCESSOR));
504    
505                    if (!tags.isEmpty()) {
506                            sb.append(StringPool.COMMA);
507                    }
508    
509                    sb.append(ListUtil.toString(categories, AssetCategory.NAME_ACCESSOR));
510    
511                    return sb.toString();
512            }
513    
514            public static String getDefaultAssetPublisherId(Layout layout) {
515                    return layout.getTypeSettingsProperty(
516                            LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID,
517                            StringPool.BLANK);
518            }
519    
520            public static Set<String> getLayoutTagNames(HttpServletRequest request) {
521                    Set<String> tagNames = (Set<String>)request.getAttribute(
522                            WebKeys.ASSET_LAYOUT_TAG_NAMES);
523    
524                    if (tagNames == null) {
525                            tagNames = new HashSet<>();
526    
527                            request.setAttribute(WebKeys.ASSET_LAYOUT_TAG_NAMES, tagNames);
528                    }
529    
530                    return tagNames;
531            }
532    
533            public static boolean hasSubtype(
534                    String subtypeClassName, Map<String, PortletURL> addPortletURLs) {
535    
536                    for (Map.Entry<String, PortletURL> entry : addPortletURLs.entrySet()) {
537                            String className = entry.getKey();
538    
539                            if (className.startsWith(subtypeClassName) &&
540                                    !className.equals(subtypeClassName)) {
541    
542                                    return true;
543                            }
544                    }
545    
546                    return false;
547            }
548    
549            public static boolean isDefaultAssetPublisher(
550                    Layout layout, String portletId, String portletResource) {
551    
552                    String defaultAssetPublisherPortletId = getDefaultAssetPublisherId(
553                            layout);
554    
555                    if (Validator.isNull(defaultAssetPublisherPortletId)) {
556                            return false;
557                    }
558    
559                    if (defaultAssetPublisherPortletId.equals(portletId) ||
560                            defaultAssetPublisherPortletId.equals(portletResource)) {
561    
562                            return true;
563                    }
564    
565                    return false;
566            }
567    
568            public static boolean isValidWord(String word) {
569                    if (Validator.isNull(word)) {
570                            return false;
571                    }
572    
573                    char[] wordCharArray = word.toCharArray();
574    
575                    for (char c : wordCharArray) {
576                            for (char invalidChar : INVALID_CHARACTERS) {
577                                    if (c == invalidChar) {
578                                            if (_log.isDebugEnabled()) {
579                                                    _log.debug(
580                                                            "Word " + word + " is not valid because " + c +
581                                                                    " is not allowed");
582                                            }
583    
584                                            return false;
585                                    }
586                            }
587                    }
588    
589                    return true;
590            }
591    
592            public static Hits search(
593                            HttpServletRequest request, AssetEntryQuery assetEntryQuery,
594                            int start, int end)
595                    throws Exception {
596    
597                    SearchContext searchContext = SearchContextFactory.getInstance(request);
598    
599                    return search(searchContext, assetEntryQuery, start, end);
600            }
601    
602            public static Hits search(
603                            SearchContext searchContext, AssetEntryQuery assetEntryQuery,
604                            int start, int end)
605                    throws Exception {
606    
607                    AssetSearcher assetSearcher = getAssetSearcher(
608                            searchContext, assetEntryQuery, start, end);
609    
610                    return assetSearcher.search(searchContext);
611            }
612    
613            public static BaseModelSearchResult<AssetEntry> searchAssetEntries(
614                            HttpServletRequest request, AssetEntryQuery assetEntryQuery,
615                            int start, int end)
616                    throws Exception {
617    
618                    SearchContext searchContext = SearchContextFactory.getInstance(request);
619    
620                    return searchAssetEntries(searchContext, assetEntryQuery, start, end);
621            }
622    
623            public static BaseModelSearchResult<AssetEntry> searchAssetEntries(
624                            SearchContext searchContext, AssetEntryQuery assetEntryQuery,
625                            int start, int end)
626                    throws Exception {
627    
628                    AssetSearcher assetSearcher = getAssetSearcher(
629                            searchContext, assetEntryQuery, start, end);
630    
631                    Hits hits = assetSearcher.search(searchContext);
632    
633                    List<AssetEntry> assetEntries = getAssetEntries(hits);
634    
635                    return new BaseModelSearchResult<>(assetEntries, hits.getLength());
636            }
637    
638            public static String substituteCategoryPropertyVariables(
639                    long groupId, long categoryId, String s) {
640    
641                    String result = s;
642    
643                    AssetCategory category = null;
644    
645                    if (categoryId > 0) {
646                            category = AssetCategoryLocalServiceUtil.fetchCategory(categoryId);
647                    }
648    
649                    if (category != null) {
650                            List<AssetCategoryProperty> categoryProperties =
651                                    AssetCategoryPropertyLocalServiceUtil.getCategoryProperties(
652                                            categoryId);
653    
654                            for (AssetCategoryProperty categoryProperty : categoryProperties) {
655                                    result = StringUtil.replace(
656                                            result, "[$" + categoryProperty.getKey() + "$]",
657                                            categoryProperty.getValue());
658                            }
659                    }
660    
661                    return StringUtil.stripBetween(result, "[$", "$]");
662            }
663    
664            public static String toWord(String text) {
665                    if (Validator.isNull(text)) {
666                            return text;
667                    }
668    
669                    char[] textCharArray = text.toCharArray();
670    
671                    for (int i = 0; i < textCharArray.length; i++) {
672                            char c = textCharArray[i];
673    
674                            for (char invalidChar : INVALID_CHARACTERS) {
675                                    if (c == invalidChar) {
676                                            textCharArray[i] = CharPool.SPACE;
677    
678                                            break;
679                                    }
680                            }
681                    }
682    
683                    return new String(textCharArray);
684            }
685    
686            protected static AssetSearcher getAssetSearcher(
687                            SearchContext searchContext, AssetEntryQuery assetEntryQuery,
688                            int start, int end)
689                    throws Exception {
690    
691                    Indexer<?> searcher = AssetSearcher.getInstance();
692    
693                    AssetSearcher assetSearcher = (AssetSearcher)searcher;
694    
695                    assetSearcher.setAssetEntryQuery(assetEntryQuery);
696    
697                    Layout layout = assetEntryQuery.getLayout();
698    
699                    if (layout != null) {
700                            searchContext.setAttribute(Field.LAYOUT_UUID, layout.getUuid());
701                    }
702    
703                    String ddmStructureFieldName = (String)assetEntryQuery.getAttribute(
704                            "ddmStructureFieldName");
705                    Serializable ddmStructureFieldValue = assetEntryQuery.getAttribute(
706                            "ddmStructureFieldValue");
707    
708                    if (Validator.isNotNull(ddmStructureFieldName) &&
709                            Validator.isNotNull(ddmStructureFieldValue)) {
710    
711                            searchContext.setAttribute(
712                                    "ddmStructureFieldName", ddmStructureFieldName);
713                            searchContext.setAttribute(
714                                    "ddmStructureFieldValue", ddmStructureFieldValue);
715                    }
716    
717                    String paginationType = GetterUtil.getString(
718                            assetEntryQuery.getPaginationType(), "more");
719    
720                    if (!paginationType.equals("none") &&
721                            !paginationType.equals("simple")) {
722    
723                            searchContext.setAttribute("paginationType", paginationType);
724                    }
725    
726                    searchContext.setClassTypeIds(assetEntryQuery.getClassTypeIds());
727                    searchContext.setEnd(end);
728                    searchContext.setGroupIds(assetEntryQuery.getGroupIds());
729    
730                    if (Validator.isNotNull(assetEntryQuery.getKeywords())) {
731                            searchContext.setLike(true);
732                    }
733    
734                    searchContext.setSorts(
735                            getSorts(assetEntryQuery, searchContext.getLocale()));
736                    searchContext.setStart(start);
737    
738                    return assetSearcher;
739            }
740    
741            protected static String getDDMFormFieldType(String sortField)
742                    throws PortalException {
743    
744                    String[] sortFields = sortField.split(
745                            DDMStructureManager.STRUCTURE_INDEXER_FIELD_SEPARATOR);
746    
747                    long ddmStructureId = GetterUtil.getLong(sortFields[2]);
748                    String fieldName = sortFields[3];
749    
750                    DDMStructure ddmStructure = DDMStructureManagerUtil.getStructure(
751                            ddmStructureId);
752    
753                    return ddmStructure.getFieldType(fieldName);
754            }
755    
756            protected static String getOrderByCol(
757                    String sortField, String fieldType, int sortType, Locale locale) {
758    
759                    if (sortField.startsWith(
760                                    DDMStructureManager.STRUCTURE_INDEXER_FIELD_PREFIX)) {
761    
762                            sortField = sortField.concat(StringPool.UNDERLINE).concat(
763                                    LocaleUtil.toLanguageId(locale));
764    
765                            if (!fieldType.equals("ddm-date") &&
766                                    ((sortType == Sort.DOUBLE_TYPE) ||
767                                     (sortType == Sort.FLOAT_TYPE) || (sortType == Sort.INT_TYPE) ||
768                                     (sortType == Sort.LONG_TYPE))) {
769    
770                                    sortField = sortField.concat(StringPool.UNDERLINE).concat(
771                                            "Number");
772                            }
773    
774                            sortField = DocumentImpl.getSortableFieldName(sortField);
775                    }
776                    else if (sortField.equals("modifiedDate")) {
777                            sortField = Field.MODIFIED_DATE;
778                    }
779                    else if (sortField.equals("title")) {
780                            sortField = DocumentImpl.getSortableFieldName(
781                                    "localized_title_".concat(LocaleUtil.toLanguageId(locale)));
782                    }
783    
784                    return sortField;
785            }
786    
787            protected static Sort getSort(
788                            String orderByType, String sortField, Locale locale)
789                    throws Exception {
790    
791                    String ddmFormFieldType = sortField;
792    
793                    if (ddmFormFieldType.startsWith(
794                                    DDMStructureManager.STRUCTURE_INDEXER_FIELD_PREFIX)) {
795    
796                            ddmFormFieldType = getDDMFormFieldType(ddmFormFieldType);
797                    }
798    
799                    int sortType = getSortType(ddmFormFieldType);
800    
801                    return SortFactoryUtil.getSort(
802                            AssetEntry.class, sortType,
803                            getOrderByCol(sortField, ddmFormFieldType, sortType, locale),
804                            !sortField.startsWith(
805                                    DDMStructureManager.STRUCTURE_INDEXER_FIELD_PREFIX),
806                            orderByType);
807            }
808    
809            protected static Sort[] getSorts(
810                            AssetEntryQuery assetEntryQuery, Locale locale)
811                    throws Exception {
812    
813                    Sort sort1 = getSort(
814                            assetEntryQuery.getOrderByType1(), assetEntryQuery.getOrderByCol1(),
815                            locale);
816                    Sort sort2 = getSort(
817                            assetEntryQuery.getOrderByType2(), assetEntryQuery.getOrderByCol2(),
818                            locale);
819    
820                    return new Sort[] {sort1, sort2};
821            }
822    
823            protected static int getSortType(String fieldType) {
824                    int sortType = Sort.STRING_TYPE;
825    
826                    if (fieldType.equals(Field.CREATE_DATE) ||
827                            fieldType.equals(Field.EXPIRATION_DATE) ||
828                            fieldType.equals(Field.PUBLISH_DATE) ||
829                            fieldType.equals("ddm-date") || fieldType.equals("modifiedDate")) {
830    
831                            sortType = Sort.LONG_TYPE;
832                    }
833                    else if (fieldType.equals(Field.PRIORITY) ||
834                                     fieldType.equals(Field.RATINGS) ||
835                                     fieldType.equals("ddm-decimal") ||
836                                     fieldType.equals("ddm-number")) {
837    
838                            sortType = Sort.DOUBLE_TYPE;
839                    }
840                    else if (fieldType.equals(Field.VIEW_COUNT) ||
841                                     fieldType.equals("ddm-integer")) {
842    
843                            sortType = Sort.INT_TYPE;
844                    }
845    
846                    return sortType;
847            }
848    
849            private static final Log _log = LogFactoryUtil.getLog(AssetUtil.class);
850    
851    }