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.kernel.xml.Element;
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, Element rootElement)
068                    throws Exception {
069    
070                    return updateExportPortletPreferences(
071                            portletDataContext, portletId, portletPreferences, rootElement);
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, Element rootElement)
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(), rootElement);
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(), rootElement);
177                            }
178                            else if (name.equals("assetVocabularyId")) {
179                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
180                                            portletDataContext, portlet, portletPreferences, name,
181                                            AssetVocabulary.class.getName(), rootElement);
182                            }
183                            else if (name.startsWith("queryName") &&
184                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
185    
186                                    String index = name.substring(9);
187    
188                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
189                                            portletDataContext, portlet, portletPreferences,
190                                            "queryValues" + index, AssetCategory.class.getName(),
191                                            rootElement);
192                            }
193                            else if (name.equals("scopeIds")) {
194                                    updateExportScopeIds(
195                                            portletDataContext, portletPreferences, name,
196                                            portletDataContext.getPlid());
197                            }
198                    }
199    
200                    return portletPreferences;
201            }
202    
203            protected void updateExportScopeIds(
204                            PortletDataContext portletDataContext,
205                            PortletPreferences portletPreferences, String key, long plid)
206                    throws Exception {
207    
208                    String[] oldValues = portletPreferences.getValues(key, null);
209    
210                    if (oldValues == null) {
211                            return;
212                    }
213    
214                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
215    
216                    String companyGroupScopeId =
217                            AssetPublisher.SCOPE_ID_GROUP_PREFIX +
218                                    portletDataContext.getCompanyGroupId();
219    
220                    String[] newValues = new String[oldValues.length];
221    
222                    for (int i = 0; i < oldValues.length; i++) {
223                            String oldValue = oldValues[i];
224    
225                            if (oldValue.startsWith(AssetPublisher.SCOPE_ID_GROUP_PREFIX)) {
226                                    newValues[i] = StringUtil.replace(
227                                            oldValue, companyGroupScopeId,
228                                            "[$COMPANY_GROUP_SCOPE_ID$]");
229                            }
230                            else if (oldValue.startsWith(
231                                                    AssetPublisher.SCOPE_ID_LAYOUT_PREFIX)) {
232    
233                                    // Legacy preferences
234    
235                                    String scopeIdSuffix = oldValue.substring(
236                                            AssetPublisher.SCOPE_ID_LAYOUT_PREFIX.length());
237    
238                                    long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
239    
240                                    Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
241                                            layout.getGroupId(), layout.isPrivateLayout(),
242                                            scopeIdLayoutId);
243    
244                                    newValues[i] =
245                                            AssetPublisher.SCOPE_ID_LAYOUT_UUID_PREFIX +
246                                                    scopeIdLayout.getUuid();
247                            }
248                            else {
249                                    newValues[i] = oldValue;
250                            }
251                    }
252    
253                    portletPreferences.setValues(key, newValues);
254            }
255    
256            protected void updateImportClassNameIds(
257                            PortletPreferences portletPreferences, String key)
258                    throws Exception {
259    
260                    String[] oldValues = portletPreferences.getValues(key, null);
261    
262                    if (oldValues == null) {
263                            return;
264                    }
265    
266                    String[] newValues = new String[oldValues.length];
267    
268                    int i = 0;
269    
270                    for (String oldValue : oldValues) {
271                            if (key.equals("anyAssetType") &&
272                                    (oldValue.equals("false") || oldValue.equals("true"))) {
273    
274                                    newValues[i++] = oldValue;
275    
276                                    continue;
277                            }
278    
279                            try {
280                                    long classNameId = PortalUtil.getClassNameId(oldValue);
281    
282                                    newValues[i++] = String.valueOf(classNameId);
283                            }
284                            catch (Exception e) {
285                                    if (_log.isWarnEnabled()) {
286                                            _log.warn(
287                                                    "Unable to find class name ID for class name " +
288                                                            oldValue);
289                                    }
290                            }
291                    }
292    
293                    portletPreferences.setValues(key, newValues);
294            }
295    
296            protected PortletPreferences updateImportPortletPreferences(
297                            PortletDataContext portletDataContext, String portletId,
298                            PortletPreferences portletPreferences)
299                    throws Exception {
300    
301                    Company company = CompanyLocalServiceUtil.getCompanyById(
302                            portletDataContext.getCompanyId());
303    
304                    Group companyGroup = company.getGroup();
305    
306                    String anyAssetTypeClassName = portletPreferences.getValue(
307                            "anyAssetType", StringPool.BLANK);
308    
309                    Enumeration<String> enu = portletPreferences.getNames();
310    
311                    while (enu.hasMoreElements()) {
312                            String name = enu.nextElement();
313    
314                            String value = GetterUtil.getString(
315                                    portletPreferences.getValue(name, null));
316    
317                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
318                                    updateImportClassNameIds(portletPreferences, name);
319                            }
320                            else if (name.equals(
321                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
322                                             (name.equals("classTypeIds") &&
323                                              anyAssetTypeClassName.equals(
324                                                      DLFileEntry.class.getName())) ||
325                                             name.equals(
326                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
327    
328                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
329                                            portletDataContext, portletPreferences, name,
330                                            DLFileEntryType.class, companyGroup.getGroupId());
331                            }
332                            else if (name.equals(
333                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
334                                             (name.equals("classTypeIds") &&
335                                              anyAssetTypeClassName.equals(
336                                                      JournalArticle.class.getName())) ||
337                                             name.equals(
338                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
339    
340                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
341                                            portletDataContext, portletPreferences, name,
342                                            DDMStructure.class, companyGroup.getGroupId());
343                            }
344                            else if (name.equals("assetVocabularyId")) {
345                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
346                                            portletDataContext, portletPreferences, name,
347                                            AssetVocabulary.class, companyGroup.getGroupId());
348                            }
349                            else if (name.startsWith("queryName") &&
350                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
351    
352                                    String index = name.substring(9, name.length());
353    
354                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
355                                            portletDataContext, portletPreferences,
356                                            "queryValues" + index, AssetCategory.class,
357                                            companyGroup.getGroupId());
358                            }
359                            else if (name.equals("scopeIds")) {
360                                    updateImportScopeIds(
361                                            portletPreferences, name, companyGroup.getGroupId(),
362                                            portletDataContext.getPlid());
363                            }
364                    }
365    
366                    return portletPreferences;
367            }
368    
369            protected void updateImportScopeIds(
370                            PortletPreferences portletPreferences, String key,
371                            long companyGroupId, long plid)
372                    throws Exception {
373    
374                    String[] oldValues = portletPreferences.getValues(key, null);
375    
376                    if (oldValues == null) {
377                            return;
378                    }
379    
380                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
381    
382                    String companyGroupScopeId =
383                            AssetPublisher.SCOPE_ID_GROUP_PREFIX + companyGroupId;
384    
385                    List<String> newValues = new ArrayList<String>(oldValues.length);
386    
387                    for (String oldValue : oldValues) {
388                            String newValue = StringUtil.replace(
389                                    oldValue, "[$COMPANY_GROUP_SCOPE_ID$]", companyGroupScopeId);
390    
391                            try {
392                                    if (!AssetPublisherUtil.isScopeIdSelectable(
393                                                    PermissionThreadLocal.getPermissionChecker(), newValue,
394                                                    companyGroupId, layout)) {
395    
396                                            continue;
397                                    }
398    
399                                    newValues.add(newValue);
400                            }
401                            catch (NoSuchGroupException nsge) {
402                                    if (_log.isInfoEnabled()) {
403                                            _log.info(
404                                                    "Ignoring scope " + newValue + " because the " +
405                                                            "referenced group was not found");
406                                    }
407                            }
408                            catch (PrincipalException pe) {
409                                    if (_log.isInfoEnabled()) {
410                                            _log.info(
411                                                    "Ignoring scope " + newValue + " because the " +
412                                                            "referenced parent group no longer allows " +
413                                                                    "sharing content with child sites");
414                                    }
415                            }
416                    }
417    
418                    portletPreferences.setValues(
419                            key, newValues.toArray(new String[newValues.size()]));
420            }
421    
422            private static Log _log = LogFactoryUtil.getLog(
423                    AssetPublisherPortletDataHandler.class);
424    
425    }