001    /**
002     * Copyright (c) 2000-present 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.language.LanguageUtil;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.servlet.SessionMessages;
028    import com.liferay.portal.kernel.util.Accessor;
029    import com.liferay.portal.kernel.util.ArrayUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HtmlUtil;
032    import com.liferay.portal.kernel.util.InstanceFactory;
033    import com.liferay.portal.kernel.util.ListUtil;
034    import com.liferay.portal.kernel.util.LocaleUtil;
035    import com.liferay.portal.kernel.util.LocalizationUtil;
036    import com.liferay.portal.kernel.util.ParamUtil;
037    import com.liferay.portal.kernel.util.PrefsPropsUtil;
038    import com.liferay.portal.kernel.util.PrimitiveLongList;
039    import com.liferay.portal.kernel.util.PropsKeys;
040    import com.liferay.portal.kernel.util.StringPool;
041    import com.liferay.portal.kernel.util.StringUtil;
042    import com.liferay.portal.kernel.util.Validator;
043    import com.liferay.portal.kernel.xml.Document;
044    import com.liferay.portal.kernel.xml.Element;
045    import com.liferay.portal.kernel.xml.SAXReaderUtil;
046    import com.liferay.portal.model.Company;
047    import com.liferay.portal.model.Group;
048    import com.liferay.portal.model.GroupConstants;
049    import com.liferay.portal.model.Layout;
050    import com.liferay.portal.model.PortletConstants;
051    import com.liferay.portal.model.User;
052    import com.liferay.portal.security.auth.PrincipalException;
053    import com.liferay.portal.security.auth.PrincipalThreadLocal;
054    import com.liferay.portal.security.permission.ActionKeys;
055    import com.liferay.portal.security.permission.PermissionChecker;
056    import com.liferay.portal.service.GroupLocalServiceUtil;
057    import com.liferay.portal.service.LayoutLocalServiceUtil;
058    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
059    import com.liferay.portal.service.SubscriptionLocalServiceUtil;
060    import com.liferay.portal.service.permission.GroupPermissionUtil;
061    import com.liferay.portal.service.permission.PortletPermissionUtil;
062    import com.liferay.portal.theme.ThemeDisplay;
063    import com.liferay.portal.util.PortalUtil;
064    import com.liferay.portal.util.PortletKeys;
065    import com.liferay.portal.util.PropsValues;
066    import com.liferay.portal.util.SubscriptionSender;
067    import com.liferay.portal.util.WebKeys;
068    import com.liferay.portlet.PortletPreferencesFactoryUtil;
069    import com.liferay.portlet.StrictPortletPreferencesImpl;
070    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
071    import com.liferay.portlet.asset.model.AssetCategory;
072    import com.liferay.portlet.asset.model.AssetEntry;
073    import com.liferay.portlet.asset.model.AssetRenderer;
074    import com.liferay.portlet.asset.model.AssetRendererFactory;
075    import com.liferay.portlet.asset.model.AssetTag;
076    import com.liferay.portlet.asset.model.ClassType;
077    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
078    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
079    import com.liferay.portlet.asset.service.AssetEntryServiceUtil;
080    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
081    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
082    import com.liferay.portlet.expando.model.ExpandoBridge;
083    import com.liferay.portlet.sites.util.SitesUtil;
084    
085    import java.io.IOException;
086    import java.io.Serializable;
087    
088    import java.util.ArrayList;
089    import java.util.HashMap;
090    import java.util.HashSet;
091    import java.util.Iterator;
092    import java.util.LinkedHashMap;
093    import java.util.List;
094    import java.util.Locale;
095    import java.util.Map;
096    import java.util.Set;
097    import java.util.concurrent.ConcurrentHashMap;
098    
099    import javax.portlet.PortletException;
100    import javax.portlet.PortletPreferences;
101    import javax.portlet.PortletRequest;
102    
103    import javax.servlet.http.HttpServletRequest;
104    import javax.servlet.http.HttpSession;
105    
106    /**
107     * @author Raymond Aug??
108     * @author Julio Camarero
109     */
110    public class AssetPublisherImpl implements AssetPublisher {
111    
112            public AssetPublisherImpl() {
113                    for (String assetEntryQueryProcessorClassName :
114                                    PropsValues.ASSET_PUBLISHER_ASSET_ENTRY_QUERY_PROCESSORS) {
115    
116                            try {
117                                    AssetEntryQueryProcessor assetEntryQueryProcessor =
118                                            (AssetEntryQueryProcessor)InstanceFactory.newInstance(
119                                                    assetEntryQueryProcessorClassName);
120    
121                                    registerAssetQueryProcessor(
122                                            assetEntryQueryProcessorClassName,
123                                            assetEntryQueryProcessor);
124                            }
125                            catch (Exception e) {
126                                    _log.error(e, e);
127                            }
128                    }
129            }
130    
131            @Override
132            public void addAndStoreSelection(
133                            PortletRequest portletRequest, String className, long classPK,
134                            int assetEntryOrder)
135                    throws Exception {
136    
137                    String referringPortletResource = ParamUtil.getString(
138                            portletRequest, "referringPortletResource");
139    
140                    if (Validator.isNull(referringPortletResource)) {
141                            return;
142                    }
143    
144                    String rootPortletId = PortletConstants.getRootPortletId(
145                            referringPortletResource);
146    
147                    if (!rootPortletId.equals(PortletKeys.ASSET_PUBLISHER)) {
148                            return;
149                    }
150    
151                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
152                            WebKeys.THEME_DISPLAY);
153    
154                    Layout layout = LayoutLocalServiceUtil.getLayout(
155                            themeDisplay.getRefererPlid());
156    
157                    PortletPreferences portletPreferences =
158                            PortletPreferencesFactoryUtil.getStrictPortletSetup(
159                                    layout, referringPortletResource);
160    
161                    if (portletPreferences instanceof StrictPortletPreferencesImpl) {
162                            return;
163                    }
164    
165                    String selectionStyle = portletPreferences.getValue(
166                            "selectionStyle", "dynamic");
167    
168                    if (selectionStyle.equals("dynamic")) {
169                            return;
170                    }
171    
172                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
173                            className, classPK);
174    
175                    addSelection(
176                            themeDisplay, portletPreferences, referringPortletResource,
177                            assetEntry.getEntryId(), assetEntryOrder, className);
178    
179                    portletPreferences.store();
180            }
181    
182            @Override
183            public void addRecentFolderId(
184                    PortletRequest portletRequest, String className, long classPK) {
185    
186                    _getRecentFolderIds(portletRequest).put(className, classPK);
187            }
188    
189            @Override
190            public void addSelection(
191                            PortletRequest portletRequest,
192                            PortletPreferences portletPreferences, String portletId)
193                    throws Exception {
194    
195                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
196                            WebKeys.THEME_DISPLAY);
197    
198                    long assetEntryId = ParamUtil.getLong(portletRequest, "assetEntryId");
199                    int assetEntryOrder = ParamUtil.getInteger(
200                            portletRequest, "assetEntryOrder");
201                    String assetEntryType = ParamUtil.getString(
202                            portletRequest, "assetEntryType");
203    
204                    addSelection(
205                            themeDisplay, portletPreferences, portletId, assetEntryId,
206                            assetEntryOrder, assetEntryType);
207            }
208    
209            @Override
210            public void addSelection(
211                            ThemeDisplay themeDisplay, PortletPreferences portletPreferences,
212                            String portletId, long assetEntryId, int assetEntryOrder,
213                            String assetEntryType)
214                    throws Exception {
215    
216                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
217                            assetEntryId);
218    
219                    String[] assetEntryXmls = portletPreferences.getValues(
220                            "assetEntryXml", new String[0]);
221    
222                    String assetEntryXml = _getAssetEntryXml(
223                            assetEntryType, assetEntry.getClassUuid());
224    
225                    if (!ArrayUtil.contains(assetEntryXmls, assetEntryXml)) {
226                            if (assetEntryOrder > -1) {
227                                    assetEntryXmls[assetEntryOrder] = assetEntryXml;
228                            }
229                            else {
230                                    assetEntryXmls = ArrayUtil.append(
231                                            assetEntryXmls, assetEntryXml);
232                            }
233    
234                            portletPreferences.setValues("assetEntryXml", assetEntryXmls);
235                    }
236    
237                    long plid = themeDisplay.getRefererPlid();
238    
239                    if (plid == 0) {
240                            plid = themeDisplay.getPlid();
241                    }
242    
243                    List<AssetEntry> assetEntries = new ArrayList<AssetEntry>();
244    
245                    assetEntries.add(assetEntry);
246    
247                    notifySubscribers(portletPreferences, plid, portletId, assetEntries);
248            }
249    
250            @Override
251            public void addUserAttributes(
252                            User user, String[] customUserAttributeNames,
253                            AssetEntryQuery assetEntryQuery)
254                    throws Exception {
255    
256                    if ((user == null) || (customUserAttributeNames.length == 0)) {
257                            return;
258                    }
259    
260                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
261                            user.getCompanyId());
262    
263                    long[] allCategoryIds = assetEntryQuery.getAllCategoryIds();
264    
265                    PrimitiveLongList allCategoryIdsList = new PrimitiveLongList(
266                            allCategoryIds.length + customUserAttributeNames.length);
267    
268                    allCategoryIdsList.addAll(allCategoryIds);
269    
270                    for (String customUserAttributeName : customUserAttributeNames) {
271                            ExpandoBridge userCustomAttributes = user.getExpandoBridge();
272    
273                            Serializable userCustomFieldValue = null;
274    
275                            try {
276                                    userCustomFieldValue = userCustomAttributes.getAttribute(
277                                            customUserAttributeName);
278                            }
279                            catch (Exception e) {
280                            }
281    
282                            if (userCustomFieldValue == null) {
283                                    continue;
284                            }
285    
286                            String userCustomFieldValueString = userCustomFieldValue.toString();
287    
288                            List<AssetCategory> assetCategories =
289                                    AssetCategoryLocalServiceUtil.search(
290                                            companyGroup.getGroupId(), userCustomFieldValueString,
291                                            new String[0], QueryUtil.ALL_POS, QueryUtil.ALL_POS);
292    
293                            for (AssetCategory assetCategory : assetCategories) {
294                                    allCategoryIdsList.add(assetCategory.getCategoryId());
295                            }
296                    }
297    
298                    assetEntryQuery.setAllCategoryIds(allCategoryIdsList.getArray());
299            }
300    
301            @Override
302            public void checkAssetEntries() throws Exception {
303                    ActionableDynamicQuery actionableDynamicQuery =
304                            PortletPreferencesLocalServiceUtil.getActionableDynamicQuery();
305    
306                    actionableDynamicQuery.setAddCriteriaMethod(
307                            new ActionableDynamicQuery.AddCriteriaMethod() {
308    
309                                    @Override
310                                    public void addCriteria(DynamicQuery dynamicQuery) {
311                                            Property property = PropertyFactoryUtil.forName(
312                                                    "portletId");
313    
314                                            String portletId =
315                                                    PortletKeys.ASSET_PUBLISHER +
316                                                            PortletConstants.INSTANCE_SEPARATOR +
317                                                                    StringPool.PERCENT;
318    
319                                            dynamicQuery.add(property.like(portletId));
320                                    }
321    
322                            });
323                    actionableDynamicQuery.setPerformActionMethod(
324                            new ActionableDynamicQuery.PerformActionMethod() {
325    
326                                    @Override
327                                    public void performAction(Object object)
328                                            throws PortalException {
329    
330                                            _checkAssetEntries(
331                                                    (com.liferay.portal.model.PortletPreferences)object);
332                                    }
333    
334                            });
335    
336                    actionableDynamicQuery.performActions();
337            }
338    
339            @Override
340            public long[] getAssetCategoryIds(PortletPreferences portletPreferences)
341                    throws Exception {
342    
343                    long[] assetCategoryIds = new long[0];
344    
345                    for (int i = 0; true; i++) {
346                            String[] queryValues = portletPreferences.getValues(
347                                    "queryValues" + i, null);
348    
349                            if (ArrayUtil.isEmpty(queryValues)) {
350                                    break;
351                            }
352    
353                            boolean queryContains = GetterUtil.getBoolean(
354                                    portletPreferences.getValue(
355                                            "queryContains" + i, StringPool.BLANK));
356                            boolean queryAndOperator = GetterUtil.getBoolean(
357                                    portletPreferences.getValue(
358                                            "queryAndOperator" + i, StringPool.BLANK));
359                            String queryName = portletPreferences.getValue(
360                                    "queryName" + i, StringPool.BLANK);
361    
362                            if (Validator.equals(queryName, "assetCategories") &&
363                                    queryContains && queryAndOperator) {
364    
365                                    assetCategoryIds = GetterUtil.getLongValues(queryValues);
366                            }
367                    }
368    
369                    return assetCategoryIds;
370            }
371    
372            @Override
373            public List<AssetEntry> getAssetEntries(
374                            PortletPreferences portletPreferences, Layout layout,
375                            long scopeGroupId, int max, boolean checkPermission)
376                    throws PortalException {
377    
378                    long[] groupIds = getGroupIds(portletPreferences, scopeGroupId, layout);
379    
380                    AssetEntryQuery assetEntryQuery = getAssetEntryQuery(
381                            portletPreferences, groupIds);
382    
383                    assetEntryQuery.setGroupIds(groupIds);
384    
385                    boolean anyAssetType = GetterUtil.getBoolean(
386                            portletPreferences.getValue("anyAssetType", null), true);
387    
388                    if (!anyAssetType) {
389                            long[] availableClassNameIds =
390                                    AssetRendererFactoryRegistryUtil.getClassNameIds(
391                                            layout.getCompanyId());
392    
393                            long[] classNameIds = getClassNameIds(
394                                    portletPreferences, availableClassNameIds);
395    
396                            assetEntryQuery.setClassNameIds(classNameIds);
397                    }
398    
399                    long[] classTypeIds = GetterUtil.getLongValues(
400                            portletPreferences.getValues("classTypeIds", null));
401    
402                    assetEntryQuery.setClassTypeIds(classTypeIds);
403    
404                    boolean enablePermissions = GetterUtil.getBoolean(
405                            portletPreferences.getValue("enablePermissions", null));
406    
407                    assetEntryQuery.setEnablePermissions(enablePermissions);
408    
409                    assetEntryQuery.setEnd(max);
410    
411                    boolean excludeZeroViewCount = GetterUtil.getBoolean(
412                            portletPreferences.getValue("excludeZeroViewCount", null));
413    
414                    assetEntryQuery.setExcludeZeroViewCount(excludeZeroViewCount);
415    
416                    boolean showOnlyLayoutAssets = GetterUtil.getBoolean(
417                            portletPreferences.getValue("showOnlyLayoutAssets", null));
418    
419                    if (showOnlyLayoutAssets) {
420                            assetEntryQuery.setLayout(layout);
421                    }
422    
423                    String orderByColumn1 = GetterUtil.getString(
424                            portletPreferences.getValue("orderByColumn1", "modifiedDate"));
425    
426                    assetEntryQuery.setOrderByCol1(orderByColumn1);
427    
428                    String orderByColumn2 = GetterUtil.getString(
429                            portletPreferences.getValue("orderByColumn2", "title"));
430    
431                    assetEntryQuery.setOrderByCol2(orderByColumn2);
432    
433                    String orderByType1 = GetterUtil.getString(
434                            portletPreferences.getValue("orderByType1", "DESC"));
435    
436                    assetEntryQuery.setOrderByType1(orderByType1);
437    
438                    String orderByType2 = GetterUtil.getString(
439                            portletPreferences.getValue("orderByType2", "ASC"));
440    
441                    assetEntryQuery.setOrderByType2(orderByType2);
442    
443                    assetEntryQuery.setStart(0);
444    
445                    if (checkPermission) {
446                            return AssetEntryServiceUtil.getEntries(assetEntryQuery);
447                    }
448                    else {
449                            return AssetEntryLocalServiceUtil.getEntries(assetEntryQuery);
450                    }
451            }
452    
453            @Override
454            public List<AssetEntry> getAssetEntries(
455                            PortletRequest portletRequest,
456                            PortletPreferences portletPreferences,
457                            PermissionChecker permissionChecker, long[] groupIds,
458                            boolean deleteMissingAssetEntries, boolean checkPermission)
459                    throws Exception {
460    
461                    String[] assetEntryXmls = portletPreferences.getValues(
462                            "assetEntryXml", new String[0]);
463    
464                    List<AssetEntry> assetEntries = new ArrayList<AssetEntry>();
465    
466                    List<String> missingAssetEntryUuids = new ArrayList<String>();
467    
468                    for (String assetEntryXml : assetEntryXmls) {
469                            Document document = SAXReaderUtil.read(assetEntryXml);
470    
471                            Element rootElement = document.getRootElement();
472    
473                            String assetEntryUuid = rootElement.elementText("asset-entry-uuid");
474    
475                            AssetEntry assetEntry = null;
476    
477                            for (long groupId : groupIds) {
478                                    assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
479                                            groupId, assetEntryUuid);
480    
481                                    if (assetEntry != null) {
482                                            break;
483                                    }
484                            }
485    
486                            if (assetEntry == null) {
487                                    if (deleteMissingAssetEntries) {
488                                            missingAssetEntryUuids.add(assetEntryUuid);
489                                    }
490    
491                                    continue;
492                            }
493    
494                            if (!assetEntry.isVisible()) {
495                                    continue;
496                            }
497    
498                            AssetRendererFactory assetRendererFactory =
499                                    AssetRendererFactoryRegistryUtil.
500                                            getAssetRendererFactoryByClassName(
501                                                    assetEntry.getClassName());
502    
503                            AssetRenderer assetRenderer = assetRendererFactory.getAssetRenderer(
504                                    assetEntry.getClassPK());
505    
506                            if (!assetRendererFactory.isActive(
507                                            permissionChecker.getCompanyId())) {
508    
509                                    if (deleteMissingAssetEntries) {
510                                            missingAssetEntryUuids.add(assetEntryUuid);
511                                    }
512    
513                                    continue;
514                            }
515    
516                            if (checkPermission &&
517                                    (!assetRenderer.isDisplayable() ||
518                                     !assetRenderer.hasViewPermission(permissionChecker))) {
519    
520                                    continue;
521                            }
522    
523                            assetEntries.add(assetEntry);
524                    }
525    
526                    if (deleteMissingAssetEntries) {
527                            AssetPublisherUtil.removeAndStoreSelection(
528                                    missingAssetEntryUuids, portletPreferences);
529    
530                            if (!missingAssetEntryUuids.isEmpty()) {
531                                    SessionMessages.add(
532                                            portletRequest, "deletedMissingAssetEntries",
533                                            missingAssetEntryUuids);
534                            }
535                    }
536    
537                    return assetEntries;
538            }
539    
540            @Override
541            public List<AssetEntry> getAssetEntries(
542                            PortletRequest portletRequest,
543                            PortletPreferences portletPreferences,
544                            PermissionChecker permissionChecker, long[] groupIds,
545                            long[] allCategoryIds, String[] allTagNames,
546                            boolean deleteMissingAssetEntries, boolean checkPermission)
547                    throws Exception {
548    
549                    List<AssetEntry> assetEntries = getAssetEntries(
550                            portletRequest, portletPreferences, permissionChecker, groupIds,
551                            deleteMissingAssetEntries, checkPermission);
552    
553                    if (assetEntries.isEmpty() ||
554                            (ArrayUtil.isEmpty(allCategoryIds) &&
555                             ArrayUtil.isEmpty(allTagNames))) {
556    
557                            return assetEntries;
558                    }
559    
560                    if (!ArrayUtil.isEmpty(allCategoryIds)) {
561                            assetEntries = _filterAssetCategoriesAssetEntries(
562                                    assetEntries, allCategoryIds);
563                    }
564    
565                    if (!ArrayUtil.isEmpty(allTagNames)) {
566                            assetEntries = _filterAssetTagNamesAssetEntries(
567                                    assetEntries, allTagNames);
568                    }
569    
570                    return assetEntries;
571            }
572    
573            /**
574             * @deprecated As of 7.0.0, replaced by {@link
575             *             AssetPublisherImpl#getAssetEntries(PortletRequest,
576             *             PortletPreferences, PermissionChecker, long[], long[],
577             *             String[], boolean , boolean)}
578             */
579            @Deprecated
580            @Override
581            public List<AssetEntry> getAssetEntries(
582                            PortletRequest portletRequest,
583                            PortletPreferences portletPreferences,
584                            PermissionChecker permissionChecker, long[] groupIds,
585                            long[] allCategoryIds, String[] assetEntryXmls,
586                            String[] allTagNames, boolean deleteMissingAssetEntries,
587                            boolean checkPermission)
588                    throws Exception {
589    
590                    return getAssetEntries(
591                            portletRequest, portletPreferences, permissionChecker, groupIds,
592                            allCategoryIds, allTagNames, deleteMissingAssetEntries,
593                            checkPermission);
594            }
595    
596            /**
597             * @deprecated As of 7.0.0, replaced by {@link
598             *             AssetPublisherImpl#getAssetEntries(PortletRequest,
599             *             PortletPreferences, PermissionChecker, long[], boolean,
600             *             boolean)}
601             */
602            @Deprecated
603            @Override
604            public List<AssetEntry> getAssetEntries(
605                            PortletRequest portletRequest,
606                            PortletPreferences portletPreferences,
607                            PermissionChecker permissionChecker, long[] groupIds,
608                            String[] assetEntryXmls, boolean deleteMissingAssetEntries,
609                            boolean checkPermission)
610                    throws Exception {
611    
612                    return getAssetEntries(
613                            portletRequest, portletPreferences, permissionChecker, groupIds,
614                            deleteMissingAssetEntries, checkPermission);
615            }
616    
617            /**
618             * @deprecated As of 7.0.0, replaced by {@link
619             *             AssetPublisherImpl#getAssetEntryQuery(PortletPreferences,
620             *             long[], long[], String[])}
621             */
622            @Deprecated
623            @Override
624            public AssetEntryQuery getAssetEntryQuery(
625                            PortletPreferences portletPreferences, long[] scopeGroupIds)
626                    throws PortalException {
627    
628                    return getAssetEntryQuery(
629                            portletPreferences, scopeGroupIds, null, null);
630            }
631    
632            @Override
633            public AssetEntryQuery getAssetEntryQuery(
634                            PortletPreferences portletPreferences, long[] scopeGroupIds,
635                            long[] overrideAllAssetCategoryIds,
636                            String[] overrideAllAssetTagNames)
637                    throws PortalException {
638    
639                    AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
640    
641                    long[] allAssetCategoryIds = new long[0];
642                    long[] anyAssetCategoryIds = new long[0];
643                    long[] notAllAssetCategoryIds = new long[0];
644                    long[] notAnyAssetCategoryIds = new long[0];
645    
646                    String[] allAssetTagNames = new String[0];
647                    String[] anyAssetTagNames = new String[0];
648                    String[] notAllAssetTagNames = new String[0];
649                    String[] notAnyAssetTagNames = new String[0];
650    
651                    for (int i = 0; true; i++) {
652                            String[] queryValues = portletPreferences.getValues(
653                                    "queryValues" + i, null);
654    
655                            if (ArrayUtil.isEmpty(queryValues)) {
656                                    break;
657                            }
658    
659                            boolean queryContains = GetterUtil.getBoolean(
660                                    portletPreferences.getValue(
661                                            "queryContains" + i, StringPool.BLANK));
662                            boolean queryAndOperator = GetterUtil.getBoolean(
663                                    portletPreferences.getValue(
664                                            "queryAndOperator" + i, StringPool.BLANK));
665                            String queryName = portletPreferences.getValue(
666                                    "queryName" + i, StringPool.BLANK);
667    
668                            if (Validator.equals(queryName, "assetCategories")) {
669                                    long[] assetCategoryIds = GetterUtil.getLongValues(queryValues);
670    
671                                    if (queryContains && queryAndOperator) {
672                                            allAssetCategoryIds = assetCategoryIds;
673                                    }
674                                    else if (queryContains && !queryAndOperator) {
675                                            anyAssetCategoryIds = assetCategoryIds;
676                                    }
677                                    else if (!queryContains && queryAndOperator) {
678                                            notAllAssetCategoryIds = assetCategoryIds;
679                                    }
680                                    else {
681                                            notAnyAssetCategoryIds = assetCategoryIds;
682                                    }
683                            }
684                            else {
685                                    if (queryContains && queryAndOperator) {
686                                            allAssetTagNames = queryValues;
687                                    }
688                                    else if (queryContains && !queryAndOperator) {
689                                            anyAssetTagNames = queryValues;
690                                    }
691                                    else if (!queryContains && queryAndOperator) {
692                                            notAllAssetTagNames = queryValues;
693                                    }
694                                    else {
695                                            notAnyAssetTagNames = queryValues;
696                                    }
697                            }
698                    }
699    
700                    if (overrideAllAssetCategoryIds != null) {
701                            allAssetCategoryIds = overrideAllAssetCategoryIds;
702                    }
703    
704                    assetEntryQuery.setAllCategoryIds(allAssetCategoryIds);
705    
706                    if (overrideAllAssetCategoryIds != null) {
707                            allAssetTagNames = overrideAllAssetTagNames;
708                    }
709    
710                    long[] siteGroupIds = getSiteGroupIds(scopeGroupIds);
711    
712                    for (String assetTagName : allAssetTagNames) {
713                            long[] allAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
714                                    siteGroupIds, assetTagName);
715    
716                            assetEntryQuery.addAllTagIdsArray(allAssetTagIds);
717                    }
718    
719                    assetEntryQuery.setAnyCategoryIds(anyAssetCategoryIds);
720    
721                    long[] anyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
722                            siteGroupIds, anyAssetTagNames);
723    
724                    assetEntryQuery.setAnyTagIds(anyAssetTagIds);
725    
726                    assetEntryQuery.setNotAllCategoryIds(notAllAssetCategoryIds);
727    
728                    for (String assetTagName : notAllAssetTagNames) {
729                            long[] notAllAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
730                                    siteGroupIds, assetTagName);
731    
732                            assetEntryQuery.addNotAllTagIdsArray(notAllAssetTagIds);
733                    }
734    
735                    assetEntryQuery.setNotAnyCategoryIds(notAnyAssetCategoryIds);
736    
737                    long[] notAnyAssetTagIds = AssetTagLocalServiceUtil.getTagIds(
738                            siteGroupIds, notAnyAssetTagNames);
739    
740                    assetEntryQuery.setNotAnyTagIds(notAnyAssetTagIds);
741    
742                    return assetEntryQuery;
743            }
744    
745            @Override
746            public String[] getAssetTagNames(PortletPreferences portletPreferences)
747                    throws Exception {
748    
749                    String[] allAssetTagNames = new String[0];
750    
751                    for (int i = 0; true; i++) {
752                            String[] queryValues = portletPreferences.getValues(
753                                    "queryValues" + i, null);
754    
755                            if (ArrayUtil.isEmpty(queryValues)) {
756                                    break;
757                            }
758    
759                            boolean queryContains = GetterUtil.getBoolean(
760                                    portletPreferences.getValue(
761                                            "queryContains" + i, StringPool.BLANK));
762                            boolean queryAndOperator = GetterUtil.getBoolean(
763                                    portletPreferences.getValue(
764                                            "queryAndOperator" + i, StringPool.BLANK));
765                            String queryName = portletPreferences.getValue(
766                                    "queryName" + i, StringPool.BLANK);
767    
768                            if (!Validator.equals(queryName, "assetCategories") &&
769                                    queryContains && queryAndOperator) {
770    
771                                    allAssetTagNames = queryValues;
772                            }
773                    }
774    
775                    return allAssetTagNames;
776            }
777    
778            /**
779             * @deprecated As of 7.0.0, replaced by {@link
780             *             AssetPublisherImpl#getAssetTagNames(PortletPreferences)}
781             */
782            @Deprecated
783            @Override
784            public String[] getAssetTagNames(
785                            PortletPreferences portletPreferences, long scopeGroupId)
786                    throws Exception {
787    
788                    return getAssetTagNames(portletPreferences);
789            }
790    
791            @Override
792            public String getClassName(AssetRendererFactory assetRendererFactory) {
793                    Class<?> clazz = assetRendererFactory.getClass();
794    
795                    String className = clazz.getName();
796    
797                    int pos = className.lastIndexOf(StringPool.PERIOD);
798    
799                    return className.substring(pos + 1);
800            }
801    
802            @Override
803            public long[] getClassNameIds(
804                    PortletPreferences portletPreferences, long[] availableClassNameIds) {
805    
806                    boolean anyAssetType = GetterUtil.getBoolean(
807                            portletPreferences.getValue(
808                                    "anyAssetType", Boolean.TRUE.toString()));
809                    String selectionStyle = portletPreferences.getValue(
810                            "selectionStyle", "dynamic");
811    
812                    if (anyAssetType || selectionStyle.equals("manual")) {
813                            return availableClassNameIds;
814                    }
815    
816                    long defaultClassNameId = GetterUtil.getLong(
817                            portletPreferences.getValue("anyAssetType", null));
818    
819                    if (defaultClassNameId > 0) {
820                            return new long[] {defaultClassNameId};
821                    }
822    
823                    long[] classNameIds = GetterUtil.getLongValues(
824                            portletPreferences.getValues("classNameIds", null));
825    
826                    if (ArrayUtil.isNotEmpty(classNameIds)) {
827                            return classNameIds;
828                    }
829                    else {
830                            return availableClassNameIds;
831                    }
832            }
833    
834            @Override
835            public Long[] getClassTypeIds(
836                    PortletPreferences portletPreferences, String className,
837                    List<ClassType> availableClassTypes) {
838    
839                    Long[] availableClassTypeIds = new Long[availableClassTypes.size()];
840    
841                    for (int i = 0; i < availableClassTypeIds.length; i++) {
842                            ClassType classType = availableClassTypes.get(i);
843    
844                            availableClassTypeIds[i] = classType.getClassTypeId();
845                    }
846    
847                    return getClassTypeIds(
848                            portletPreferences, className, availableClassTypeIds);
849            }
850    
851            @Override
852            public Long[] getClassTypeIds(
853                    PortletPreferences portletPreferences, String className,
854                    Long[] availableClassTypeIds) {
855    
856                    boolean anyAssetType = GetterUtil.getBoolean(
857                            portletPreferences.getValue(
858                                    "anyClassType" + className, Boolean.TRUE.toString()));
859    
860                    if (anyAssetType) {
861                            return availableClassTypeIds;
862                    }
863    
864                    long defaultClassTypeId = GetterUtil.getLong(
865                            portletPreferences.getValue("anyClassType" + className, null));
866    
867                    if (defaultClassTypeId > 0) {
868                            return new Long[] {defaultClassTypeId};
869                    }
870    
871                    Long[] classTypeIds = ArrayUtil.toArray(
872                            StringUtil.split(
873                                    portletPreferences.getValue(
874                                            "classTypeIds" + className, null), 0L));
875    
876                    if (classTypeIds != null) {
877                            return classTypeIds;
878                    }
879                    else {
880                            return availableClassTypeIds;
881                    }
882            }
883    
884            @Override
885            public Map<Locale, String> getEmailAssetEntryAddedBodyMap(
886                    PortletPreferences portletPreferences) {
887    
888                    return LocalizationUtil.getLocalizationMap(
889                            portletPreferences, "emailAssetEntryAddedBody",
890                            PropsKeys.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_BODY);
891            }
892    
893            @Override
894            public boolean getEmailAssetEntryAddedEnabled(
895                    PortletPreferences portletPreferences) {
896    
897                    String emailAssetEntryAddedEnabled = portletPreferences.getValue(
898                            "emailAssetEntryAddedEnabled", StringPool.BLANK);
899    
900                    if (Validator.isNotNull(emailAssetEntryAddedEnabled)) {
901                            return GetterUtil.getBoolean(emailAssetEntryAddedEnabled);
902                    }
903                    else {
904                            return PropsValues.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_ENABLED;
905                    }
906            }
907    
908            @Override
909            public Map<Locale, String> getEmailAssetEntryAddedSubjectMap(
910                    PortletPreferences portletPreferences) {
911    
912                    return LocalizationUtil.getLocalizationMap(
913                            portletPreferences, "emailAssetEntryAddedSubject",
914                            PropsKeys.ASSET_PUBLISHER_EMAIL_ASSET_ENTRY_ADDED_SUBJECT);
915            }
916    
917            @Override
918            public Map<String, String> getEmailDefinitionTerms(
919                    PortletRequest portletRequest, String emailFromAddress,
920                    String emailFromName) {
921    
922                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
923                            WebKeys.THEME_DISPLAY);
924    
925                    Map<String, String> definitionTerms =
926                            new LinkedHashMap<String, String>();
927    
928                    definitionTerms.put(
929                            "[$ASSET_ENTRIES$]",
930                            LanguageUtil.get(themeDisplay.getLocale(), "the-list-of-assets"));
931                    definitionTerms.put(
932                            "[$COMPANY_ID$]",
933                            LanguageUtil.get(
934                                    themeDisplay.getLocale(),
935                                    "the-company-id-associated-with-the-assets"));
936                    definitionTerms.put(
937                            "[$COMPANY_MX$]",
938                            LanguageUtil.get(
939                                    themeDisplay.getLocale(),
940                                    "the-company-mx-associated-with-the-assets"));
941                    definitionTerms.put(
942                            "[$COMPANY_NAME$]",
943                            LanguageUtil.get(
944                                    themeDisplay.getLocale(),
945                                    "the-company-name-associated-with-the-assets"));
946                    definitionTerms.put(
947                            "[$FROM_ADDRESS$]", HtmlUtil.escape(emailFromAddress));
948                    definitionTerms.put("[$FROM_NAME$]", HtmlUtil.escape(emailFromName));
949    
950                    Company company = themeDisplay.getCompany();
951    
952                    definitionTerms.put("[$PORTAL_URL$]", company.getVirtualHostname());
953    
954                    definitionTerms.put(
955                            "[$PORTLET_NAME$]", PortalUtil.getPortletTitle(portletRequest));
956                    definitionTerms.put(
957                            "[$SITE_NAME$]",
958                            LanguageUtil.get(
959                                    themeDisplay.getLocale(),
960                                    "the-site-name-associated-with-the-assets"));
961                    definitionTerms.put(
962                            "[$TO_ADDRESS$]",
963                            LanguageUtil.get(
964                                    themeDisplay.getLocale(),
965                                    "the-address-of-the-email-recipient"));
966                    definitionTerms.put(
967                            "[$TO_NAME$]",
968                            LanguageUtil.get(
969                                    themeDisplay.getLocale(), "the-name-of-the-email-recipient"));
970    
971                    return definitionTerms;
972            }
973    
974            @Override
975            public String getEmailFromAddress(
976                    PortletPreferences portletPreferences, long companyId) {
977    
978                    return PortalUtil.getEmailFromAddress(
979                            portletPreferences, companyId,
980                            PropsValues.ASSET_PUBLISHER_EMAIL_FROM_ADDRESS);
981            }
982    
983            @Override
984            public String getEmailFromName(
985                    PortletPreferences portletPreferences, long companyId) {
986    
987                    return PortalUtil.getEmailFromName(
988                            portletPreferences, companyId,
989                            PropsValues.ASSET_PUBLISHER_EMAIL_FROM_NAME);
990            }
991    
992            @Override
993            public long getGroupIdFromScopeId(
994                            String scopeId, long siteGroupId, boolean privateLayout)
995                    throws PortalException {
996    
997                    if (scopeId.startsWith(SCOPE_ID_CHILD_GROUP_PREFIX)) {
998                            String scopeIdSuffix = scopeId.substring(
999                                    SCOPE_ID_CHILD_GROUP_PREFIX.length());
1000    
1001                            long childGroupId = GetterUtil.getLong(scopeIdSuffix);
1002    
1003                            Group childGroup = GroupLocalServiceUtil.getGroup(childGroupId);
1004    
1005                            if (!childGroup.hasAncestor(siteGroupId)) {
1006                                    throw new PrincipalException();
1007                            }
1008    
1009                            return childGroupId;
1010                    }
1011                    else if (scopeId.startsWith(SCOPE_ID_GROUP_PREFIX)) {
1012                            String scopeIdSuffix = scopeId.substring(
1013                                    SCOPE_ID_GROUP_PREFIX.length());
1014    
1015                            if (scopeIdSuffix.equals(GroupConstants.DEFAULT)) {
1016                                    return siteGroupId;
1017                            }
1018    
1019                            long scopeGroupId = GetterUtil.getLong(scopeIdSuffix);
1020    
1021                            Group scopeGroup = GroupLocalServiceUtil.fetchGroup(scopeGroupId);
1022    
1023                            if (scopeGroup == null) {
1024                                    throw new PrincipalException();
1025                            }
1026    
1027                            return scopeGroupId;
1028                    }
1029                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_UUID_PREFIX)) {
1030                            String layoutUuid = scopeId.substring(
1031                                    SCOPE_ID_LAYOUT_UUID_PREFIX.length());
1032    
1033                            Layout scopeIdLayout =
1034                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1035                                            layoutUuid, siteGroupId, privateLayout);
1036    
1037                            Group scopeIdGroup = null;
1038    
1039                            if (scopeIdLayout.hasScopeGroup()) {
1040                                    scopeIdGroup = scopeIdLayout.getScopeGroup();
1041                            }
1042                            else {
1043                                    scopeIdGroup = GroupLocalServiceUtil.addGroup(
1044                                            PrincipalThreadLocal.getUserId(),
1045                                            GroupConstants.DEFAULT_PARENT_GROUP_ID,
1046                                            Layout.class.getName(), scopeIdLayout.getPlid(),
1047                                            GroupConstants.DEFAULT_LIVE_GROUP_ID,
1048                                            String.valueOf(scopeIdLayout.getPlid()), null, 0, true,
1049                                            GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, false,
1050                                            true, null);
1051                            }
1052    
1053                            return scopeIdGroup.getGroupId();
1054                    }
1055                    else if (scopeId.startsWith(SCOPE_ID_LAYOUT_PREFIX)) {
1056    
1057                            // Legacy portlet preferences
1058    
1059                            String scopeIdSuffix = scopeId.substring(
1060                                    SCOPE_ID_LAYOUT_PREFIX.length());
1061    
1062                            long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
1063    
1064                            Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
1065                                    siteGroupId, privateLayout, scopeIdLayoutId);
1066    
1067                            Group scopeIdGroup = scopeIdLayout.getScopeGroup();
1068    
1069                            return scopeIdGroup.getGroupId();
1070                    }
1071                    else if (scopeId.startsWith(SCOPE_ID_PARENT_GROUP_PREFIX)) {
1072                            String scopeIdSuffix = scopeId.substring(
1073                                    SCOPE_ID_PARENT_GROUP_PREFIX.length());
1074    
1075                            long parentGroupId = GetterUtil.getLong(scopeIdSuffix);
1076    
1077                            Group parentGroup = GroupLocalServiceUtil.getGroup(parentGroupId);
1078    
1079                            if (!SitesUtil.isContentSharingWithChildrenEnabled(parentGroup)) {
1080                                    throw new PrincipalException();
1081                            }
1082    
1083                            Group group = GroupLocalServiceUtil.getGroup(siteGroupId);
1084    
1085                            if (!group.hasAncestor(parentGroupId)) {
1086                                    throw new PrincipalException();
1087                            }
1088    
1089                            return parentGroupId;
1090                    }
1091                    else {
1092                            throw new IllegalArgumentException("Invalid scope ID " + scopeId);
1093                    }
1094            }
1095    
1096            @Override
1097            public long[] getGroupIds(
1098                    PortletPreferences portletPreferences, long scopeGroupId,
1099                    Layout layout) {
1100    
1101                    String[] scopeIds = portletPreferences.getValues(
1102                            "scopeIds", new String[] {SCOPE_ID_GROUP_PREFIX + scopeGroupId});
1103    
1104                    List<Long> groupIds = new ArrayList<Long>();
1105    
1106                    for (String scopeId : scopeIds) {
1107                            try {
1108                                    long groupId = getGroupIdFromScopeId(
1109                                            scopeId, scopeGroupId, layout.isPrivateLayout());
1110    
1111                                    groupIds.add(groupId);
1112                            }
1113                            catch (Exception e) {
1114                                    continue;
1115                            }
1116                    }
1117    
1118                    return ArrayUtil.toLongArray(groupIds);
1119            }
1120    
1121            @Override
1122            public long getRecentFolderId(
1123                    PortletRequest portletRequest, String className) {
1124    
1125                    Long classPK = _getRecentFolderIds(portletRequest).get(className);
1126    
1127                    if (classPK == null) {
1128                            return 0;
1129                    }
1130                    else {
1131                            return classPK.longValue();
1132                    }
1133            }
1134    
1135            @Override
1136            public String getScopeId(Group group, long scopeGroupId)
1137                    throws PortalException {
1138    
1139                    String key = null;
1140    
1141                    if (group.isLayout()) {
1142                            Layout layout = LayoutLocalServiceUtil.getLayout(
1143                                    group.getClassPK());
1144    
1145                            key = SCOPE_ID_LAYOUT_UUID_PREFIX + layout.getUuid();
1146                    }
1147                    else if (group.isLayoutPrototype() ||
1148                                     (group.getGroupId() == scopeGroupId)) {
1149    
1150                            key = SCOPE_ID_GROUP_PREFIX + GroupConstants.DEFAULT;
1151                    }
1152                    else {
1153                            Group scopeGroup = GroupLocalServiceUtil.getGroup(scopeGroupId);
1154    
1155                            if (scopeGroup.hasAncestor(group.getGroupId()) &&
1156                                    SitesUtil.isContentSharingWithChildrenEnabled(group)) {
1157    
1158                                    key = SCOPE_ID_PARENT_GROUP_PREFIX + group.getGroupId();
1159                            }
1160                            else if (group.hasAncestor(scopeGroup.getGroupId())) {
1161                                    key = SCOPE_ID_CHILD_GROUP_PREFIX + group.getGroupId();
1162                            }
1163                            else {
1164                                    key = SCOPE_ID_GROUP_PREFIX + group.getGroupId();
1165                            }
1166                    }
1167    
1168                    return key;
1169            }
1170    
1171            @Override
1172            public long getSubscriptionClassPK(long plid, String portletId)
1173                    throws PortalException {
1174    
1175                    com.liferay.portal.model.PortletPreferences portletPreferencesModel =
1176                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1177                                    PortletKeys.PREFS_OWNER_ID_DEFAULT,
1178                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, plid, portletId);
1179    
1180                    return portletPreferencesModel.getPortletPreferencesId();
1181            }
1182    
1183            @Override
1184            public boolean isScopeIdSelectable(
1185                            PermissionChecker permissionChecker, String scopeId,
1186                            long companyGroupId, Layout layout)
1187                    throws PortalException {
1188    
1189                    long groupId = getGroupIdFromScopeId(
1190                            scopeId, layout.getGroupId(), layout.isPrivateLayout());
1191    
1192                    if (scopeId.startsWith(SCOPE_ID_CHILD_GROUP_PREFIX)) {
1193                            Group group = GroupLocalServiceUtil.getGroup(groupId);
1194    
1195                            if (!group.hasAncestor(layout.getGroupId())) {
1196                                    return false;
1197                            }
1198                    }
1199                    else if (scopeId.startsWith(SCOPE_ID_PARENT_GROUP_PREFIX)) {
1200                            Group siteGroup = layout.getGroup();
1201    
1202                            if (!siteGroup.hasAncestor(groupId)) {
1203                                    return false;
1204                            }
1205    
1206                            Group group = GroupLocalServiceUtil.getGroup(groupId);
1207    
1208                            if (SitesUtil.isContentSharingWithChildrenEnabled(group)) {
1209                                    return true;
1210                            }
1211    
1212                            if (!PrefsPropsUtil.getBoolean(
1213                                            layout.getCompanyId(),
1214                                            PropsKeys.
1215                                            SITES_CONTENT_SHARING_THROUGH_ADMINISTRATORS_ENABLED)) {
1216    
1217                                    return false;
1218                            }
1219    
1220                            return GroupPermissionUtil.contains(
1221                                    permissionChecker, group, ActionKeys.UPDATE);
1222                    }
1223                    else if (groupId != companyGroupId) {
1224                            return GroupPermissionUtil.contains(
1225                                    permissionChecker, groupId, ActionKeys.UPDATE);
1226                    }
1227    
1228                    return true;
1229            }
1230    
1231            @Override
1232            public boolean isSubscribed(
1233                            long companyId, long userId, long plid, String portletId)
1234                    throws PortalException {
1235    
1236                    return SubscriptionLocalServiceUtil.isSubscribed(
1237                            companyId, userId,
1238                            com.liferay.portal.model.PortletPreferences.class.getName(),
1239                            getSubscriptionClassPK(plid, portletId));
1240            }
1241    
1242            @Override
1243            public void notifySubscribers(
1244                            PortletPreferences portletPreferences, long plid, String portletId,
1245                            List<AssetEntry> assetEntries)
1246                    throws PortalException {
1247    
1248                    if (!getEmailAssetEntryAddedEnabled(portletPreferences) ||
1249                            assetEntries.isEmpty()) {
1250    
1251                            return;
1252                    }
1253    
1254                    AssetEntry assetEntry = assetEntries.get(0);
1255    
1256                    String fromName = getEmailFromName(
1257                            portletPreferences, assetEntry.getCompanyId());
1258                    String fromAddress = getEmailFromAddress(
1259                            portletPreferences, assetEntry.getCompanyId());
1260    
1261                    Map<Locale, String> localizedSubjectMap =
1262                            getEmailAssetEntryAddedSubjectMap(portletPreferences);
1263                    Map<Locale, String> localizedBodyMap = getEmailAssetEntryAddedBodyMap(
1264                            portletPreferences);
1265    
1266                    SubscriptionSender subscriptionSender = new SubscriptionSender();
1267    
1268                    subscriptionSender.setCompanyId(assetEntry.getCompanyId());
1269                    subscriptionSender.setContextAttributes(
1270                            "[$ASSET_ENTRIES$]",
1271                            ListUtil.toString(
1272                                    assetEntries, _titleAccessor, StringPool.COMMA_AND_SPACE));
1273                    subscriptionSender.setContextUserPrefix("ASSET_PUBLISHER");
1274                    subscriptionSender.setFrom(fromAddress, fromName);
1275                    subscriptionSender.setHtmlFormat(true);
1276                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
1277                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
1278                    subscriptionSender.setMailId("asset_entry", assetEntry.getEntryId());
1279                    subscriptionSender.setPortletId(PortletKeys.ASSET_PUBLISHER);
1280                    subscriptionSender.setReplyToAddress(fromAddress);
1281    
1282                    subscriptionSender.addPersistedSubscribers(
1283                            com.liferay.portal.model.PortletPreferences.class.getName(),
1284                            getSubscriptionClassPK(plid, portletId));
1285    
1286                    subscriptionSender.flushNotificationsAsync();
1287            }
1288    
1289            @Override
1290            public void processAssetEntryQuery(
1291                            User user, PortletPreferences portletPreferences,
1292                            AssetEntryQuery assetEntryQuery)
1293                    throws Exception {
1294    
1295                    for (AssetEntryQueryProcessor assetEntryQueryProcessor :
1296                                    _assetEntryQueryProcessor.values()) {
1297    
1298                            assetEntryQueryProcessor.processAssetEntryQuery(
1299                                    user, portletPreferences, assetEntryQuery);
1300                    }
1301            }
1302    
1303            @Override
1304            public void registerAssetQueryProcessor(
1305                    String assetQueryProcessorClassName,
1306                    AssetEntryQueryProcessor assetQueryProcessor) {
1307    
1308                    if (assetQueryProcessor == null) {
1309                            return;
1310                    }
1311    
1312                    _assetEntryQueryProcessor.put(
1313                            assetQueryProcessorClassName, assetQueryProcessor);
1314            }
1315    
1316            @Override
1317            public void removeAndStoreSelection(
1318                            List<String> assetEntryUuids, PortletPreferences portletPreferences)
1319                    throws Exception {
1320    
1321                    if (assetEntryUuids.isEmpty()) {
1322                            return;
1323                    }
1324    
1325                    String[] assetEntryXmls = portletPreferences.getValues(
1326                            "assetEntryXml", new String[0]);
1327    
1328                    List<String> assetEntryXmlsList = ListUtil.fromArray(assetEntryXmls);
1329    
1330                    Iterator<String> itr = assetEntryXmlsList.iterator();
1331    
1332                    while (itr.hasNext()) {
1333                            String assetEntryXml = itr.next();
1334    
1335                            Document document = SAXReaderUtil.read(assetEntryXml);
1336    
1337                            Element rootElement = document.getRootElement();
1338    
1339                            String assetEntryUuid = rootElement.elementText("asset-entry-uuid");
1340    
1341                            if (assetEntryUuids.contains(assetEntryUuid)) {
1342                                    itr.remove();
1343                            }
1344                    }
1345    
1346                    portletPreferences.setValues(
1347                            "assetEntryXml",
1348                            assetEntryXmlsList.toArray(new String[assetEntryXmlsList.size()]));
1349    
1350                    portletPreferences.store();
1351            }
1352    
1353            @Override
1354            public void removeRecentFolderId(
1355                    PortletRequest portletRequest, String className, long classPK) {
1356    
1357                    if (getRecentFolderId(portletRequest, className) == classPK) {
1358                            _getRecentFolderIds(portletRequest).remove(className);
1359                    }
1360            }
1361    
1362            @Override
1363            public void subscribe(
1364                            PermissionChecker permissionChecker, long groupId, long plid,
1365                            String portletId)
1366                    throws PortalException {
1367    
1368                    PortletPermissionUtil.check(
1369                            permissionChecker, plid, portletId, ActionKeys.SUBSCRIBE);
1370    
1371                    SubscriptionLocalServiceUtil.addSubscription(
1372                            permissionChecker.getUserId(), groupId,
1373                            com.liferay.portal.model.PortletPreferences.class.getName(),
1374                            getSubscriptionClassPK(plid, portletId));
1375            }
1376    
1377            @Override
1378            public void unregisterAssetQueryProcessor(
1379                    String assetQueryProcessorClassName) {
1380    
1381                    _assetEntryQueryProcessor.remove(assetQueryProcessorClassName);
1382            }
1383    
1384            @Override
1385            public void unsubscribe(
1386                            PermissionChecker permissionChecker, long plid, String portletId)
1387                    throws PortalException {
1388    
1389                    PortletPermissionUtil.check(
1390                            permissionChecker, plid, portletId, ActionKeys.SUBSCRIBE);
1391    
1392                    SubscriptionLocalServiceUtil.deleteSubscription(
1393                            permissionChecker.getUserId(),
1394                            com.liferay.portal.model.PortletPreferences.class.getName(),
1395                            getSubscriptionClassPK(plid, portletId));
1396            }
1397    
1398            protected long[] getSiteGroupIds(long[] groupIds) throws PortalException {
1399                    Set<Long> siteGroupIds = new HashSet<Long>();
1400    
1401                    for (long groupId : groupIds) {
1402                            siteGroupIds.add(PortalUtil.getSiteGroupId(groupId));
1403                    }
1404    
1405                    return ArrayUtil.toLongArray(siteGroupIds);
1406            }
1407    
1408            private void _checkAssetEntries(
1409                            com.liferay.portal.model.PortletPreferences
1410                                    portletPreferencesModel)
1411                    throws PortalException {
1412    
1413                    Layout layout = LayoutLocalServiceUtil.getLayout(
1414                            portletPreferencesModel.getPlid());
1415    
1416                    PortletPreferences portletPreferences =
1417                            PortletPreferencesFactoryUtil.fromXML(
1418                                    layout.getCompanyId(), portletPreferencesModel.getOwnerId(),
1419                                    portletPreferencesModel.getOwnerType(),
1420                                    portletPreferencesModel.getPlid(),
1421                                    portletPreferencesModel.getPortletId(),
1422                                    portletPreferencesModel.getPreferences());
1423    
1424                    if (!getEmailAssetEntryAddedEnabled(portletPreferences)) {
1425                            return;
1426                    }
1427    
1428                    List<AssetEntry> assetEntries = getAssetEntries(
1429                            portletPreferences, layout, layout.getGroupId(),
1430                            PropsValues.ASSET_PUBLISHER_DYNAMIC_SUBSCRIPTION_LIMIT, false);
1431    
1432                    if (assetEntries.isEmpty()) {
1433                            return;
1434                    }
1435    
1436                    long[] notifiedAssetEntryIds = GetterUtil.getLongValues(
1437                            portletPreferences.getValues("notifiedAssetEntryIds", null));
1438    
1439                    List<AssetEntry> newAssetEntries = new ArrayList<AssetEntry>();
1440    
1441                    for (int i = 0; i < assetEntries.size(); i++) {
1442                            AssetEntry assetEntry = assetEntries.get(i);
1443    
1444                            if (!ArrayUtil.contains(
1445                                            notifiedAssetEntryIds, assetEntry.getEntryId())) {
1446    
1447                                    newAssetEntries.add(assetEntry);
1448                            }
1449                    }
1450    
1451                    notifySubscribers(
1452                            portletPreferences, portletPreferencesModel.getPlid(),
1453                            portletPreferencesModel.getPortletId(), newAssetEntries);
1454    
1455                    try {
1456                            portletPreferences.setValues(
1457                                    "notifiedAssetEntryIds",
1458                                    StringUtil.split(
1459                                            ListUtil.toString(
1460                                                    assetEntries, AssetEntry.ENTRY_ID_ACCESSOR)));
1461    
1462                            portletPreferences.store();
1463                    }
1464                    catch (IOException ioe) {
1465                            throw new SystemException(ioe);
1466                    }
1467                    catch (PortletException pe) {
1468                            throw new SystemException(pe);
1469                    }
1470            }
1471    
1472            private List<AssetEntry> _filterAssetCategoriesAssetEntries(
1473                            List<AssetEntry> assetEntries, long[] assetCategoryIds)
1474                    throws Exception {
1475    
1476                    List<AssetEntry> filteredAssetEntries = new ArrayList<AssetEntry>();
1477    
1478                    for (AssetEntry assetEntry : assetEntries) {
1479                            if (ArrayUtil.containsAll(
1480                                            assetEntry.getCategoryIds(), assetCategoryIds)) {
1481    
1482                                    filteredAssetEntries.add(assetEntry);
1483                            }
1484                    }
1485    
1486                    return filteredAssetEntries;
1487            }
1488    
1489            private List<AssetEntry> _filterAssetTagNamesAssetEntries(
1490                            List<AssetEntry> assetEntries, String[] assetTagNames)
1491                    throws Exception {
1492    
1493                    List<AssetEntry> filteredAssetEntries = new ArrayList<AssetEntry>();
1494    
1495                    for (AssetEntry assetEntry : assetEntries) {
1496                            List<AssetTag> assetTags = assetEntry.getTags();
1497    
1498                            String[] assetEntryAssetTagNames = new String[assetTags.size()];
1499    
1500                            for (int i = 0; i < assetTags.size(); i++) {
1501                                    AssetTag assetTag = assetTags.get(i);
1502    
1503                                    assetEntryAssetTagNames[i] = assetTag.getName();
1504                            }
1505    
1506                            if (ArrayUtil.containsAll(assetEntryAssetTagNames, assetTagNames)) {
1507                                    filteredAssetEntries.add(assetEntry);
1508                            }
1509                    }
1510    
1511                    return filteredAssetEntries;
1512            }
1513    
1514            private String _getAssetEntryXml(
1515                    String assetEntryType, String assetEntryUuid) {
1516    
1517                    String xml = null;
1518    
1519                    try {
1520                            Document document = SAXReaderUtil.createDocument(StringPool.UTF8);
1521    
1522                            Element assetEntryElement = document.addElement("asset-entry");
1523    
1524                            Element assetEntryTypeElement = assetEntryElement.addElement(
1525                                    "asset-entry-type");
1526    
1527                            assetEntryTypeElement.addText(assetEntryType);
1528    
1529                            Element assetEntryUuidElement = assetEntryElement.addElement(
1530                                    "asset-entry-uuid");
1531    
1532                            assetEntryUuidElement.addText(assetEntryUuid);
1533    
1534                            xml = document.formattedString(StringPool.BLANK);
1535                    }
1536                    catch (IOException ioe) {
1537                            if (_log.isWarnEnabled()) {
1538                                    _log.warn(ioe);
1539                            }
1540                    }
1541    
1542                    return xml;
1543            }
1544    
1545            private Map<String, Long> _getRecentFolderIds(
1546                    PortletRequest portletRequest) {
1547    
1548                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
1549                            portletRequest);
1550                    HttpSession session = request.getSession();
1551    
1552                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1553                            WebKeys.THEME_DISPLAY);
1554    
1555                    String key =
1556                            AssetPublisherUtil.class + StringPool.UNDERLINE +
1557                                    themeDisplay.getScopeGroupId();
1558    
1559                    Map<String, Long> recentFolderIds =
1560                            (Map<String, Long>)session.getAttribute(key);
1561    
1562                    if (recentFolderIds == null) {
1563                            recentFolderIds = new HashMap<String, Long>();
1564                    }
1565    
1566                    session.setAttribute(key, recentFolderIds);
1567    
1568                    return recentFolderIds;
1569            }
1570    
1571            private static Log _log = LogFactoryUtil.getLog(AssetPublisherImpl.class);
1572    
1573            private Map<String, AssetEntryQueryProcessor> _assetEntryQueryProcessor =
1574                    new ConcurrentHashMap<String, AssetEntryQueryProcessor>();
1575    
1576            private Accessor<AssetEntry, String> _titleAccessor =
1577                    new Accessor<AssetEntry, String>() {
1578    
1579                            @Override
1580                            public String get(AssetEntry assetEntry) {
1581                                    return assetEntry.getTitle(LocaleUtil.getSiteDefault());
1582                            }
1583    
1584                            @Override
1585                            public Class<String> getAttributeClass() {
1586                                    return String.class;
1587                            }
1588    
1589                            @Override
1590                            public Class<AssetEntry> getTypeClass() {
1591                                    return AssetEntry.class;
1592                            }
1593    
1594                    };
1595    
1596    }