001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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 anyAssetTypeString = portletPreferences.getValue(
169                            "anyAssetType", null);
170    
171                    String selectionStyle = portletPreferences.getValue(
172                            "selectionStyle", null);
173    
174                    if (Validator.isNotNull(selectionStyle) &&
175                            selectionStyle.equals("manual")) {
176    
177                            portletPreferences.reset("anyAssetType");
178    
179                            anyAssetTypeString = portletPreferences.getValue(
180                                    "anyAssetType", null);
181                    }
182                    else if (Validator.isNotNull(anyAssetTypeString) &&
183                                     anyAssetTypeString.equals("false")) {
184    
185                            String[] classNameIds = portletPreferences.getValues(
186                                    "classNameIds", StringPool.EMPTY_ARRAY);
187    
188                            if (classNameIds.length == 1) {
189                                    portletPreferences.setValue("anyAssetType", classNameIds[0]);
190    
191                                    anyAssetTypeString = portletPreferences.getValue(
192                                            "anyAssetType", null);
193    
194                                    portletPreferences.reset("classNameIds");
195                            }
196                    }
197    
198                    String anyAssetTypeClassName = StringPool.BLANK;
199    
200                    long anyAssetType = GetterUtil.getLong(anyAssetTypeString);
201    
202                    if (anyAssetType > 0) {
203                            anyAssetTypeClassName = PortalUtil.getClassName(anyAssetType);
204                    }
205    
206                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
207                            portletDataContext.getCompanyId(), portletId);
208    
209                    Enumeration<String> enu = portletPreferences.getNames();
210    
211                    while (enu.hasMoreElements()) {
212                            String name = enu.nextElement();
213    
214                            String value = GetterUtil.getString(
215                                    portletPreferences.getValue(name, null));
216    
217                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
218                                    if (name.equals("classNameIds") &&
219                                            Validator.isNotNull(anyAssetTypeString) &&
220                                            !anyAssetTypeString.equals("false")) {
221    
222                                            portletPreferences.reset(name);
223                                    }
224                                    else {
225                                            updateExportClassNameIds(portletPreferences, name);
226                                    }
227                            }
228                            else if (name.equals(
229                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
230                                             (name.equals("classTypeIds") &&
231                                              anyAssetTypeClassName.equals(
232                                                      DLFileEntry.class.getName())) ||
233                                             name.equals(
234                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
235    
236                                    String anyClassTypeDLFileEntryAssetRendererFactory =
237                                            portletPreferences.getValue(
238                                                    "anyClassTypeDLFileEntryAssetRendererFactory", null);
239    
240                                    String[] classTypeIdsDLFileEntryAssetRendererFactory =
241                                            portletPreferences.getValues(
242                                                    "classTypeIdsDLFileEntryAssetRendererFactory",
243                                                    StringPool.EMPTY_ARRAY);
244    
245                                    if (Validator.isNotNull(
246                                                    anyClassTypeDLFileEntryAssetRendererFactory) &&
247                                            anyClassTypeDLFileEntryAssetRendererFactory.equals(
248                                                    "false") &&
249                                            (classTypeIdsDLFileEntryAssetRendererFactory.length == 1)) {
250    
251                                            portletPreferences.setValue(
252                                                    "anyClassTypeDLFileEntryAssetRendererFactory",
253                                                    classTypeIdsDLFileEntryAssetRendererFactory[0]);
254    
255                                            portletPreferences.reset(
256                                                    "classTypeIdsDLFileEntryAssetRendererFactory");
257    
258                                            anyClassTypeDLFileEntryAssetRendererFactory =
259                                                    portletPreferences.getValue(
260                                                            "anyClassTypeDLFileEntryAssetRendererFactory",
261                                                            null);
262                                    }
263    
264                                    if (!anyAssetTypeClassName.equals(
265                                                    DLFileEntry.class.getName()) ||
266                                            (name.equals(
267                                                    "classTypeIdsDLFileEntryAssetRendererFactory") &&
268                                             Validator.isNotNull(
269                                                     anyClassTypeDLFileEntryAssetRendererFactory) &&
270                                             !anyClassTypeDLFileEntryAssetRendererFactory.equals(
271                                                     "false"))) {
272    
273                                            portletPreferences.reset(name);
274                                    }
275                                    else {
276                                            ExportImportHelperUtil.
277                                                    updateExportPortletPreferencesClassPKs(
278                                                            portletDataContext, portlet, portletPreferences,
279                                                            name, DLFileEntryType.class.getName(),
280                                                            portletDataContext.getExportDataRootElement());
281                                    }
282                            }
283                            else if (name.equals(
284                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
285                                             (name.equals("classTypeIds") &&
286                                              anyAssetTypeClassName.equals(
287                                                      JournalArticle.class.getName())) ||
288                                             name.equals(
289                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
290    
291                                    String anyClassTypeJournalArticleAssetRendererFactory =
292                                            portletPreferences.getValue(
293                                                    "anyClassTypeJournalArticleAssetRendererFactory", null);
294    
295                                    String[] classTypeIdsJournalArticleAssetRendererFactory =
296                                            portletPreferences.getValues(
297                                                    "classTypeIdsJournalArticleAssetRendererFactory",
298                                                    StringPool.EMPTY_ARRAY);
299    
300                                    if (Validator.isNotNull(
301                                                    anyClassTypeJournalArticleAssetRendererFactory) &&
302                                            anyClassTypeJournalArticleAssetRendererFactory.equals(
303                                                    "false") &&
304                                            (classTypeIdsJournalArticleAssetRendererFactory.length ==
305                                                    1)) {
306    
307                                            portletPreferences.setValue(
308                                                    "anyClassTypeJournalArticleAssetRendererFactory",
309                                                    classTypeIdsJournalArticleAssetRendererFactory[0]);
310    
311                                            portletPreferences.reset(
312                                                    "classTypeIdsJournalArticleAssetRendererFactory");
313    
314                                            anyClassTypeJournalArticleAssetRendererFactory =
315                                                    portletPreferences.getValue(
316                                                            "anyClassTypeJournalArticleAssetRendererFactory",
317                                                            null);
318                                    }
319    
320                                    if (!anyAssetTypeClassName.equals(
321                                                    JournalArticle.class.getName()) ||
322                                            (name.equals(
323                                                    "classTypeIdsJournalArticleAssetRendererFactory") &&
324                                             Validator.isNotNull(
325                                                     anyClassTypeJournalArticleAssetRendererFactory) &&
326                                             !anyClassTypeJournalArticleAssetRendererFactory.equals(
327                                                     "false"))) {
328    
329                                            portletPreferences.reset(name);
330                                    }
331                                    else {
332                                            ExportImportHelperUtil.
333                                                    updateExportPortletPreferencesClassPKs(
334                                                            portletDataContext, portlet, portletPreferences,
335                                                            name, DDMStructure.class.getName(),
336                                                            portletDataContext.getExportDataRootElement());
337                                    }
338                            }
339                            else if (name.equals("assetVocabularyId")) {
340                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
341                                            portletDataContext, portlet, portletPreferences, name,
342                                            AssetVocabulary.class.getName(),
343                                            portletDataContext.getExportDataRootElement());
344                            }
345                            else if (name.startsWith("orderByColumn")) {
346                                    updateExportDDMStructures(
347                                            portletDataContext, portletPreferences, name);
348                            }
349                            else if (name.startsWith("queryName") &&
350                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
351    
352                                    String index = name.substring(9);
353    
354                                    ExportImportHelperUtil.updateExportPortletPreferencesClassPKs(
355                                            portletDataContext, portlet, portletPreferences,
356                                            "queryValues" + index, AssetCategory.class.getName(),
357                                            portletDataContext.getExportDataRootElement());
358                            }
359                            else if (name.startsWith("queryName") &&
360                                             StringUtil.equalsIgnoreCase(value, "assetTags")) {
361    
362                                    String index = name.substring(9);
363    
364                                    String[] assetTagNames = portletPreferences.getValues(
365                                            "queryValues" + index, null);
366    
367                                    if (ArrayUtil.isEmpty(assetTagNames)) {
368                                            continue;
369                                    }
370    
371                                    portletDataContext.addAssetTags(
372                                            AssetPublisher.class.getName(), 0, assetTagNames);
373                            }
374                            else if (name.equals("scopeIds")) {
375                                    updateExportScopeIds(
376                                            portletDataContext, portletPreferences, name,
377                                            portletDataContext.getPlid());
378                            }
379                    }
380    
381                    return portletPreferences;
382            }
383    
384            protected void updateExportScopeIds(
385                            PortletDataContext portletDataContext,
386                            PortletPreferences portletPreferences, String key, long plid)
387                    throws Exception {
388    
389                    String[] oldValues = portletPreferences.getValues(key, null);
390    
391                    if (oldValues == null) {
392                            return;
393                    }
394    
395                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
396    
397                    String companyGroupScopeId =
398                            AssetPublisher.SCOPE_ID_GROUP_PREFIX +
399                                    portletDataContext.getCompanyGroupId();
400    
401                    String[] newValues = new String[oldValues.length];
402    
403                    for (int i = 0; i < oldValues.length; i++) {
404                            String oldValue = oldValues[i];
405    
406                            if (oldValue.startsWith(AssetPublisher.SCOPE_ID_GROUP_PREFIX)) {
407                                    newValues[i] = StringUtil.replace(
408                                            oldValue, companyGroupScopeId,
409                                            "[$COMPANY_GROUP_SCOPE_ID$]");
410                            }
411                            else if (oldValue.startsWith(
412                                                    AssetPublisher.SCOPE_ID_LAYOUT_PREFIX)) {
413    
414                                    // Legacy preferences
415    
416                                    String scopeIdSuffix = oldValue.substring(
417                                            AssetPublisher.SCOPE_ID_LAYOUT_PREFIX.length());
418    
419                                    long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);
420    
421                                    Layout scopeIdLayout = LayoutLocalServiceUtil.getLayout(
422                                            layout.getGroupId(), layout.isPrivateLayout(),
423                                            scopeIdLayoutId);
424    
425                                    newValues[i] =
426                                            AssetPublisher.SCOPE_ID_LAYOUT_UUID_PREFIX +
427                                                    scopeIdLayout.getUuid();
428                            }
429                            else {
430                                    newValues[i] = oldValue;
431                            }
432                    }
433    
434                    portletPreferences.setValues(key, newValues);
435            }
436    
437            protected void updateImportClassNameIds(
438                            PortletPreferences portletPreferences, String key)
439                    throws Exception {
440    
441                    String[] oldValues = portletPreferences.getValues(key, null);
442    
443                    if (oldValues == null) {
444                            return;
445                    }
446    
447                    String[] newValues = new String[oldValues.length];
448    
449                    int i = 0;
450    
451                    for (String oldValue : oldValues) {
452                            if (key.equals("anyAssetType") &&
453                                    (oldValue.equals("false") || oldValue.equals("true"))) {
454    
455                                    newValues[i++] = oldValue;
456    
457                                    continue;
458                            }
459    
460                            try {
461                                    long classNameId = PortalUtil.getClassNameId(oldValue);
462    
463                                    newValues[i++] = String.valueOf(classNameId);
464                            }
465                            catch (Exception e) {
466                                    if (_log.isWarnEnabled()) {
467                                            _log.warn(
468                                                    "Unable to find class name ID for class name " +
469                                                            oldValue);
470                                    }
471                            }
472                    }
473    
474                    portletPreferences.setValues(key, newValues);
475            }
476    
477            protected void updateImportDDMStructures(
478                            PortletDataContext portletDataContext,
479                            PortletPreferences portletPreferences, String key)
480                    throws Exception {
481    
482                    String oldValue = portletPreferences.getValue(key, null);
483    
484                    if (Validator.isNull(oldValue) ||
485                            !oldValue.startsWith(
486                                    DDMIndexer.DDM_FIELD_NAMESPACE + StringPool.FORWARD_SLASH)) {
487    
488                            return;
489                    }
490    
491                    String[] oldValueParts = StringUtil.split(
492                            oldValue, StringPool.FORWARD_SLASH);
493    
494                    String ddmStructureUuid = oldValueParts[1];
495    
496                    DDMStructure ddmStructure =
497                            DDMStructureLocalServiceUtil.fetchDDMStructureByUuidAndGroupId(
498                                    ddmStructureUuid, portletDataContext.getScopeGroupId());
499    
500                    if (ddmStructure == null) {
501                            ddmStructure =
502                                    DDMStructureLocalServiceUtil.fetchDDMStructureByUuidAndGroupId(
503                                            ddmStructureUuid, portletDataContext.getCompanyGroupId());
504                    }
505    
506                    if (ddmStructure == null) {
507                            return;
508                    }
509    
510                    long ddmStructureId = ddmStructure.getStructureId();
511    
512                    String newValue = oldValue.replace(
513                            String.valueOf(ddmStructureUuid), String.valueOf(ddmStructureId));
514    
515                    portletPreferences.setValue(key, newValue);
516            }
517    
518            protected PortletPreferences updateImportPortletPreferences(
519                            PortletDataContext portletDataContext, String portletId,
520                            PortletPreferences portletPreferences)
521                    throws Exception {
522    
523                    Company company = CompanyLocalServiceUtil.getCompanyById(
524                            portletDataContext.getCompanyId());
525    
526                    Group companyGroup = company.getGroup();
527    
528                    String anyAssetTypeClassName = portletPreferences.getValue(
529                            "anyAssetType", StringPool.BLANK);
530    
531                    Enumeration<String> enu = portletPreferences.getNames();
532    
533                    while (enu.hasMoreElements()) {
534                            String name = enu.nextElement();
535    
536                            String value = GetterUtil.getString(
537                                    portletPreferences.getValue(name, null));
538    
539                            if (name.equals("anyAssetType") || name.equals("classNameIds")) {
540                                    updateImportClassNameIds(portletPreferences, name);
541                            }
542                            else if (name.equals(
543                                                    "anyClassTypeDLFileEntryAssetRendererFactory") ||
544                                             (name.equals("classTypeIds") &&
545                                              anyAssetTypeClassName.equals(
546                                                      DLFileEntry.class.getName())) ||
547                                             name.equals(
548                                                    "classTypeIdsDLFileEntryAssetRendererFactory")) {
549    
550                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
551                                            portletDataContext, portletPreferences, name,
552                                            DLFileEntryType.class, companyGroup.getGroupId());
553                            }
554                            else if (name.equals(
555                                                    "anyClassTypeJournalArticleAssetRendererFactory") ||
556                                             (name.equals("classTypeIds") &&
557                                              anyAssetTypeClassName.equals(
558                                                      JournalArticle.class.getName())) ||
559                                             name.equals(
560                                                    "classTypeIdsJournalArticleAssetRendererFactory")) {
561    
562                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
563                                            portletDataContext, portletPreferences, name,
564                                            DDMStructure.class, companyGroup.getGroupId());
565                            }
566                            else if (name.equals("assetVocabularyId")) {
567                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
568                                            portletDataContext, portletPreferences, name,
569                                            AssetVocabulary.class, companyGroup.getGroupId());
570                            }
571                            else if (name.startsWith("orderByColumn")) {
572                                    updateImportDDMStructures(
573                                            portletDataContext, portletPreferences, name);
574                            }
575                            else if (name.startsWith("queryName") &&
576                                             StringUtil.equalsIgnoreCase(value, "assetCategories")) {
577    
578                                    String index = name.substring(9, name.length());
579    
580                                    ExportImportHelperUtil.updateImportPortletPreferencesClassPKs(
581                                            portletDataContext, portletPreferences,
582                                            "queryValues" + index, AssetCategory.class,
583                                            companyGroup.getGroupId());
584                            }
585                            else if (name.equals("scopeIds")) {
586                                    updateImportScopeIds(
587                                            portletPreferences, name, companyGroup.getGroupId(),
588                                            portletDataContext.getPlid());
589                            }
590                    }
591    
592                    return portletPreferences;
593            }
594    
595            protected void updateImportScopeIds(
596                            PortletPreferences portletPreferences, String key,
597                            long companyGroupId, long plid)
598                    throws Exception {
599    
600                    String[] oldValues = portletPreferences.getValues(key, null);
601    
602                    if (oldValues == null) {
603                            return;
604                    }
605    
606                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
607    
608                    String companyGroupScopeId =
609                            AssetPublisher.SCOPE_ID_GROUP_PREFIX + companyGroupId;
610    
611                    List<String> newValues = new ArrayList<String>(oldValues.length);
612    
613                    for (String oldValue : oldValues) {
614                            String newValue = StringUtil.replace(
615                                    oldValue, "[$COMPANY_GROUP_SCOPE_ID$]", companyGroupScopeId);
616    
617                            try {
618                                    if (!AssetPublisherUtil.isScopeIdSelectable(
619                                                    PermissionThreadLocal.getPermissionChecker(), newValue,
620                                                    companyGroupId, layout)) {
621    
622                                            continue;
623                                    }
624    
625                                    newValues.add(newValue);
626                            }
627                            catch (NoSuchGroupException nsge) {
628                                    if (_log.isInfoEnabled()) {
629                                            _log.info(
630                                                    "Ignoring scope " + newValue + " because the " +
631                                                            "referenced group was not found");
632                                    }
633                            }
634                            catch (PrincipalException pe) {
635                                    if (_log.isInfoEnabled()) {
636                                            _log.info(
637                                                    "Ignoring scope " + newValue + " because the " +
638                                                            "referenced parent group no longer allows " +
639                                                                    "sharing content with child sites");
640                                    }
641                            }
642                    }
643    
644                    portletPreferences.setValues(
645                            key, newValues.toArray(new String[newValues.size()]));
646            }
647    
648            private static Log _log = LogFactoryUtil.getLog(
649                    AssetPublisherPortletDataHandler.class);
650    
651    }