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.lar;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.kernel.lar.DataLevel;
019    import com.liferay.portal.kernel.lar.DefaultConfigurationPortletDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.model.Company;
028    import com.liferay.portal.model.Group;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.Portlet;
031    import com.liferay.portal.security.auth.PrincipalException;
032    import com.liferay.portal.security.permission.PermissionThreadLocal;
033    import com.liferay.portal.service.CompanyLocalServiceUtil;
034    import com.liferay.portal.service.LayoutLocalServiceUtil;
035    import com.liferay.portal.service.PortletLocalServiceUtil;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portlet.asset.model.AssetCategory;
038    import com.liferay.portlet.asset.model.AssetVocabulary;
039    import com.liferay.portlet.assetpublisher.util.AssetPublisher;
040    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
041    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
042    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
043    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
044    import com.liferay.portlet.journal.model.JournalArticle;
045    
046    import java.util.ArrayList;
047    import java.util.Enumeration;
048    import java.util.List;
049    
050    import javax.portlet.PortletPreferences;
051    
052    /**
053     * @author Julio Camarero
054     */
055    public class AssetPublisherPortletDataHandler
056            extends DefaultConfigurationPortletDataHandler {
057    
058            public AssetPublisherPortletDataHandler() {
059                    setDataLevel(DataLevel.PORTLET_INSTANCE);
060                    setPublishToLiveByDefault(true);
061            }
062    
063            @Override
064            protected PortletPreferences doProcessExportPortletPreferences(
065                            PortletDataContext portletDataContext, String portletId,
066                            PortletPreferences portletPreferences)
067                    throws Exception {
068    
069                    return updateExportPortletPreferences(
070                            portletDataContext, portletId, portletPreferences);
071            }
072    
073            @Override
074            protected PortletPreferences doProcessImportPortletPreferences(
075                            PortletDataContext portletDataContext, String portletId,
076                            PortletPreferences portletPreferences)
077                    throws Exception {
078    
079                    return updateImportPortletPreferences(
080                            portletDataContext, portletId, portletPreferences);
081            }
082    
083            protected void updateExportClassNameIds(
084                            PortletPreferences portletPreferences, String key)
085                    throws Exception {
086    
087                    String[] oldValues = portletPreferences.getValues(key, null);
088    
089                    if (oldValues == null) {
090                            return;
091                    }
092    
093                    String[] newValues = new String[oldValues.length];
094    
095                    int i = 0;
096    
097                    for (String oldValue : oldValues) {
098                            if (key.equals("anyAssetType") &&
099                                    (oldValue.equals("false") || oldValue.equals("true"))) {
100    
101                                    newValues[i++] = oldValue;
102    
103                                    continue;
104                            }
105    
106                            try {
107                                    long classNameId = GetterUtil.getLong(oldValue);
108    
109                                    String className = PortalUtil.getClassName(classNameId);
110    
111                                    newValues[i++] = className;
112                            }
113                            catch (Exception e) {
114                                    if (_log.isWarnEnabled()) {
115                                            _log.warn(
116                                                    "Unable to get class name ID for class name " +
117                                                            oldValue);
118                                    }
119                            }
120                    }
121    
122                    portletPreferences.setValues(key, newValues);
123            }
124    
125            protected PortletPreferences updateExportPortletPreferences(
126                            PortletDataContext portletDataContext, String portletId,
127                            PortletPreferences portletPreferences)
128                    throws Exception {
129    
130                    String anyAssetTypeClassName = StringPool.BLANK;
131    
132                    long anyAssetType = GetterUtil.getLong(
133                            portletPreferences.getValue("anyAssetType", null));
134    
135                    if (anyAssetType > 0) {
136                            anyAssetTypeClassName = PortalUtil.getClassName(anyAssetType);
137                    }
138    
139                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
140                            portletDataContext.getCompanyId(), portletId);
141    
142                    Enumeration<String> enu = portletPreferences.getNames();
143    
144                    while (enu.hasMoreElements()) {
145                            String name = enu.nextElement();
146    
147                            String value = GetterUtil.getString(
148                                    portletPreferences.getValue(name, null));
149    
150                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
151                                    updateExportClassNameIds(portletPreferences, name);
152                            }
153                            else if (name.equals(
154                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
155                                             (name.equals("classTypeIds") &&
156                                              anyAssetTypeClassName.equals(
157                                                      DLFileEntry.class.getName())) ||
158                                             name.equals(
159                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
160    
161                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
162                                            portletDataContext, portlet, portletPreferences, name,
163                                            DLFileEntryType.class.getName());
164                            }
165                            else if (name.equals(
166                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
167                                             (name.equals("classTypeIds") &&
168                                              anyAssetTypeClassName.equals(
169                                                      JournalArticle.class.getName())) ||
170                                             name.equals(
171                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
172    
173                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
174                                            portletDataContext, portlet, portletPreferences, name,
175                                            DDMStructure.class.getName());
176                            }
177                            else if (name.equals("assetVocabularyId")) {
178                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
179                                            portletDataContext, portlet, portletPreferences, name,
180                                            AssetVocabulary.class.getName());
181                            }
182                            else if (name.startsWith("queryName") &&
183                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
184    
185                                    String index = name.substring(9);
186    
187                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
188                                            portletDataContext, portlet, portletPreferences,
189                                            "queryValues" + index, AssetCategory.class.getName());
190                            }
191                            else if (name.equals("scopeIds")) {
192                                    updateExportScopeIds(
193                                            portletDataContext, portletPreferences, name,
194                                            portletDataContext.getPlid());
195                            }
196                    }
197    
198                    return portletPreferences;
199            }
200    
201            protected void updateExportScopeIds(
202                            PortletDataContext portletDataContext,
203                            PortletPreferences portletPreferences, String key, long plid)
204                    throws Exception {
205    
206                    String[] oldValues = portletPreferences.getValues(key, null);
207    
208                    if (oldValues == null) {
209                            return;
210                    }
211    
212                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
213    
214                    String companyGroupScopeId =
215                            AssetPublisher.SCOPE_ID_GROUP_PREFIX +
216                                    portletDataContext.getCompanyGroupId();
217    
218                    String[] newValues = new String[oldValues.length];
219    
220                    for (int i = 0; i < oldValues.length; i++) {
221                            String oldValue = oldValues[i];
222    
223                            if (oldValue.startsWith(AssetPublisher.SCOPE_ID_GROUP_PREFIX)) {
224                                    newValues[i] = StringUtil.replace(
225                                            oldValue, companyGroupScopeId,
226                                            "[$COMPANY_GROUP_SCOPE_ID$]");
227                            }
228                            else if (oldValue.startsWith(
229                                                    AssetPublisher.SCOPE_ID_LAYOUT_PREFIX)) {
230    
231                                    // Legacy preferences
232    
233                                    String scopeIdSuffix = oldValue.substring(
234                                            AssetPublisher.SCOPE_ID_LAYOUT_PREFIX.length());
235    
236                                    long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
237    
238                                    Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
239                                            layout.getGroupId(), layout.isPrivateLayout(),
240                                            scopeIdLayoutId);
241    
242                                    newValues[i] =
243                                            AssetPublisher.SCOPE_ID_LAYOUT_UUID_PREFIX +
244                                                    scopeIdLayout.getUuid();
245                            }
246                            else {
247                                    newValues[i] = oldValue;
248                            }
249                    }
250    
251                    portletPreferences.setValues(key, newValues);
252            }
253    
254            protected void updateImportClassNameIds(
255                            PortletPreferences portletPreferences, String key)
256                    throws Exception {
257    
258                    String[] oldValues = portletPreferences.getValues(key, null);
259    
260                    if (oldValues == null) {
261                            return;
262                    }
263    
264                    String[] newValues = new String[oldValues.length];
265    
266                    int i = 0;
267    
268                    for (String oldValue : oldValues) {
269                            if (key.equals("anyAssetType") &&
270                                    (oldValue.equals("false") || oldValue.equals("true"))) {
271    
272                                    newValues[i++] = oldValue;
273    
274                                    continue;
275                            }
276    
277                            try {
278                                    long classNameId = PortalUtil.getClassNameId(oldValue);
279    
280                                    newValues[i++] = String.valueOf(classNameId);
281                            }
282                            catch (Exception e) {
283                                    if (_log.isWarnEnabled()) {
284                                            _log.warn(
285                                                    "Unable to find class name ID for class name " +
286                                                            oldValue);
287                                    }
288                            }
289                    }
290    
291                    portletPreferences.setValues(key, newValues);
292            }
293    
294            protected PortletPreferences updateImportPortletPreferences(
295                            PortletDataContext portletDataContext, String portletId,
296                            PortletPreferences portletPreferences)
297                    throws Exception {
298    
299                    Company company = CompanyLocalServiceUtil.getCompanyById(
300                            portletDataContext.getCompanyId());
301    
302                    Group companyGroup = company.getGroup();
303    
304                    String anyAssetTypeClassName = portletPreferences.getValue(
305                            "anyAssetType", StringPool.BLANK);
306    
307                    Enumeration<String> enu = portletPreferences.getNames();
308    
309                    while (enu.hasMoreElements()) {
310                            String name = enu.nextElement();
311    
312                            String value = GetterUtil.getString(
313                                    portletPreferences.getValue(name, null));
314    
315                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
316                                    updateImportClassNameIds(portletPreferences, name);
317                            }
318                            else if (name.equals(
319                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
320                                             (name.equals("classTypeIds") &&
321                                              anyAssetTypeClassName.equals(
322                                                      DLFileEntry.class.getName())) ||
323                                             name.equals(
324                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
325    
326                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
327                                            portletDataContext, portletPreferences, name,
328                                            DLFileEntryType.class, companyGroup.getGroupId());
329                            }
330                            else if (name.equals(
331                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
332                                             (name.equals("classTypeIds") &&
333                                              anyAssetTypeClassName.equals(
334                                                      JournalArticle.class.getName())) ||
335                                             name.equals(
336                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
337    
338                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
339                                            portletDataContext, portletPreferences, name,
340                                            DDMStructure.class, companyGroup.getGroupId());
341                            }
342                            else if (name.equals("assetVocabularyId")) {
343                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
344                                            portletDataContext, portletPreferences, name,
345                                            AssetVocabulary.class, companyGroup.getGroupId());
346                            }
347                            else if (name.startsWith("queryName") &&
348                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
349    
350                                    String index = name.substring(9, name.length());
351    
352                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
353                                            portletDataContext, portletPreferences,
354                                            "queryValues" + index, AssetCategory.class,
355                                            companyGroup.getGroupId());
356                            }
357                            else if (name.equals("scopeIds")) {
358                                    updateImportScopeIds(
359                                            portletPreferences, name, companyGroup.getGroupId(),
360                                            portletDataContext.getPlid());
361                            }
362                    }
363    
364                    return portletPreferences;
365            }
366    
367            protected void updateImportScopeIds(
368                            PortletPreferences portletPreferences, String key,
369                            long companyGroupId, long plid)
370                    throws Exception {
371    
372                    String[] oldValues = portletPreferences.getValues(key, null);
373    
374                    if (oldValues == null) {
375                            return;
376                    }
377    
378                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
379    
380                    String companyGroupScopeId =
381                            AssetPublisher.SCOPE_ID_GROUP_PREFIX + companyGroupId;
382    
383                    List<String> newValues = new ArrayList<String>(oldValues.length);
384    
385                    for (String oldValue : oldValues) {
386                            String newValue = StringUtil.replace(
387                                    oldValue, "[$COMPANY_GROUP_SCOPE_ID$]", companyGroupScopeId);
388    
389                            try {
390                                    if (!AssetPublisherUtil.isScopeIdSelectable(
391                                                    PermissionThreadLocal.getPermissionChecker(), newValue,
392                                                    companyGroupId, layout)) {
393    
394                                            continue;
395                                    }
396    
397                                    newValues.add(newValue);
398                            }
399                            catch (NoSuchGroupException nsge) {
400                                    if (_log.isInfoEnabled()) {
401                                            _log.info(
402                                                    "Ignoring scope " + newValue + " because the " +
403                                                            "referenced group was not found");
404                                    }
405                            }
406                            catch (PrincipalException pe) {
407                                    if (_log.isInfoEnabled()) {
408                                            _log.info(
409                                                    "Ignoring scope " + newValue + " because the " +
410                                                            "referenced parent group no longer allows " +
411                                                                    "sharing content with child sites");
412                                    }
413                            }
414                    }
415    
416                    portletPreferences.setValues(
417                            key, newValues.toArray(new String[newValues.size()]));
418            }
419    
420            private static Log _log = LogFactoryUtil.getLog(
421                    AssetPublisherPortletDataHandler.class);
422    
423    }