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