com.liferay.asset.publisher.web.internal.messaging.AssetEntriesCheckerUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.asset.publisher.web.internal.messaging.AssetEntriesCheckerUtil.java

Source

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.asset.publisher.web.internal.messaging;

import aQute.bnd.annotation.ProviderType;

import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.service.persistence.AssetEntryQuery;
import com.liferay.asset.publisher.web.configuration.AssetPublisherWebConfiguration;
import com.liferay.asset.publisher.web.constants.AssetPublisherPortletKeys;
import com.liferay.asset.publisher.web.internal.util.AssetPublisherWebUtil;
import com.liferay.asset.publisher.web.util.AssetPublisherUtil;
import com.liferay.asset.util.AssetHelper;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.module.configuration.ConfigurationProvider;
import com.liferay.portal.kernel.portlet.PortletIdCodec;
import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil;
import com.liferay.portal.kernel.search.BaseModelSearchResult;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchContextFactory;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionCheckerFactoryUtil;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.service.PortletPreferencesLocalService;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.util.Accessor;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.LocaleThreadLocal;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.SubscriptionSender;
import com.liferay.portal.kernel.util.TimeZoneThreadLocal;
import com.liferay.portlet.asset.service.permission.AssetEntryPermission;
import com.liferay.portlet.configuration.kernel.util.PortletConfigurationUtil;
import com.liferay.subscription.model.Subscription;
import com.liferay.subscription.service.SubscriptionLocalService;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Eudaldo Alonso
 */
@Component(configurationPid = "com.liferay.asset.publisher.web.configuration.AssetPublisherWebConfiguration", immediate = true, service = AssetEntriesCheckerUtil.class)
@ProviderType
public class AssetEntriesCheckerUtil {

    public void checkAssetEntries() throws Exception {
        ActionableDynamicQuery actionableDynamicQuery = _portletPreferencesLocalService.getActionableDynamicQuery();

        actionableDynamicQuery.setAddCriteriaMethod(new ActionableDynamicQuery.AddCriteriaMethod() {

            @Override
            public void addCriteria(DynamicQuery dynamicQuery) {
                Property property = PropertyFactoryUtil.forName("portletId");

                dynamicQuery.add(property.like(
                        PortletIdCodec.encode(AssetPublisherPortletKeys.ASSET_PUBLISHER, StringPool.PERCENT)));
            }

        });
        actionableDynamicQuery.setPerformActionMethod(
                new ActionableDynamicQuery.PerformActionMethod<com.liferay.portal.kernel.model.PortletPreferences>() {

                    @Override
                    public void performAction(com.liferay.portal.kernel.model.PortletPreferences portletPreferences)
                            throws PortalException {

                        _checkAssetEntries(portletPreferences);
                    }

                });

        actionableDynamicQuery.performActions();
    }

    @Reference(unbind = "-")
    protected void setAssetPublisherWebUtil(AssetPublisherWebUtil assetPublisherWebUtil) {

        _assetPublisherWebUtil = assetPublisherWebUtil;
    }

    @Reference(unbind = "-")
    protected void setLayoutLocalService(LayoutLocalService layoutLocalService) {

        _layoutLocalService = layoutLocalService;
    }

    @Reference(unbind = "-")
    protected void setPortletPreferencesLocalService(
            PortletPreferencesLocalService portletPreferencesLocalService) {

        _portletPreferencesLocalService = portletPreferencesLocalService;
    }

    @Reference(unbind = "-")
    protected void setSubscriptionLocalService(SubscriptionLocalService subscriptionLocalService) {

        _subscriptionLocalService = subscriptionLocalService;
    }

    @Reference(unbind = "-")
    protected void setUserLocalService(UserLocalService userLocalService) {
        _userLocalService = userLocalService;
    }

    private static List<AssetEntry> _filterAssetEntries(long userId, List<AssetEntry> assetEntries) {

        User user = _userLocalService.fetchUser(userId);

        if (user == null) {
            return Collections.emptyList();
        }

        PermissionChecker permissionChecker = null;

        try {
            permissionChecker = PermissionCheckerFactoryUtil.create(user);
        } catch (Exception e) {
            return Collections.emptyList();
        }

        List<AssetEntry> filteredAssetEntries = new ArrayList<>();

        for (AssetEntry assetEntry : assetEntries) {
            try {
                if (AssetEntryPermission.contains(permissionChecker, assetEntry, ActionKeys.VIEW)) {

                    filteredAssetEntries.add(assetEntry);
                }
            } catch (Exception e) {
                continue;
            }
        }

        return filteredAssetEntries;
    }

    private static SubscriptionSender _getSubscriptionSender(PortletPreferences portletPreferences,
            List<AssetEntry> assetEntries) {

        if (assetEntries.isEmpty()) {
            return null;
        }

        AssetEntry assetEntry = assetEntries.get(0);

        String fromName = _assetPublisherWebUtil.getEmailFromName(portletPreferences, assetEntry.getCompanyId());
        String fromAddress = _assetPublisherWebUtil.getEmailFromAddress(portletPreferences,
                assetEntry.getCompanyId());

        Map<Locale, String> localizedSubjectMap = _assetPublisherWebUtil
                .getEmailAssetEntryAddedSubjectMap(portletPreferences);
        Map<Locale, String> localizedBodyMap = _assetPublisherWebUtil
                .getEmailAssetEntryAddedBodyMap(portletPreferences);

        SubscriptionSender subscriptionSender = new SubscriptionSender();

        subscriptionSender.setCompanyId(assetEntry.getCompanyId());
        subscriptionSender.setContextAttributes("[$ASSET_ENTRIES$]",
                ListUtil.toString(assetEntries, _titleAccessor, StringPool.COMMA_AND_SPACE));
        subscriptionSender.setFrom(fromAddress, fromName);
        subscriptionSender.setHtmlFormat(true);
        subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
        subscriptionSender
                .setLocalizedPortletTitleMap(PortletConfigurationUtil.getPortletTitleMap(portletPreferences));
        subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
        subscriptionSender.setMailId("asset_entry", assetEntry.getEntryId());
        subscriptionSender.setPortletId(AssetPublisherPortletKeys.ASSET_PUBLISHER);
        subscriptionSender.setReplyToAddress(fromAddress);

        return subscriptionSender;
    }

    private static void _notifySubscribers(List<Subscription> subscriptions, PortletPreferences portletPreferences,
            List<AssetEntry> assetEntries) {

        if (!_assetPublisherWebUtil.getEmailAssetEntryAddedEnabled(portletPreferences)) {

            return;
        }

        Map<List<AssetEntry>, List<User>> assetEntriesToUsersMap = new HashMap<>();

        for (Subscription subscription : subscriptions) {
            long userId = subscription.getUserId();

            User user = _userLocalService.fetchUser(userId);

            if ((user == null) || !user.isActive()) {
                continue;
            }

            List<AssetEntry> filteredAssetEntries = _filterAssetEntries(userId, assetEntries);

            if (filteredAssetEntries.isEmpty()) {
                continue;
            }

            List<User> users = assetEntriesToUsersMap.get(filteredAssetEntries);

            if (users == null) {
                users = new LinkedList<>();

                assetEntriesToUsersMap.put(filteredAssetEntries, users);
            }

            users.add(user);
        }

        for (Map.Entry<List<AssetEntry>, List<User>> entry : assetEntriesToUsersMap.entrySet()) {

            List<AssetEntry> filteredAssetEntries = entry.getKey();
            List<User> users = entry.getValue();

            SubscriptionSender subscriptionSender = _getSubscriptionSender(portletPreferences,
                    filteredAssetEntries);

            if (subscriptionSender == null) {
                continue;
            }

            for (User user : users) {
                subscriptionSender.addRuntimeSubscribers(user.getEmailAddress(), user.getFullName());
            }

            subscriptionSender.flushNotificationsAsync();
        }
    }

    private void _checkAssetEntries(com.liferay.portal.kernel.model.PortletPreferences portletPreferencesModel)
            throws PortalException {

        Layout layout = _layoutLocalService.fetchLayout(portletPreferencesModel.getPlid());

        if (layout == null) {
            return;
        }

        PortletPreferences portletPreferences = PortletPreferencesFactoryUtil.fromXML(layout.getCompanyId(),
                portletPreferencesModel.getOwnerId(), portletPreferencesModel.getOwnerType(),
                portletPreferencesModel.getPlid(), portletPreferencesModel.getPortletId(),
                portletPreferencesModel.getPreferences());

        if (!_assetPublisherWebUtil.getEmailAssetEntryAddedEnabled(portletPreferences)) {

            return;
        }

        List<AssetEntry> assetEntries = _getAssetEntries(portletPreferences, layout);

        if (assetEntries.isEmpty()) {
            return;
        }

        long[] notifiedAssetEntryIds = GetterUtil
                .getLongValues(portletPreferences.getValues("notifiedAssetEntryIds", null));

        ArrayList<AssetEntry> newAssetEntries = new ArrayList<>();

        for (AssetEntry assetEntry : assetEntries) {
            if (!ArrayUtil.contains(notifiedAssetEntryIds, assetEntry.getEntryId())) {

                newAssetEntries.add(assetEntry);
            }
        }

        List<Subscription> subscriptions = _subscriptionLocalService.getSubscriptions(
                portletPreferencesModel.getCompanyId(),
                com.liferay.portal.kernel.model.PortletPreferences.class.getName(),
                _assetPublisherWebUtil.getSubscriptionClassPK(portletPreferencesModel.getPlid(),
                        portletPreferencesModel.getPortletId()));

        _notifySubscribers(subscriptions, portletPreferences, newAssetEntries);

        try {
            portletPreferences.setValues("notifiedAssetEntryIds",
                    StringUtil.split(ListUtil.toString(assetEntries, AssetEntry.ENTRY_ID_ACCESSOR)));

            portletPreferences.store();
        } catch (IOException | PortletException e) {
            throw new PortalException(e);
        }
    }

    private List<AssetEntry> _getAssetEntries(PortletPreferences portletPreferences, Layout layout)
            throws PortalException {

        AssetPublisherWebConfiguration assetPublisherWebConfiguration = _configurationProvider
                .getCompanyConfiguration(AssetPublisherWebConfiguration.class, layout.getCompanyId());

        AssetEntryQuery assetEntryQuery = AssetPublisherUtil.getAssetEntryQuery(portletPreferences,
                layout.getGroupId(), layout, null, null);

        assetEntryQuery.setEnd(assetPublisherWebConfiguration.dynamicSubscriptionLimit());
        assetEntryQuery.setStart(0);

        try {
            SearchContext searchContext = SearchContextFactory.getInstance(new long[0], new String[0], null,
                    layout.getCompanyId(), StringPool.BLANK, layout, LocaleThreadLocal.getSiteDefaultLocale(),
                    layout.getGroupId(), TimeZoneThreadLocal.getDefaultTimeZone(), 0);

            BaseModelSearchResult<AssetEntry> baseModelSearchResult = _assetHelper.searchAssetEntries(searchContext,
                    assetEntryQuery, 0, assetPublisherWebConfiguration.dynamicSubscriptionLimit());

            return baseModelSearchResult.getBaseModels();
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    private static AssetPublisherWebUtil _assetPublisherWebUtil;
    private static LayoutLocalService _layoutLocalService;
    private static PortletPreferencesLocalService _portletPreferencesLocalService;
    private static SubscriptionLocalService _subscriptionLocalService;

    private static final Accessor<AssetEntry, String> _titleAccessor = new Accessor<AssetEntry, String>() {

        @Override
        public String get(AssetEntry assetEntry) {
            return assetEntry.getTitle(LocaleUtil.getSiteDefault());
        }

        @Override
        public Class<String> getAttributeClass() {
            return String.class;
        }

        @Override
        public Class<AssetEntry> getTypeClass() {
            return AssetEntry.class;
        }

    };

    private static UserLocalService _userLocalService;

    @Reference
    private AssetHelper _assetHelper;

    @Reference
    private ConfigurationProvider _configurationProvider;

}