001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.assetpublisher.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                                            portletDataContext.getExportDataRootElement());
165                            }
166                            else if (name.equals(
167                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
168                                             (name.equals("classTypeIds") &&
169                                              anyAssetTypeClassName.equals(
170                                                      JournalArticle.class.getName())) ||
171                                             name.equals(
172                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
173    
174                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
175                                            portletDataContext, portlet, portletPreferences, name,
176                                            DDMStructure.class.getName(),
177                                            portletDataContext.getExportDataRootElement());
178                            }
179                            else if (name.equals("assetVocabularyId")) {
180                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
181                                            portletDataContext, portlet, portletPreferences, name,
182                                            AssetVocabulary.class.getName(),
183                                            portletDataContext.getExportDataRootElement());
184                            }
185                            else if (name.startsWith("queryName") &&
186                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
187    
188                                    String index = name.substring(9);
189    
190                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
191                                            portletDataContext, portlet, portletPreferences,
192                                            "queryValues" + index, AssetCategory.class.getName(),
193                                            portletDataContext.getExportDataRootElement());
194                            }
195                            else if (name.equals("scopeIds")) {
196                                    updateExportScopeIds(
197                                            portletDataContext, portletPreferences, name,
198                                            portletDataContext.getPlid());
199                            }
200                    }
201    
202                    return portletPreferences;
203            }
204    
205            protected void updateExportScopeIds(
206                            PortletDataContext portletDataContext,
207                            PortletPreferences portletPreferences, String key, long plid)
208                    throws Exception {
209    
210                    String[] oldValues = portletPreferences.getValues(key, null);
211    
212                    if (oldValues == null) {
213                            return;
214                    }
215    
216                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
217    
218                    String companyGroupScopeId =
219                            AssetPublisher.SCOPE_ID_GROUP_PREFIX +
220                                    portletDataContext.getCompanyGroupId();
221    
222                    String[] newValues = new String[oldValues.length];
223    
224                    for (int i = 0; i < oldValues.length; i++) {
225                            String oldValue = oldValues[i];
226    
227                            if (oldValue.startsWith(AssetPublisher.SCOPE_ID_GROUP_PREFIX)) {
228                                    newValues[i] = StringUtil.replace(
229                                            oldValue, companyGroupScopeId,
230                                            "[$COMPANY_GROUP_SCOPE_ID$]");
231                            }
232                            else if (oldValue.startsWith(
233                                                    AssetPublisher.SCOPE_ID_LAYOUT_PREFIX)) {
234    
235                                    // Legacy preferences
236    
237                                    String scopeIdSuffix = oldValue.substring(
238                                            AssetPublisher.SCOPE_ID_LAYOUT_PREFIX.length());
239    
240                                    long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
241    
242                                    Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
243                                            layout.getGroupId(), layout.isPrivateLayout(),
244                                            scopeIdLayoutId);
245    
246                                    newValues[i] =
247                                            AssetPublisher.SCOPE_ID_LAYOUT_UUID_PREFIX +
248                                                    scopeIdLayout.getUuid();
249                            }
250                            else {
251                                    newValues[i] = oldValue;
252                            }
253                    }
254    
255                    portletPreferences.setValues(key, newValues);
256            }
257    
258            protected void updateImportClassNameIds(
259                            PortletPreferences portletPreferences, String key)
260                    throws Exception {
261    
262                    String[] oldValues = portletPreferences.getValues(key, null);
263    
264                    if (oldValues == null) {
265                            return;
266                    }
267    
268                    String[] newValues = new String[oldValues.length];
269    
270                    int i = 0;
271    
272                    for (String oldValue : oldValues) {
273                            if (key.equals("anyAssetType") &&
274                                    (oldValue.equals("false") || oldValue.equals("true"))) {
275    
276                                    newValues[i++] = oldValue;
277    
278                                    continue;
279                            }
280    
281                            try {
282                                    long classNameId = PortalUtil.getClassNameId(oldValue);
283    
284                                    newValues[i++] = String.valueOf(classNameId);
285                            }
286                            catch (Exception e) {
287                                    if (_log.isWarnEnabled()) {
288                                            _log.warn(
289                                                    "Unable to find class name ID for class name " +
290                                                            oldValue);
291                                    }
292                            }
293                    }
294    
295                    portletPreferences.setValues(key, newValues);
296            }
297    
298            protected PortletPreferences updateImportPortletPreferences(
299                            PortletDataContext portletDataContext, String portletId,
300                            PortletPreferences portletPreferences)
301                    throws Exception {
302    
303                    Company company = CompanyLocalServiceUtil.getCompanyById(
304                            portletDataContext.getCompanyId());
305    
306                    Group companyGroup = company.getGroup();
307    
308                    String anyAssetTypeClassName = portletPreferences.getValue(
309                            "anyAssetType", StringPool.BLANK);
310    
311                    Enumeration<String> enu = portletPreferences.getNames();
312    
313                    while (enu.hasMoreElements()) {
314                            String name = enu.nextElement();
315    
316                            String value = GetterUtil.getString(
317                                    portletPreferences.getValue(name, null));
318    
319                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
320                                    updateImportClassNameIds(portletPreferences, name);
321                            }
322                            else if (name.equals(
323                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
324                                             (name.equals("classTypeIds") &&
325                                              anyAssetTypeClassName.equals(
326                                                      DLFileEntry.class.getName())) ||
327                                             name.equals(
328                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
329    
330                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
331                                            portletDataContext, portletPreferences, name,
332                                            DLFileEntryType.class, companyGroup.getGroupId());
333                            }
334                            else if (name.equals(
335                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
336                                             (name.equals("classTypeIds") &&
337                                              anyAssetTypeClassName.equals(
338                                                      JournalArticle.class.getName())) ||
339                                             name.equals(
340                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
341    
342                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
343                                            portletDataContext, portletPreferences, name,
344                                            DDMStructure.class, companyGroup.getGroupId());
345                            }
346                            else if (name.equals("assetVocabularyId")) {
347                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
348                                            portletDataContext, portletPreferences, name,
349                                            AssetVocabulary.class, companyGroup.getGroupId());
350                            }
351                            else if (name.startsWith("queryName") &&
352                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
353    
354                                    String index = name.substring(9, name.length());
355    
356                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
357                                            portletDataContext, portletPreferences,
358                                            "queryValues" + index, AssetCategory.class,
359                                            companyGroup.getGroupId());
360                            }
361                            else if (name.equals("scopeIds")) {
362                                    updateImportScopeIds(
363                                            portletPreferences, name, companyGroup.getGroupId(),
364                                            portletDataContext.getPlid());
365                            }
366                    }
367    
368                    return portletPreferences;
369            }
370    
371            protected void updateImportScopeIds(
372                            PortletPreferences portletPreferences, String key,
373                            long companyGroupId, long plid)
374                    throws Exception {
375    
376                    String[] oldValues = portletPreferences.getValues(key, null);
377    
378                    if (oldValues == null) {
379                            return;
380                    }
381    
382                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
383    
384                    String companyGroupScopeId =
385                            AssetPublisher.SCOPE_ID_GROUP_PREFIX + companyGroupId;
386    
387                    List<String> newValues = new ArrayList<String>(oldValues.length);
388    
389                    for (String oldValue : oldValues) {
390                            String newValue = StringUtil.replace(
391                                    oldValue, "[$COMPANY_GROUP_SCOPE_ID$]", companyGroupScopeId);
392    
393                            try {
394                                    if (!AssetPublisherUtil.isScopeIdSelectable(
395                                                    PermissionThreadLocal.getPermissionChecker(), newValue,
396                                                    companyGroupId, layout)) {
397    
398                                            continue;
399                                    }
400    
401                                    newValues.add(newValue);
402                            }
403                            catch (NoSuchGroupException nsge) {
404                                    if (_log.isInfoEnabled()) {
405                                            _log.info(
406                                                    "Ignoring scope " + newValue + " because the " +
407                                                            "referenced group was not found");
408                                    }
409                            }
410                            catch (PrincipalException pe) {
411                                    if (_log.isInfoEnabled()) {
412                                            _log.info(
413                                                    "Ignoring scope " + newValue + " because the " +
414                                                            "referenced parent group no longer allows " +
415                                                                    "sharing content with child sites");
416                                    }
417                            }
418                    }
419    
420                    portletPreferences.setValues(
421                            key, newValues.toArray(new String[newValues.size()]));
422            }
423    
424            private static Log _log = LogFactoryUtil.getLog(
425                    AssetPublisherPortletDataHandler.class);
426    
427    }