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