001    /**
002     * Copyright (c) 2000-2012 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.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.Property;
020    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021    import com.liferay.portal.kernel.dao.orm.QueryUtil;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.util.Accessor;
027    import com.liferay.portal.kernel.util.ArrayUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.ListUtil;
030    import com.liferay.portal.kernel.util.LocaleUtil;
031    import com.liferay.portal.kernel.util.LocalizationUtil;
032    import com.liferay.portal.kernel.util.ParamUtil;
033    import com.liferay.portal.kernel.util.PrimitiveLongList;
034    import com.liferay.portal.kernel.util.PropsKeys;
035    import com.liferay.portal.kernel.util.PropsUtil;
036    import com.liferay.portal.kernel.util.StringPool;
037    import com.liferay.portal.kernel.util.StringUtil;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.kernel.xml.Document;
040    import com.liferay.portal.kernel.xml.Element;
041    import com.liferay.portal.kernel.xml.SAXReaderUtil;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.model.GroupConstants;
044    import com.liferay.portal.model.Layout;
045    import com.liferay.portal.model.PortletConstants;
046    import com.liferay.portal.model.User;
047    import com.liferay.portal.security.auth.PrincipalThreadLocal;
048    import com.liferay.portal.security.permission.ActionKeys;
049    import com.liferay.portal.security.permission.PermissionChecker;
050    import com.liferay.portal.service.GroupLocalServiceUtil;
051    import com.liferay.portal.service.LayoutLocalServiceUtil;
052    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
053    import com.liferay.portal.service.ServiceContext;
054    import com.liferay.portal.service.ServiceContextFactory;
055    import com.liferay.portal.service.ServiceContextUtil;
056    import com.liferay.portal.service.SubscriptionLocalServiceUtil;
057    import com.liferay.portal.service.permission.GroupPermissionUtil;
058    import com.liferay.portal.service.permission.PortletPermissionUtil;
059    import com.liferay.portal.service.persistence.PortletPreferencesActionableDynamicQuery;
060    import com.liferay.portal.theme.ThemeDisplay;
061    import com.liferay.portal.util.PortalUtil;
062    import com.liferay.portal.util.PortletKeys;
063    import com.liferay.portal.util.PropsValues;
064    import com.liferay.portal.util.SubscriptionSender;
065    import com.liferay.portal.util.WebKeys;
066    import com.liferay.portlet.PortletPreferencesFactoryUtil;
067    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
068    import com.liferay.portlet.asset.model.AssetCategory;
069    import com.liferay.portlet.asset.model.AssetEntry;
070    import com.liferay.portlet.asset.model.AssetRendererFactory;
071    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
072    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
073    import com.liferay.portlet.asset.service.AssetEntryServiceUtil;
074    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
075    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
076    import com.liferay.portlet.expando.model.ExpandoBridge;
077    import com.liferay.portlet.sites.util.SitesUtil;
078    import com.liferay.util.ContentUtil;
079    
080    import java.io.IOException;
081    import java.io.Serializable;
082    
083    import java.util.ArrayList;
084    import java.util.HashMap;
085    import java.util.Iterator;
086    import java.util.List;
087    import java.util.Locale;
088    import java.util.Map;
089    
090    import javax.portlet.PortletException;
091    import javax.portlet.PortletPreferences;
092    import javax.portlet.PortletRequest;
093    
094    import javax.servlet.http.HttpServletRequest;
095    import javax.servlet.http.HttpSession;
096    
097    /**
098     * @author Raymond Augé
099     * @author Julio Camarero
100     */
101    public class AssetPublisherUtil {
102    
103            public static final String SCOPE_ID_CHILD_GROUP_PREFIX = "ChildGroup_";
104    
105            public static final String SCOPE_ID_GROUP_PREFIX = "Group_";
106    
107            public static final String SCOPE_ID_LAYOUT_PREFIX = "Layout_";
108    
109            public static final String SCOPE_ID_LAYOUT_UUID_PREFIX = "LayoutUuid_";
110    
111            public static final String SCOPE_ID_PARENT_GROUP_PREFIX = "ParentGroup_";
112    
113            public static void addAndStoreSelection(
114                            PortletRequest portletRequest, String className, long classPK,
115                            int assetEntryOrder)
116                    throws Exception {
117    
118                    String referringPortletResource = ParamUtil.getString(
119                            portletRequest, "referringPortletResource");
120    
121                    if (Validator.isNull(referringPortletResource)) {
122                            return;
123                    }
124    
125                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
126                            WebKeys.THEME_DISPLAY);
127    
128                    Layout layout = LayoutLocalServiceUtil.getLayout(
129                            themeDisplay.getRefererPlid());
130    
131                    PortletPreferences portletPreferences =
132                            PortletPreferencesFactoryUtil.getPortletSetup(
133                                    themeDisplay.getScopeGroupId(), layout,
134                                    referringPortletResource, null);
135    
136                    String selectionStyle = portletPreferences.getValue(
137                            "selectionStyle", "dynamic");
138    
139                    if (selectionStyle.equals("dynamic")) {
140                            return;
141                    }
142    
143                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
144                            className, classPK);
145    
146                    addSelection(
147                            portletRequest, portletPreferences, referringPortletResource,
148                            assetEntry.getEntryId(), assetEntryOrder, className);
149    
150                    portletPreferences.store();
151            }
152    
153            public static void addRecentFolderId(
154                    PortletRequest portletRequest, String className, long classPK) {
155    
156                    _getRecentFolderIds(portletRequest).put(className, classPK);
157            }
158    
159            public static void addSelection(
160                            PortletRequest portletRequest,
161                            PortletPreferences portletPreferences, String portletId)
162                    throws Exception {
163    
164                    long assetEntryId = ParamUtil.getLong(portletRequest, "assetEntryId");
165                    int assetEntryOrder = ParamUtil.getInteger(
166                            portletRequest, "assetEntryOrder");
167                    String assetEntryType = ParamUtil.getString(
168                            portletRequest, "assetEntryType");
169    
170                    addSelection(
171                            portletRequest, portletPreferences, portletId, assetEntryId,
172                            assetEntryOrder, assetEntryType);
173            }
174    
175            public static void addSelection(
176                            PortletRequest portletRequest,
177                            PortletPreferences portletPreferences, String portletId,
178                            long assetEntryId, int assetEntryOrder, String assetEntryType)
179                    throws Exception {
180    
181                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
182                            assetEntryId);
183    
184                    String[] assetEntryXmls = portletPreferences.getValues(
185                            "assetEntryXml", new String[0]);
186    
187                    String assetEntryXml = _getAssetEntryXml(
188                            assetEntryType, assetEntry.getClassUuid());
189    
190                    if (!ArrayUtil.contains(assetEntryXmls, assetEntryXml)) {
191                            if (assetEntryOrder > -1) {
192                                    assetEntryXmls[assetEntryOrder] = assetEntryXml;
193                            }
194                            else {
195                                    assetEntryXmls = ArrayUtil.append(
196                                            assetEntryXmls, assetEntryXml);
197                            }
198    
199                            portletPreferences.setValues("assetEntryXml", assetEntryXmls);
200                    }
201    
202                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
203                            WebKeys.THEME_DISPLAY);
204    
205                    long plid = themeDisplay.getRefererPlid();
206    
207                    if (plid == 0) {
208                            plid = themeDisplay.getPlid();
209                    }
210    
211                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
212                            AssetEntry.class.getName(), portletRequest);
213    
214                    List<AssetEntry> assetEntries = new ArrayList<AssetEntry>();
215    
216                    assetEntries.add(assetEntry);
217    
218                    notifySubscribers(
219                            ServiceContextUtil.getPortletPreferences(serviceContext), plid,
220                            portletId, assetEntries);
221            }
222    
223            public static void addUserAttributes(
224                            User user, String[] customUserAttributeNames,
225                            AssetEntryQuery assetEntryQuery)
226                    throws Exception {
227    
228                    if ((user == null) || (customUserAttributeNames.length == 0)) {
229                            return;
230                    }
231    
232                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
233                            user.getCompanyId());
234    
235                    long[] allCategoryIds = assetEntryQuery.getAllCategoryIds();
236    
237                    PrimitiveLongList allCategoryIdsList = new PrimitiveLongList(
238                            allCategoryIds.length + customUserAttributeNames.length);
239    
240                    allCategoryIdsList.addAll(allCategoryIds);
241    
242                    for (String customUserAttributeName : customUserAttributeNames) {
243                            ExpandoBridge userCustomAttributes = user.getExpandoBridge();
244    
245                            Serializable userCustomFieldValue =
246                                    userCustomAttributes.getAttribute(customUserAttributeName);
247    
248                            if (userCustomFieldValue == null) {
249                                    continue;
250                            }
251    
252                            String userCustomFieldValueString = userCustomFieldValue.toString();
253    
254                            List<AssetCategory> assetCategories =
255                                    AssetCategoryLocalServiceUtil.search(
256                                            companyGroup.getGroupId(), userCustomFieldValueString,
257                                            new String[0], QueryUtil.ALL_POS, QueryUtil.ALL_POS);
258    
259                            for (AssetCategory assetCategory : assetCategories) {
260                                    allCategoryIdsList.add(assetCategory.getCategoryId());
261                            }
262                    }
263    
264                    assetEntryQuery.setAllCategoryIds(allCategoryIdsList.getArray());
265            }
266    
267            public static void checkAssetEntries() throws Exception {
268                    ActionableDynamicQuery actionableDynamicQuery =
269                            new PortletPreferencesActionableDynamicQuery() {
270    
271                            @Override
272                            protected void addCriteria(DynamicQuery dynamicQuery) {
273                                    Property property = PropertyFactoryUtil.forName("portletId");
274    
275                                    String portletId =
276                                            PortletKeys.ASSET_PUBLISHER +
277                                                    PortletConstants.INSTANCE_SEPARATOR +
278                                                            StringPool.PERCENT;
279    
280                                    dynamicQuery.add(property.like(portletId));
281                            }
282    
283                            @Override
284                            protected void performAction(Object object)
285                                    throws PortalException, SystemException {
286    
287                                    com.liferay.portal.model.PortletPreferences portletPreferences =
288                                            (com.liferay.portal.model.PortletPreferences)object;
289    
290                                    _checkAssetEntries(portletPreferences);
291                            }
292    
293                    };
294    
295                    actionableDynamicQuery.performActions();
296            }
297    
298            public static List<AssetEntry> getAssetEntries(
299                            PortletPreferences preferences, Layout layout, long scopeGroupId,
300                            boolean checkPermission)
301                    throws PortalException, SystemException {
302    
303                    AssetEntryQuery assetEntryQuery = getAssetEntryQuery(
304                            preferences, new long[] {scopeGroupId});
305    
306                    boolean anyAssetType = GetterUtil.getBoolean(
307                            preferences.getValue("anyAssetType", null), true);
308    
309                    if (!anyAssetType) {
310                            long[] availableClassNameIds =
311                                    AssetRendererFactoryRegistryUtil.getClassNameIds();
312    
313                            long[] classNameIds = getClassNameIds(
314                                    preferences, availableClassNameIds);
315    
316                            assetEntryQuery.setClassNameIds(classNameIds);
317                    }
318    
319                    long[] classTypeIds = GetterUtil.getLongValues(
320                            preferences.getValues("classTypeIds", null));
321    
322                    assetEntryQuery.setClassTypeIds(classTypeIds);
323    
324                    boolean enablePermissions = GetterUtil.getBoolean(
325                            preferences.getValue("enablePermissions", null));
326    
327                    assetEntryQuery.setEnablePermissions(enablePermissions);
328    
329                    int rssDelta = GetterUtil.getInteger(
330                            preferences.getValue("rssDelta", "20"));
331    
332                    assetEntryQuery.setEnd(rssDelta);
333    
334                    boolean excludeZeroViewCount = GetterUtil.getBoolean(
335                            preferences.getValue("excludeZeroViewCount", null));
336    
337                    assetEntryQuery.setExcludeZeroViewCount(excludeZeroViewCount);
338    
339                    long[] groupIds = getGroupIds(preferences, scopeGroupId, layout);
340    
341                    assetEntryQuery.setGroupIds(groupIds);
342    
343                    boolean showOnlyLayoutAssets = GetterUtil.getBoolean(
344                            preferences.getValue("showOnlyLayoutAssets", null));
345    
346                    if (showOnlyLayoutAssets) {
347                            assetEntryQuery.setLayout(layout);
348                    }
349    
350                    String orderByColumn1 = GetterUtil.getString(
351                            preferences.getValue("orderByColumn1", "modifiedDate"));
352    
353                    assetEntryQuery.setOrderByCol1(orderByColumn1);
354    
355                    String orderByColumn2 = GetterUtil.getString(
356                            preferences.getValue("orderByColumn2", "title"));
357    
358                    assetEntryQuery.setOrderByCol2(orderByColumn2);
359    
360                    String orderByType1 = GetterUtil.getString(
361                            preferences.getValue("orderByType1", "DESC"));
362    
363                    assetEntryQuery.setOrderByType1(orderByType1);
364    
365                    String orderByType2 = GetterUtil.getString(
366                            preferences.getValue("orderByType2", "ASC"));
367    
368                    assetEntryQuery.setOrderByType2(orderByType2);
369    
370                    assetEntryQuery.setStart(0);
371    
372                    if (checkPermission) {
373                            return AssetEntryServiceUtil.getEntries(assetEntryQuery);
374                    }
375                    else {
376                            return AssetEntryLocalServiceUtil.getEntries(assetEntryQuery);
377                    }
378            }
379    
380            public static AssetEntryQuery getAssetEntryQuery(
381                            PortletPreferences portletPreferences, long[] scopeGroupIds)
382                    throws PortalException, SystemException {
383    
384                    AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
385    
386                    long[] allAssetCategoryIds = new long[0];
387                    long[] anyAssetCategoryIds = new long[0];
388                    long[] notAllAssetCategoryIds = new long[0];
389                    long[] notAnyAssetCategoryIds = new long[0];
390    
391                    String[] allAssetTagNames = new String[0];
392                    String[] anyAssetTagNames = new String[0];
393                    String[] notAllAssetTagNames = new String[0];
394                    String[] notAnyAssetTagNames = new String[0];
395    
396                    for (int i = 0; true; i++) {
397                            String[] queryValues = portletPreferences.getValues(
398                                    "queryValues" + i, null);
399    
400                            if ((queryValues == null) || (queryValues.length == 0)) {
401                                    break;
402                            }
403    
404                            boolean queryContains = GetterUtil.getBoolean(
405                                    portletPreferences.getValue(
406                                            "queryContains" + i, StringPool.BLANK));
407                            boolean queryAndOperator = GetterUtil.getBoolean(
408                                    portletPreferences.getValue(
409                                            "queryAndOperator" + i, StringPool.BLANK));
410                            String queryName = portletPreferences.getValue(
411                                    "queryName" + i, StringPool.BLANK);
412    
413                            if (Validator.equals(queryName, "assetCategories")) {
414                                    long[] assetCategoryIds = GetterUtil.getLongValues(queryValues);
415    
416                                    if (queryContains &&
417                                            (queryAndOperator || (assetCategoryIds.length == 1))) {
418    
419                                            allAssetCategoryIds = assetCategoryIds;
420                                    }
421                                    else if (queryContains && !queryAndOperator) {
422                                            anyAssetCategoryIds = assetCategoryIds;
423                                    }
424                                    else if (!queryContains && queryAndOperator) {
425                                            notAllAssetCategoryIds = assetCategoryIds;
426                                    }
427                                    else {
428                                            notAnyAssetCategoryIds = assetCategoryIds;
429                                    }
430                            }
431                            else {
432                                    if (queryContains && queryAndOperator) {
433                                            allAssetTagNames = queryValues;
434                                    }
435                                    else if (queryContains && !queryAndOperator) {
436                                            anyAssetTagNames = queryValues;
437                                    }
438                                    else if (!queryContains && queryAndOperator) {
439                                            notAllAssetTagNames = queryValues;
440                                    }
441                                    else {
442                                            notAnyAssetTagNames = queryValues;
443                                    }
444                            }
445                    }
446    
447                    assetEntryQuery.setAllCategoryIds(allAssetCategoryIds);
448    
449                    for (String assetTagName : allAssetTagNames) {
450                            long[] allAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
451                                    scopeGroupIds, assetTagName);
452    
453                            assetEntryQuery.addAllTagIdsArray(allAssetTagIds);
454                    }
455    
456                    assetEntryQuery.setAnyCategoryIds(anyAssetCategoryIds);
457    
458                    long[] anyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
459                            scopeGroupIds, anyAssetTagNames);
460    
461                    assetEntryQuery.setAnyTagIds(anyAssetTagIds);
462    
463                    assetEntryQuery.setNotAllCategoryIds(notAllAssetCategoryIds);
464    
465                    for (String assetTagName : notAllAssetTagNames) {
466                            long[] notAllAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
467                                    scopeGroupIds, assetTagName);
468    
469                            assetEntryQuery.addNotAllTagIdsArray(notAllAssetTagIds);
470                    }
471    
472                    assetEntryQuery.setNotAnyCategoryIds(notAnyAssetCategoryIds);
473    
474                    long[] notAnyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
475                            scopeGroupIds, notAnyAssetTagNames);
476    
477                    assetEntryQuery.setNotAnyTagIds(notAnyAssetTagIds);
478    
479                    return assetEntryQuery;
480            }
481    
482            public static String[] getAssetTagNames(
483                            PortletPreferences portletPreferences, long scopeGroupId)
484                    throws Exception {
485    
486                    String[] allAssetTagNames = new String[0];
487    
488                    for (int i = 0; true; i++) {
489                            String[] queryValues = portletPreferences.getValues(
490                                    "queryValues" + i, null);
491    
492                            if ((queryValues == null) || (queryValues.length == 0)) {
493                                    break;
494                            }
495    
496                            boolean queryContains = GetterUtil.getBoolean(
497                                    portletPreferences.getValue(
498                                            "queryContains" + i, StringPool.BLANK));
499                            boolean queryAndOperator = GetterUtil.getBoolean(
500                                    portletPreferences.getValue(
501                                            "queryAndOperator" + i, StringPool.BLANK));
502                            String queryName = portletPreferences.getValue(
503                                    "queryName" + i, StringPool.BLANK);
504    
505                            if (!Validator.equals(queryName, "assetCategories") &&
506                                    queryContains &&
507                                    (queryAndOperator || (queryValues.length == 1))) {
508    
509                                    allAssetTagNames = queryValues;
510                            }
511                    }
512    
513                    return allAssetTagNames;
514            }
515    
516            public static String getClassName(
517                    AssetRendererFactory assetRendererFactory) {
518    
519                    Class<?> clazz = assetRendererFactory.getClass();
520    
521                    String className = clazz.getName();
522    
523                    int pos = className.lastIndexOf(StringPool.PERIOD);
524    
525                    return className.substring(pos + 1);
526            }
527    
528            public static long[] getClassNameIds(
529                    PortletPreferences portletPreferences, long[] availableClassNameIds) {
530    
531                    boolean anyAssetType = GetterUtil.getBoolean(
532                            portletPreferences.getValue(
533                                    "anyAssetType", Boolean.TRUE.toString()));
534    
535                    if (anyAssetType) {
536                            return availableClassNameIds;
537                    }
538    
539                    long defaultClassNameId = GetterUtil.getLong(
540                            portletPreferences.getValue("anyAssetType", null));
541    
542                    if (defaultClassNameId > 0) {
543                            return new long[] {defaultClassNameId};
544                    }
545    
546                    long[] classNameIds = GetterUtil.getLongValues(
547                            portletPreferences.getValues("classNameIds", null));
548    
549                    if (classNameIds != null) {
550                            return classNameIds;
551                    }
552                    else {
553                            return availableClassNameIds;
554                    }
555            }
556    
557            public static Long[] getClassTypeIds(
558                    PortletPreferences portletPreferences, String className,
559                    Long[] availableClassTypeIds) {
560    
561                    boolean anyAssetType = GetterUtil.getBoolean(
562                            portletPreferences.getValue(
563                                    "anyClassType" + className, Boolean.TRUE.toString()));
564    
565                    if (anyAssetType) {
566                            return availableClassTypeIds;
567                    }
568    
569                    long defaultClassTypeId = GetterUtil.getLong(
570                            portletPreferences.getValue("anyClassType" + className, null));
571    
572                    if (defaultClassTypeId > 0) {
573                            return new Long[] {defaultClassTypeId};
574                    }
575    
576                    Long[] classTypeIds = ArrayUtil.toArray(
577                            StringUtil.split(
578                                    portletPreferences.getValue(
579                                            "classTypeIds" + className, null), 0L));
580    
581                    if (classTypeIds != null) {
582                            return classTypeIds;
583                    }
584                    else {
585                            return availableClassTypeIds;
586                    }
587            }
588    
589            public static Map<Locale, String> getEmailAssetEntryAddedBodyMap(
590                    PortletPreferences preferences) {
591    
592                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
593                            preferences, "emailAssetEntryAddedBody");
594    
595                    Locale defaultLocale = LocaleUtil.getDefault();
596    
597                    String defaultValue = map.get(defaultLocale);
598    
599                    if (Validator.isNotNull(defaultValue)) {
600                            return map;
601                    }
602    
603                    map.put(
604                            defaultLocale,
605                            ContentUtil.get(
606                                    PropsUtil.get(
607                                            PropsKeys.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_BODY)));
608    
609                    return map;
610            }
611    
612            public static boolean getEmailAssetEntryAddedEnabled(
613                    PortletPreferences preferences) {
614    
615                    String emailAssetEntryAddedEnabled = preferences.getValue(
616                            "emailAssetEntryAddedEnabled", StringPool.BLANK);
617    
618                    if (Validator.isNotNull(emailAssetEntryAddedEnabled)) {
619                            return GetterUtil.getBoolean(emailAssetEntryAddedEnabled);
620                    }
621                    else {
622                            return PropsValues.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_ENABLED;
623                    }
624            }
625    
626            public static Map<Locale, String> getEmailAssetEntryAddedSubjectMap(
627                    PortletPreferences preferences) {
628    
629                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
630                            preferences, "emailAssetEntryAddedSubject");
631    
632                    Locale defaultLocale = LocaleUtil.getDefault();
633    
634                    String defaultValue = map.get(defaultLocale);
635    
636                    if (Validator.isNotNull(defaultValue)) {
637                            return map;
638                    }
639    
640                    map.put(
641                            defaultLocale,
642                            ContentUtil.get(
643                                    PropsUtil.get(
644                                            PropsKeys.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_SUBJECT))
645                    );
646    
647                    return map;
648            }
649    
650            public static String getEmailFromAddress(
651                            PortletPreferences preferences, long companyId)
652                    throws SystemException {
653    
654                    return PortalUtil.getEmailFromAddress(
655                            preferences, companyId,
656                            PropsValues.ASSET_PUBLISHER_EMAIL_FROM_ADDRESS);
657            }
658    
659            public static String getEmailFromName(
660                            PortletPreferences preferences, long companyId)
661                    throws SystemException {
662    
663                    return PortalUtil.getEmailFromName(
664                            preferences, companyId,
665                            PropsValues.ASSET_PUBLISHER_EMAIL_FROM_NAME);
666            }
667    
668            public static long getGroupIdFromScopeId(
669                            String scopeId, long siteGroupId, boolean privateLayout)
670                    throws PortalException, SystemException {
671    
672                    if (scopeId.startsWith(SCOPE_ID_CHILD_GROUP_PREFIX)) {
673                            String scopeIdSuffix = scopeId.substring(
674                                    SCOPE_ID_CHILD_GROUP_PREFIX.length());
675    
676                            return GetterUtil.getLong(scopeIdSuffix);
677                    }
678                    else if (scopeId.startsWith(SCOPE_ID_GROUP_PREFIX)) {
679                            String scopeIdSuffix = scopeId.substring(
680                                    SCOPE_ID_GROUP_PREFIX.length());
681    
682                            if (scopeIdSuffix.equals(GroupConstants.DEFAULT)) {
683                                    return siteGroupId;
684                            }
685    
686                            return GetterUtil.getLong(scopeIdSuffix);
687                    }
688                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_UUID_PREFIX)) {
689                            String layoutUuid = scopeId.substring(
690                                    SCOPE_ID_LAYOUT_UUID_PREFIX.length());
691    
692                            Layout scopeIdLayout =
693                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
694                                            layoutUuid, siteGroupId, privateLayout);
695    
696                            Group scopeIdGroup = null;
697    
698                            if (scopeIdLayout.hasScopeGroup()) {
699                                    scopeIdGroup = scopeIdLayout.getScopeGroup();
700                            }
701                            else {
702                                    scopeIdGroup = GroupLocalServiceUtil.addGroup(
703                                            PrincipalThreadLocal.getUserId(),
704                                            GroupConstants.DEFAULT_PARENT_GROUP_ID,
705                                            Layout.class.getName(), scopeIdLayout.getPlid(),
706                                            GroupConstants.DEFAULT_LIVE_GROUP_ID,
707                                            String.valueOf(scopeIdLayout.getPlid()), null, 0, null,
708                                            false, true, null);
709                            }
710    
711                            return scopeIdGroup.getGroupId();
712                    }
713                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_PREFIX)) {
714    
715                            // Legacy preferences
716    
717                            String scopeIdSuffix = scopeId.substring(
718                                    SCOPE_ID_LAYOUT_PREFIX.length());
719    
720                            long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
721    
722                            Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
723                                    siteGroupId, privateLayout, scopeIdLayoutId);
724    
725                            Group scopeIdGroup = scopeIdLayout.getScopeGroup();
726    
727                            return scopeIdGroup.getGroupId();
728                    }
729                    else if (scopeId.startsWith(SCOPE_ID_PARENT_GROUP_PREFIX)) {
730                            String scopeIdSuffix = scopeId.substring(
731                                    SCOPE_ID_PARENT_GROUP_PREFIX.length());
732    
733                            return GetterUtil.getLong(scopeIdSuffix);
734                    }
735                    else {
736                            throw new IllegalArgumentException("Invalid scope ID " + scopeId);
737                    }
738            }
739    
740            public static long[] getGroupIds(
741                    PortletPreferences portletPreferences, long scopeGroupId,
742                    Layout layout) {
743    
744                    String[] scopeIds = portletPreferences.getValues(
745                            "scopeIds", new String[] {SCOPE_ID_GROUP_PREFIX + scopeGroupId});
746    
747                    long[] groupIds = new long[scopeIds.length];
748    
749                    int i = 0;
750    
751                    for (String scopeId : scopeIds) {
752                            try {
753                                    groupIds[i] = getGroupIdFromScopeId(
754                                            scopeId, scopeGroupId, layout.isPrivateLayout());
755    
756                                    i++;
757                            }
758                            catch (Exception e) {
759                                    continue;
760                            }
761                    }
762    
763                    return groupIds;
764            }
765    
766            public static long getRecentFolderId(
767                    PortletRequest portletRequest, String className) {
768    
769                    Long classPK = _getRecentFolderIds(portletRequest).get(className);
770    
771                    if (classPK == null) {
772                            return 0;
773                    }
774                    else {
775                            return classPK.longValue();
776                    }
777            }
778    
779            public static String getScopeId(Group group, long scopeGroupId)
780                    throws PortalException, SystemException {
781    
782                    String key = null;
783    
784                    if (group.isLayout()) {
785                            Layout layout = LayoutLocalServiceUtil.getLayout(
786                                    group.getClassPK());
787    
788                            key = SCOPE_ID_LAYOUT_UUID_PREFIX + layout.getUuid();
789                    }
790                    else if (group.isLayoutPrototype() ||
791                                    (group.getGroupId() == scopeGroupId)) {
792    
793                            key = SCOPE_ID_GROUP_PREFIX + GroupConstants.DEFAULT;
794                    }
795                    else {
796                            Group scopeGroup = GroupLocalServiceUtil.getGroup(scopeGroupId);
797    
798                            if (scopeGroup.hasAncestor(group.getGroupId())) {
799                                    key = SCOPE_ID_PARENT_GROUP_PREFIX + group.getGroupId();
800                            }
801                            else if (group.hasAncestor(scopeGroup.getGroupId())) {
802                                    key = SCOPE_ID_CHILD_GROUP_PREFIX + group.getGroupId();
803                            }
804                            else {
805                                    key = SCOPE_ID_GROUP_PREFIX + group.getGroupId();
806                            }
807                    }
808    
809                    return key;
810            }
811    
812            public static boolean isScopeIdSelectable(
813                            PermissionChecker permissionChecker, String scopeId,
814                            long companyGroupId, Layout layout)
815                    throws PortalException, SystemException {
816    
817                    long groupId = AssetPublisherUtil.getGroupIdFromScopeId(
818                            scopeId, layout.getGroupId(), layout.isPrivateLayout());
819    
820                    if (scopeId.startsWith(
821                                    AssetPublisherUtil.SCOPE_ID_CHILD_GROUP_PREFIX)) {
822    
823                            Group group = GroupLocalServiceUtil.getGroup(groupId);
824    
825                            if (!group.hasAncestor(layout.getGroupId())) {
826                                    return false;
827                            }
828                    }
829                    else if (scopeId.startsWith(
830                                            AssetPublisherUtil.SCOPE_ID_PARENT_GROUP_PREFIX)) {
831    
832                            Group siteGroup = layout.getGroup();
833    
834                            if (!siteGroup.hasAncestor(groupId)) {
835                                    return false;
836                            }
837    
838                            if (!SitesUtil.isContentSharingWithChildrenEnabled(siteGroup)) {
839                                    return GroupPermissionUtil.contains(
840                                            permissionChecker, groupId, ActionKeys.UPDATE);
841                            }
842                    }
843                    else if (groupId != companyGroupId) {
844                            return GroupPermissionUtil.contains(
845                                    permissionChecker, groupId, ActionKeys.UPDATE);
846                    }
847    
848                    return true;
849            }
850    
851            public static boolean isSubscribed(
852                            long companyId, long userId, long plid, String portletId)
853                    throws PortalException, SystemException {
854    
855                    return SubscriptionLocalServiceUtil.isSubscribed(
856                            companyId, userId,
857                            com.liferay.portal.model.PortletPreferences.class.getName(),
858                            _getPortletPreferencesId(plid, portletId));
859            }
860    
861            public static void notifySubscribers(
862                            PortletPreferences preferences, long plid, String portletId,
863                            List<AssetEntry> assetEntries)
864                    throws PortalException, SystemException {
865    
866                    if (!getEmailAssetEntryAddedEnabled(preferences) ||
867                            assetEntries.isEmpty()) {
868    
869                            return;
870                    }
871    
872                    AssetEntry assetEntry = assetEntries.get(0);
873    
874                    String fromName = getEmailFromName(
875                            preferences, assetEntry.getCompanyId());
876                    String fromAddress = getEmailFromAddress(
877                            preferences, assetEntry.getCompanyId());
878    
879                    Map<Locale, String> localizedSubjectMap =
880                            getEmailAssetEntryAddedSubjectMap(preferences);
881                    Map<Locale, String> localizedBodyMap = getEmailAssetEntryAddedBodyMap(
882                            preferences);
883    
884                    SubscriptionSender subscriptionSender = new SubscriptionSender();
885    
886                    subscriptionSender.setCompanyId(assetEntry.getCompanyId());
887                    subscriptionSender.setContextAttributes(
888                            "[$ASSET_ENTRIES$]",
889                            ListUtil.toString(
890                                    assetEntries, _titleAccessor, StringPool.COMMA_AND_SPACE));
891                    subscriptionSender.setContextUserPrefix("ASSET_PUBLISHER");
892                    subscriptionSender.setFrom(fromAddress, fromName);
893                    subscriptionSender.setHtmlFormat(true);
894                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
895                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
896                    subscriptionSender.setMailId("asset_entry", assetEntry.getEntryId());
897                    subscriptionSender.setPortletId(PortletKeys.ASSET_PUBLISHER);
898                    subscriptionSender.setReplyToAddress(fromAddress);
899    
900                    subscriptionSender.addPersistedSubscribers(
901                            com.liferay.portal.model.PortletPreferences.class.getName(),
902                            _getPortletPreferencesId(plid, portletId));
903    
904                    subscriptionSender.flushNotificationsAsync();
905            }
906    
907            public static void removeAndStoreSelection(
908                            List<String> assetEntryUuids, PortletPreferences portletPreferences)
909                    throws Exception {
910    
911                    if (assetEntryUuids.size() == 0) {
912                            return;
913                    }
914    
915                    String[] assetEntryXmls = portletPreferences.getValues(
916                            "assetEntryXml", new String[0]);
917    
918                    List<String> assetEntryXmlsList = ListUtil.fromArray(assetEntryXmls);
919    
920                    Iterator<String> itr = assetEntryXmlsList.iterator();
921    
922                    while (itr.hasNext()) {
923                            String assetEntryXml = itr.next();
924    
925                            Document document = SAXReaderUtil.read(assetEntryXml);
926    
927                            Element rootElement = document.getRootElement();
928    
929                            String assetEntryUuid = rootElement.elementText("asset-entry-uuid");
930    
931                            if (assetEntryUuids.contains(assetEntryUuid)) {
932                                    itr.remove();
933                            }
934                    }
935    
936                    portletPreferences.setValues(
937                            "assetEntryXml",
938                            assetEntryXmlsList.toArray(new String[assetEntryXmlsList.size()]));
939    
940                    portletPreferences.store();
941            }
942    
943            public static void removeRecentFolderId(
944                    PortletRequest portletRequest, String className, long classPK) {
945    
946                    if (getRecentFolderId(portletRequest, className) == classPK) {
947                            _getRecentFolderIds(portletRequest).remove(className);
948                    }
949            }
950    
951            public static void subscribe(
952                            PermissionChecker permissionChecker, long groupId, long plid,
953                            String portletId)
954                    throws PortalException, SystemException {
955    
956                    PortletPermissionUtil.check(
957                            permissionChecker, plid, portletId, ActionKeys.SUBSCRIBE);
958    
959                    SubscriptionLocalServiceUtil.addSubscription(
960                            permissionChecker.getUserId(), groupId,
961                            com.liferay.portal.model.PortletPreferences.class.getName(),
962                            _getPortletPreferencesId(plid, portletId));
963            }
964    
965            public static void unsubscribe(
966                            PermissionChecker permissionChecker, long plid, String portletId)
967                    throws PortalException, SystemException {
968    
969                    PortletPermissionUtil.check(
970                            permissionChecker, plid, portletId, ActionKeys.SUBSCRIBE);
971    
972                    SubscriptionLocalServiceUtil.deleteSubscription(
973                            permissionChecker.getUserId(),
974                            com.liferay.portal.model.PortletPreferences.class.getName(),
975                            _getPortletPreferencesId(plid, portletId));
976            }
977    
978            private static void _checkAssetEntries(
979                            com.liferay.portal.model.PortletPreferences portletPreferences)
980                    throws PortalException, SystemException {
981    
982                    Layout layout = LayoutLocalServiceUtil.getLayout(
983                            portletPreferences.getPlid());
984    
985                    PortletPreferences preferences = PortletPreferencesFactoryUtil.fromXML(
986                            layout.getCompanyId(), portletPreferences.getOwnerId(),
987                            portletPreferences.getOwnerType(), portletPreferences.getPlid(),
988                            portletPreferences.getPortletId(),
989                            portletPreferences.getPreferences());
990    
991                    if (!getEmailAssetEntryAddedEnabled(preferences)) {
992                            return;
993                    }
994    
995                    List<AssetEntry> assetEntries = getAssetEntries(
996                            preferences, layout, layout.getGroupId(), false);
997    
998                    if (assetEntries.isEmpty()) {
999                            return;
1000                    }
1001    
1002                    long[] notifiedAssetEntryIds = GetterUtil.getLongValues(
1003                            preferences.getValues("notifiedAssetEntryIds", null));
1004    
1005                    List<AssetEntry> newAssetEntries = new ArrayList<AssetEntry>();
1006    
1007                    for (int i = 0; i < assetEntries.size(); i++) {
1008                            AssetEntry assetEntry = assetEntries.get(i);
1009    
1010                            if (!ArrayUtil.contains(
1011                                            notifiedAssetEntryIds, assetEntry.getEntryId())) {
1012    
1013                                    newAssetEntries.add(assetEntry);
1014                            }
1015                    }
1016    
1017                    notifySubscribers(
1018                            preferences, portletPreferences.getPlid(),
1019                            portletPreferences.getPortletId(), newAssetEntries);
1020    
1021                    try {
1022                            preferences.setValues(
1023                                    "notifiedAssetEntryIds",
1024                                    StringUtil.split(
1025                                            ListUtil.toString(
1026                                                    assetEntries, AssetEntry.ENTRY_ID_ACCESSOR)));
1027    
1028                            preferences.store();
1029                    }
1030                    catch (IOException ioe) {
1031                            throw new SystemException(ioe);
1032                    }
1033                    catch (PortletException pe) {
1034                            throw new SystemException(pe);
1035                    }
1036            }
1037    
1038            private static String _getAssetEntryXml(
1039                    String assetEntryType, String assetEntryUuid) {
1040    
1041                    String xml = null;
1042    
1043                    try {
1044                            Document document = SAXReaderUtil.createDocument(StringPool.UTF8);
1045    
1046                            Element assetEntryElement = document.addElement("asset-entry");
1047    
1048                            Element assetEntryTypeElement = assetEntryElement.addElement(
1049                                    "asset-entry-type");
1050    
1051                            assetEntryTypeElement.addText(assetEntryType);
1052    
1053                            Element assetEntryUuidElement = assetEntryElement.addElement(
1054                                    "asset-entry-uuid");
1055    
1056                            assetEntryUuidElement.addText(assetEntryUuid);
1057    
1058                            xml = document.formattedString(StringPool.BLANK);
1059                    }
1060                    catch (IOException ioe) {
1061                            if (_log.isWarnEnabled()) {
1062                                    _log.warn(ioe);
1063                            }
1064                    }
1065    
1066                    return xml;
1067            }
1068    
1069            private static long _getPortletPreferencesId(long plid, String portletId)
1070                    throws PortalException, SystemException {
1071    
1072                    com.liferay.portal.model.PortletPreferences portletPreferences =
1073                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1074                                    PortletKeys.PREFS_OWNER_ID_DEFAULT,
1075                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, plid, portletId);
1076    
1077                    return portletPreferences.getPortletPreferencesId();
1078            }
1079    
1080            private static Map<String, Long> _getRecentFolderIds(
1081                    PortletRequest portletRequest) {
1082    
1083                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
1084                            portletRequest);
1085                    HttpSession session = request.getSession();
1086    
1087                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1088                            WebKeys.THEME_DISPLAY);
1089    
1090                    String key =
1091                            AssetPublisherUtil.class + StringPool.UNDERLINE +
1092                                    themeDisplay.getScopeGroupId();
1093    
1094                    Map<String, Long> recentFolderIds =
1095                            (Map<String, Long>)session.getAttribute(key);
1096    
1097                    if (recentFolderIds == null) {
1098                            recentFolderIds = new HashMap<String, Long>();
1099                    }
1100    
1101                    session.setAttribute(key, recentFolderIds);
1102    
1103                    return recentFolderIds;
1104            }
1105    
1106            private static Log _log = LogFactoryUtil.getLog(AssetPublisherUtil.class);
1107    
1108            private static Accessor<AssetEntry, String> _titleAccessor =
1109                    new Accessor<AssetEntry, String>() {
1110    
1111                            public String get(AssetEntry assetEntry) {
1112                                    return assetEntry.getTitle(LocaleUtil.getDefault());
1113                            }
1114    
1115                    };
1116    
1117    }