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