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