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