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