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