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.assetpublisher.util;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.ListUtil;
023    import com.liferay.portal.kernel.util.ParamUtil;
024    import com.liferay.portal.kernel.util.PrimitiveLongList;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.xml.Document;
029    import com.liferay.portal.kernel.xml.Element;
030    import com.liferay.portal.kernel.xml.SAXReaderUtil;
031    import com.liferay.portal.model.Group;
032    import com.liferay.portal.model.GroupConstants;
033    import com.liferay.portal.model.Layout;
034    import com.liferay.portal.model.User;
035    import com.liferay.portal.service.GroupLocalServiceUtil;
036    import com.liferay.portal.service.LayoutLocalServiceUtil;
037    import com.liferay.portal.theme.ThemeDisplay;
038    import com.liferay.portal.util.PortalUtil;
039    import com.liferay.portal.util.WebKeys;
040    import com.liferay.portlet.PortletPreferencesFactoryUtil;
041    import com.liferay.portlet.asset.model.AssetCategory;
042    import com.liferay.portlet.asset.model.AssetEntry;
043    import com.liferay.portlet.asset.model.AssetRendererFactory;
044    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
045    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
046    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
047    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
048    import com.liferay.portlet.expando.model.ExpandoBridge;
049    
050    import java.io.IOException;
051    import java.io.Serializable;
052    
053    import java.util.HashMap;
054    import java.util.Iterator;
055    import java.util.List;
056    import java.util.Map;
057    
058    import javax.portlet.PortletPreferences;
059    import javax.portlet.PortletRequest;
060    
061    import javax.servlet.http.HttpServletRequest;
062    import javax.servlet.http.HttpSession;
063    
064    /**
065     * @author Raymond Aug??
066     * @author Julio Camarero
067     */
068    public class AssetPublisherUtil {
069    
070            public static final String SCOPE_ID_GROUP_PREFIX = "Group_";
071    
072            public static final String SCOPE_ID_LAYOUT_PREFIX = "Layout_";
073    
074            public static final String SCOPE_ID_LAYOUT_UUID_PREFIX = "LayoutUuid_";
075    
076            public static void addAndStoreSelection(
077                            PortletRequest portletRequest, String className, long classPK,
078                            int assetEntryOrder)
079                    throws Exception {
080    
081                    String referringPortletResource = ParamUtil.getString(
082                            portletRequest, "referringPortletResource");
083    
084                    if (Validator.isNull(referringPortletResource)) {
085                            return;
086                    }
087    
088                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
089                            WebKeys.THEME_DISPLAY);
090    
091                    Layout layout = LayoutLocalServiceUtil.getLayout(
092                            themeDisplay.getRefererPlid());
093    
094                    PortletPreferences portletPreferences =
095                            PortletPreferencesFactoryUtil.getPortletSetup(
096                                    themeDisplay.getScopeGroupId(), layout,
097                                    referringPortletResource, null);
098    
099                    String selectionStyle = portletPreferences.getValue(
100                            "selectionStyle", "dynamic");
101    
102                    if (selectionStyle.equals("dynamic")) {
103                            return;
104                    }
105    
106                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
107                            className, classPK);
108    
109                    addSelection(
110                            className, assetEntry.getEntryId(), assetEntryOrder,
111                            portletPreferences);
112    
113                    portletPreferences.store();
114            }
115    
116            public static void addRecentFolderId(
117                    PortletRequest portletRequest, String className, long classPK) {
118    
119                    _getRecentFolderIds(portletRequest).put(className, classPK);
120            }
121    
122            public static void addSelection(
123                            PortletRequest portletRequest,
124                            PortletPreferences portletPreferences)
125                    throws Exception {
126    
127                    String assetEntryType = ParamUtil.getString(
128                            portletRequest, "assetEntryType");
129                    long assetEntryId = ParamUtil.getLong(portletRequest, "assetEntryId");
130                    int assetEntryOrder = ParamUtil.getInteger(
131                            portletRequest, "assetEntryOrder");
132    
133                    addSelection(
134                            assetEntryType, assetEntryId, assetEntryOrder, portletPreferences);
135            }
136    
137            public static void addSelection(
138                            String assetEntryType, long assetEntryId, int assetEntryOrder,
139                            PortletPreferences portletPreferences)
140                    throws Exception {
141    
142                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
143                            assetEntryId);
144    
145                    String[] assetEntryXmls = portletPreferences.getValues(
146                            "assetEntryXml", new String[0]);
147    
148                    String assetEntryXml = _getAssetEntryXml(
149                            assetEntryType, assetEntry.getClassUuid());
150    
151                    if (assetEntryOrder > -1) {
152                            assetEntryXmls[assetEntryOrder] = assetEntryXml;
153                    }
154                    else {
155                            assetEntryXmls = ArrayUtil.append(assetEntryXmls, assetEntryXml);
156                    }
157    
158                    portletPreferences.setValues("assetEntryXml", assetEntryXmls);
159            }
160    
161            public static void addUserAttributes(
162                            User user, String[] customUserAttributeNames,
163                            AssetEntryQuery assetEntryQuery)
164                    throws Exception {
165    
166                    if ((user == null) || (customUserAttributeNames.length == 0)) {
167                            return;
168                    }
169    
170                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
171                            user.getCompanyId());
172    
173                    long[] allCategoryIds = assetEntryQuery.getAllCategoryIds();
174    
175                    PrimitiveLongList allCategoryIdsList = new PrimitiveLongList(
176                            allCategoryIds.length + customUserAttributeNames.length);
177    
178                    allCategoryIdsList.addAll(allCategoryIds);
179    
180                    for (String customUserAttributeName : customUserAttributeNames) {
181                            ExpandoBridge userCustomAttributes = user.getExpandoBridge();
182    
183                            Serializable userCustomFieldValue =
184                                    userCustomAttributes.getAttribute(customUserAttributeName);
185    
186                            if (userCustomFieldValue == null) {
187                                    continue;
188                            }
189    
190                            String userCustomFieldValueString = userCustomFieldValue.toString();
191    
192                            List<AssetCategory> assetCategories =
193                                    AssetCategoryLocalServiceUtil.search(
194                                            companyGroup.getGroupId(), userCustomFieldValueString,
195                                            new String[0], QueryUtil.ALL_POS, QueryUtil.ALL_POS);
196    
197                            for (AssetCategory assetCategory : assetCategories) {
198                                    allCategoryIdsList.add(assetCategory.getCategoryId());
199                            }
200                    }
201    
202                    assetEntryQuery.setAllCategoryIds(allCategoryIdsList.getArray());
203            }
204    
205            public static AssetEntryQuery getAssetEntryQuery(
206                            PortletPreferences portletPreferences, long[] scopeGroupIds)
207                    throws Exception {
208    
209                    AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
210    
211                    long[] allAssetCategoryIds = new long[0];
212                    long[] anyAssetCategoryIds = new long[0];
213                    long[] notAllAssetCategoryIds = new long[0];
214                    long[] notAnyAssetCategoryIds = new long[0];
215    
216                    String[] allAssetTagNames = new String[0];
217                    String[] anyAssetTagNames = new String[0];
218                    String[] notAllAssetTagNames = new String[0];
219                    String[] notAnyAssetTagNames = new String[0];
220    
221                    for (int i = 0; true; i++) {
222                            String[] queryValues = portletPreferences.getValues(
223                                    "queryValues" + i, null);
224    
225                            if ((queryValues == null) || (queryValues.length == 0)) {
226                                    break;
227                            }
228    
229                            boolean queryContains = GetterUtil.getBoolean(
230                                    portletPreferences.getValue(
231                                            "queryContains" + i, StringPool.BLANK));
232                            boolean queryAndOperator = GetterUtil.getBoolean(
233                                    portletPreferences.getValue(
234                                            "queryAndOperator" + i, StringPool.BLANK));
235                            String queryName = portletPreferences.getValue(
236                                    "queryName" + i, StringPool.BLANK);
237    
238                            if (Validator.equals(queryName, "assetCategories")) {
239                                    long[] assetCategoryIds = GetterUtil.getLongValues(queryValues);
240    
241                                    if (queryContains &&
242                                            (queryAndOperator || (assetCategoryIds.length == 1))) {
243    
244                                            allAssetCategoryIds = assetCategoryIds;
245                                    }
246                                    else if (queryContains && !queryAndOperator) {
247                                            anyAssetCategoryIds = assetCategoryIds;
248                                    }
249                                    else if (!queryContains && queryAndOperator) {
250                                            notAllAssetCategoryIds = assetCategoryIds;
251                                    }
252                                    else {
253                                            notAnyAssetCategoryIds = assetCategoryIds;
254                                    }
255                            }
256                            else {
257                                    if (queryContains && queryAndOperator) {
258                                            allAssetTagNames = queryValues;
259                                    }
260                                    else if (queryContains && !queryAndOperator) {
261                                            anyAssetTagNames = queryValues;
262                                    }
263                                    else if (!queryContains && queryAndOperator) {
264                                            notAllAssetTagNames = queryValues;
265                                    }
266                                    else {
267                                            notAnyAssetTagNames = queryValues;
268                                    }
269                            }
270                    }
271    
272                    assetEntryQuery.setAllCategoryIds(allAssetCategoryIds);
273    
274                    for (String assetTagName : allAssetTagNames) {
275                            long[] allAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
276                                    scopeGroupIds, assetTagName);
277    
278                            assetEntryQuery.addAllTagIdsArray(allAssetTagIds);
279                    }
280    
281                    assetEntryQuery.setAnyCategoryIds(anyAssetCategoryIds);
282    
283                    long[] anyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
284                            scopeGroupIds, anyAssetTagNames);
285    
286                    assetEntryQuery.setAnyTagIds(anyAssetTagIds);
287    
288                    assetEntryQuery.setNotAllCategoryIds(notAllAssetCategoryIds);
289    
290                    for (String assetTagName : notAllAssetTagNames) {
291                            long[] notAllAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
292                                    scopeGroupIds, assetTagName);
293    
294                            assetEntryQuery.addNotAllTagIdsArray(notAllAssetTagIds);
295                    }
296    
297                    assetEntryQuery.setNotAnyCategoryIds(notAnyAssetCategoryIds);
298    
299                    long[] notAnyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
300                            scopeGroupIds, notAnyAssetTagNames);
301    
302                    assetEntryQuery.setNotAnyTagIds(notAnyAssetTagIds);
303    
304                    return assetEntryQuery;
305            }
306    
307            public static String[] getAssetTagNames(
308                            PortletPreferences portletPreferences, long scopeGroupId)
309                    throws Exception {
310    
311                    String[] allAssetTagNames = new String[0];
312    
313                    for (int i = 0; true; i++) {
314                            String[] queryValues = portletPreferences.getValues(
315                                    "queryValues" + i, null);
316    
317                            if ((queryValues == null) || (queryValues.length == 0)) {
318                                    break;
319                            }
320    
321                            boolean queryContains = GetterUtil.getBoolean(
322                                    portletPreferences.getValue(
323                                            "queryContains" + i, StringPool.BLANK));
324                            boolean queryAndOperator = GetterUtil.getBoolean(
325                                    portletPreferences.getValue(
326                                            "queryAndOperator" + i, StringPool.BLANK));
327                            String queryName = portletPreferences.getValue(
328                                    "queryName" + i, StringPool.BLANK);
329    
330                            if (!Validator.equals(queryName, "assetCategories") &&
331                                    queryContains &&
332                                    (queryAndOperator || (queryValues.length == 1))) {
333    
334                                    allAssetTagNames = queryValues;
335                            }
336                    }
337    
338                    return allAssetTagNames;
339            }
340    
341            public static String getClassName(
342                    AssetRendererFactory assetRendererFactory) {
343    
344                    Class<?> clazz = assetRendererFactory.getClass();
345    
346                    String className = clazz.getName();
347    
348                    int pos = className.lastIndexOf(StringPool.PERIOD);
349    
350                    return className.substring(pos + 1);
351            }
352    
353            public static long[] getClassNameIds(
354                    PortletPreferences portletPreferences, long[] availableClassNameIds) {
355    
356                    boolean anyAssetType = GetterUtil.getBoolean(
357                            portletPreferences.getValue(
358                                    "anyAssetType", Boolean.TRUE.toString()));
359    
360                    if (anyAssetType) {
361                            return availableClassNameIds;
362                    }
363    
364                    long defaultClassNameId = GetterUtil.getLong(
365                            portletPreferences.getValue("anyAssetType", null));
366    
367                    if (defaultClassNameId > 0) {
368                            return new long[] {defaultClassNameId};
369                    }
370    
371                    long[] classNameIds = GetterUtil.getLongValues(
372                            portletPreferences.getValues("classNameIds", null));
373    
374                    if (classNameIds != null) {
375                            return classNameIds;
376                    }
377                    else {
378                            return availableClassNameIds;
379                    }
380            }
381    
382            public static Long[] getClassTypeIds(
383                    PortletPreferences portletPreferences, String className,
384                    Long[] availableClassTypeIds) {
385    
386                    boolean anyAssetType = GetterUtil.getBoolean(
387                            portletPreferences.getValue(
388                                    "anyClassType" + className, Boolean.TRUE.toString()));
389    
390                    if (anyAssetType) {
391                            return availableClassTypeIds;
392                    }
393    
394                    long defaultClassTypeId = GetterUtil.getLong(
395                            portletPreferences.getValue("anyClassType" + className, null));
396    
397                    if (defaultClassTypeId > 0) {
398                            return new Long[] {defaultClassTypeId};
399                    }
400    
401                    Long[] classTypeIds = ArrayUtil.toArray(
402                            StringUtil.split(
403                                    portletPreferences.getValue(
404                                            "classTypeIds" + className, null), 0L));
405    
406                    if (classTypeIds != null) {
407                            return classTypeIds;
408                    }
409                    else {
410                            return availableClassTypeIds;
411                    }
412            }
413    
414            public static long[] getGroupIds(
415                    PortletPreferences portletPreferences, long scopeGroupId,
416                    Layout layout) {
417    
418                    String defaultScopeId = GetterUtil.getString(
419                            portletPreferences.getValue("defaultScope", null));
420    
421                    if (Validator.isNull(defaultScopeId) ||
422                            defaultScopeId.equals(StringPool.FALSE)) {
423    
424                            String[] scopeIds = portletPreferences.getValues(
425                                    "scopeIds",
426                                    new String[] {SCOPE_ID_GROUP_PREFIX + scopeGroupId});
427    
428                            long[] groupIds = new long[scopeIds.length];
429    
430                            int i = 0;
431    
432                            for (String scopeId : scopeIds) {
433                                    try {
434                                            groupIds[i] = _getGroupId(
435                                                    scopeId, scopeGroupId, layout.isPrivateLayout());
436    
437                                            i++;
438                                    }
439                                    catch (Exception e) {
440                                            continue;
441                                    }
442                            }
443    
444                            return groupIds;
445                    }
446    
447                    if (defaultScopeId.equals(StringPool.TRUE)) {
448                            return new long[] {scopeGroupId};
449                    }
450    
451                    try {
452                            long groupId = _getGroupId(
453                                    defaultScopeId, scopeGroupId, layout.isPrivateLayout());
454    
455                            return new long[] {groupId};
456                    }
457                    catch (Exception e) {
458                            return new long[0];
459                    }
460            }
461    
462            public static long getRecentFolderId(
463                    PortletRequest portletRequest, String className) {
464    
465                    Long classPK = _getRecentFolderIds(portletRequest).get(className);
466    
467                    if (classPK == null) {
468                            return 0;
469                    }
470                    else {
471                            return classPK.longValue();
472                    }
473            }
474    
475            public static void removeAndStoreSelection(
476                            List<String> assetEntryUuids, PortletPreferences portletPreferences)
477                    throws Exception {
478    
479                    if (assetEntryUuids.size() == 0) {
480                            return;
481                    }
482    
483                    String[] assetEntryXmls = portletPreferences.getValues(
484                            "assetEntryXml", new String[0]);
485    
486                    List<String> assetEntryXmlsList = ListUtil.fromArray(assetEntryXmls);
487    
488                    Iterator<String> itr = assetEntryXmlsList.iterator();
489    
490                    while (itr.hasNext()) {
491                            String assetEntryXml = itr.next();
492    
493                            Document document = SAXReaderUtil.read(assetEntryXml);
494    
495                            Element rootElement = document.getRootElement();
496    
497                            String assetEntryUuid = rootElement.elementText("asset-entry-uuid");
498    
499                            if (assetEntryUuids.contains(assetEntryUuid)) {
500                                    itr.remove();
501                            }
502                    }
503    
504                    portletPreferences.setValues(
505                            "assetEntryXml",
506                            assetEntryXmlsList.toArray(new String[assetEntryXmlsList.size()]));
507    
508                    portletPreferences.store();
509            }
510    
511            public static void removeRecentFolderId(
512                    PortletRequest portletRequest, String className, long classPK) {
513    
514                    if (getRecentFolderId(portletRequest, className) == classPK) {
515                            _getRecentFolderIds(portletRequest).remove(className);
516                    }
517            }
518    
519            private static String _getAssetEntryXml(
520                    String assetEntryType, String assetEntryUuid) {
521    
522                    String xml = null;
523    
524                    try {
525                            Document document = SAXReaderUtil.createDocument(StringPool.UTF8);
526    
527                            Element assetEntryElement = document.addElement("asset-entry");
528    
529                            Element assetEntryTypeElement = assetEntryElement.addElement(
530                                    "asset-entry-type");
531    
532                            assetEntryTypeElement.addText(assetEntryType);
533    
534                            Element assetEntryUuidElement = assetEntryElement.addElement(
535                                    "asset-entry-uuid");
536    
537                            assetEntryUuidElement.addText(assetEntryUuid);
538    
539                            xml = document.formattedString(StringPool.BLANK);
540                    }
541                    catch (IOException ioe) {
542                            if (_log.isWarnEnabled()) {
543                                    _log.warn(ioe);
544                            }
545                    }
546    
547                    return xml;
548            }
549    
550            private static long _getGroupId(
551                            String scopeId, long scopeGroupId, boolean privateLayout)
552                    throws Exception {
553    
554                    if (scopeId.startsWith(SCOPE_ID_GROUP_PREFIX)) {
555                            String scopeIdSuffix = scopeId.substring(
556                                    SCOPE_ID_GROUP_PREFIX.length());
557    
558                            if (scopeIdSuffix.equals(GroupConstants.DEFAULT)) {
559                                    return scopeGroupId;
560                            }
561    
562                            return GetterUtil.getLong(scopeIdSuffix);
563                    }
564                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_UUID_PREFIX)) {
565                            String layoutUuid = scopeId.substring(
566                                    SCOPE_ID_LAYOUT_UUID_PREFIX.length());
567    
568                            Layout scopeIdLayout =
569                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
570                                            layoutUuid, scopeGroupId, privateLayout);
571    
572                            Group scopeIdGroup = scopeIdLayout.getScopeGroup();
573    
574                            return scopeIdGroup.getGroupId();
575                    }
576                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_PREFIX)) {
577    
578                            // Legacy preferences
579    
580                            String scopeIdSuffix = scopeId.substring(
581                                    SCOPE_ID_LAYOUT_PREFIX.length());
582    
583                            long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
584    
585                            Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
586                                    scopeGroupId, privateLayout, scopeIdLayoutId);
587    
588                            Group scopeIdGroup = scopeIdLayout.getScopeGroup();
589    
590                            return scopeIdGroup.getGroupId();
591                    }
592                    else {
593                            throw new IllegalArgumentException("Invalid scope ID " + scopeId);
594                    }
595            }
596    
597            private static Map<String, Long> _getRecentFolderIds(
598                    PortletRequest portletRequest) {
599    
600                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
601                            portletRequest);
602                    HttpSession session = request.getSession();
603    
604                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
605                            WebKeys.THEME_DISPLAY);
606    
607                    String key =
608                            AssetPublisherUtil.class + StringPool.UNDERLINE +
609                                    themeDisplay.getScopeGroupId();
610    
611                    Map<String, Long> recentFolderIds =
612                            (Map<String, Long>)session.getAttribute(key);
613    
614                    if (recentFolderIds == null) {
615                            recentFolderIds = new HashMap<String, Long>();
616                    }
617    
618                    session.setAttribute(key, recentFolderIds);
619    
620                    return recentFolderIds;
621            }
622    
623            private static Log _log = LogFactoryUtil.getLog(AssetPublisherUtil.class);
624    
625    }