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.portal.lar;
016    
017    import com.liferay.portal.LARFileException;
018    import com.liferay.portal.LARTypeException;
019    import com.liferay.portal.LayoutImportException;
020    import com.liferay.portal.LocaleException;
021    import com.liferay.portal.MissingReferenceException;
022    import com.liferay.portal.PortletIdException;
023    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.exception.SystemException;
026    import com.liferay.portal.kernel.language.LanguageUtil;
027    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
028    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
029    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
030    import com.liferay.portal.kernel.lar.ManifestSummary;
031    import com.liferay.portal.kernel.lar.MissingReference;
032    import com.liferay.portal.kernel.lar.MissingReferences;
033    import com.liferay.portal.kernel.lar.PortletDataContext;
034    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
035    import com.liferay.portal.kernel.lar.PortletDataHandler;
036    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
037    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
038    import com.liferay.portal.kernel.lar.UserIdStrategy;
039    import com.liferay.portal.kernel.log.Log;
040    import com.liferay.portal.kernel.log.LogFactoryUtil;
041    import com.liferay.portal.kernel.search.Indexer;
042    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
043    import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
044    import com.liferay.portal.kernel.util.ArrayUtil;
045    import com.liferay.portal.kernel.util.GetterUtil;
046    import com.liferay.portal.kernel.util.LocaleUtil;
047    import com.liferay.portal.kernel.util.MapUtil;
048    import com.liferay.portal.kernel.util.ReleaseInfo;
049    import com.liferay.portal.kernel.util.StringBundler;
050    import com.liferay.portal.kernel.util.StringPool;
051    import com.liferay.portal.kernel.util.StringUtil;
052    import com.liferay.portal.kernel.util.Validator;
053    import com.liferay.portal.kernel.xml.Document;
054    import com.liferay.portal.kernel.xml.DocumentException;
055    import com.liferay.portal.kernel.xml.Element;
056    import com.liferay.portal.kernel.xml.Node;
057    import com.liferay.portal.kernel.xml.SAXReaderUtil;
058    import com.liferay.portal.kernel.zip.ZipReader;
059    import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
060    import com.liferay.portal.model.Group;
061    import com.liferay.portal.model.Layout;
062    import com.liferay.portal.model.LayoutConstants;
063    import com.liferay.portal.model.Lock;
064    import com.liferay.portal.model.Portlet;
065    import com.liferay.portal.model.PortletConstants;
066    import com.liferay.portal.model.PortletItem;
067    import com.liferay.portal.model.PortletPreferences;
068    import com.liferay.portal.model.User;
069    import com.liferay.portal.security.permission.PermissionCacheUtil;
070    import com.liferay.portal.service.GroupLocalServiceUtil;
071    import com.liferay.portal.service.LayoutLocalServiceUtil;
072    import com.liferay.portal.service.PortletItemLocalServiceUtil;
073    import com.liferay.portal.service.PortletLocalServiceUtil;
074    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
075    import com.liferay.portal.service.ServiceContext;
076    import com.liferay.portal.service.ServiceContextThreadLocal;
077    import com.liferay.portal.service.UserLocalServiceUtil;
078    import com.liferay.portal.service.persistence.PortletPreferencesUtil;
079    import com.liferay.portal.service.persistence.UserUtil;
080    import com.liferay.portal.servlet.filters.cache.CacheUtil;
081    import com.liferay.portal.util.PortalUtil;
082    import com.liferay.portal.util.PortletKeys;
083    import com.liferay.portlet.PortletPreferencesFactoryUtil;
084    import com.liferay.portlet.PortletPreferencesImpl;
085    import com.liferay.portlet.asset.NoSuchTagException;
086    import com.liferay.portlet.asset.model.AssetCategory;
087    import com.liferay.portlet.asset.model.AssetCategoryConstants;
088    import com.liferay.portlet.asset.model.AssetEntry;
089    import com.liferay.portlet.asset.model.AssetLink;
090    import com.liferay.portlet.asset.model.AssetTag;
091    import com.liferay.portlet.asset.model.AssetTagConstants;
092    import com.liferay.portlet.asset.model.AssetVocabulary;
093    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
094    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
095    import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
096    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
097    import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
098    import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
099    import com.liferay.portlet.asset.service.persistence.AssetTagUtil;
100    import com.liferay.portlet.asset.service.persistence.AssetVocabularyUtil;
101    import com.liferay.portlet.expando.NoSuchTableException;
102    import com.liferay.portlet.expando.model.ExpandoColumn;
103    import com.liferay.portlet.expando.model.ExpandoTable;
104    import com.liferay.portlet.expando.service.ExpandoColumnLocalServiceUtil;
105    import com.liferay.portlet.expando.service.ExpandoTableLocalServiceUtil;
106    import com.liferay.portlet.expando.util.ExpandoConverterUtil;
107    import com.liferay.portlet.journalcontent.util.JournalContentUtil;
108    import com.liferay.portlet.messageboards.model.MBMessage;
109    import com.liferay.portlet.ratings.model.RatingsEntry;
110    
111    import java.io.File;
112    import java.io.Serializable;
113    
114    import java.util.ArrayList;
115    import java.util.Enumeration;
116    import java.util.HashMap;
117    import java.util.List;
118    import java.util.Locale;
119    import java.util.Map;
120    
121    import org.apache.commons.lang.time.StopWatch;
122    
123    /**
124     * @author Brian Wing Shun Chan
125     * @author Joel Kozikowski
126     * @author Charles May
127     * @author Raymond Aug??
128     * @author Jorge Ferrer
129     * @author Bruno Farache
130     * @author Zsigmond Rab
131     * @author Douglas Wong
132     * @author Mate Thurzo
133     */
134    public class PortletImporter {
135    
136            public String importPortletData(
137                            PortletDataContext portletDataContext, String portletId,
138                            PortletPreferences portletPreferences, Element portletDataElement)
139                    throws Exception {
140    
141                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
142                            portletDataContext.getCompanyId(), portletId);
143    
144                    if (portlet == null) {
145                            if (_log.isDebugEnabled()) {
146                                    _log.debug(
147                                            "Do not import portlet data for " + portletId +
148                                                    " because the portlet does not exist");
149                            }
150    
151                            return null;
152                    }
153    
154                    PortletDataHandler portletDataHandler =
155                            portlet.getPortletDataHandlerInstance();
156    
157                    if ((portletDataHandler == null) ||
158                            portletDataHandler.isDataPortletInstanceLevel()) {
159    
160                            if (_log.isDebugEnabled()) {
161                                    _log.debug(
162                                            "Do not import portlet data for " + portletId +
163                                                    " because the portlet does not have a " +
164                                                            "PortletDataHandler");
165                            }
166    
167                            return null;
168                    }
169    
170                    if (_log.isDebugEnabled()) {
171                            _log.debug("Importing data for " + portletId);
172                    }
173    
174                    PortletPreferencesImpl portletPreferencesImpl = null;
175    
176                    if (portletPreferences != null) {
177                            portletPreferencesImpl =
178                                    (PortletPreferencesImpl)
179                                            PortletPreferencesFactoryUtil.fromDefaultXML(
180                                                    portletPreferences.getPreferences());
181                    }
182    
183                    String portletData = portletDataContext.getZipEntryAsString(
184                            portletDataElement.attributeValue("path"));
185    
186                    if (Validator.isNull(portletData)) {
187                            return null;
188                    }
189    
190                    portletPreferencesImpl =
191                            (PortletPreferencesImpl)portletDataHandler.importData(
192                                    portletDataContext, portletId, portletPreferencesImpl,
193                                    portletData);
194    
195                    if (portletPreferencesImpl == null) {
196                            return null;
197                    }
198    
199                    return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
200            }
201    
202            public void importPortletInfo(
203                            long userId, long plid, long groupId, String portletId,
204                            Map<String, String[]> parameterMap, File file)
205                    throws Exception {
206    
207                    try {
208                            ExportImportThreadLocal.setPortletImportInProcess(true);
209    
210                            doImportPortletInfo(
211                                    userId, plid, groupId, portletId, parameterMap, file);
212                    }
213                    finally {
214                            ExportImportThreadLocal.setPortletImportInProcess(false);
215    
216                            CacheUtil.clearCache();
217                            JournalContentUtil.clearCache();
218                            PermissionCacheUtil.clearCache();
219                    }
220            }
221    
222            public MissingReferences validateFile(
223                            long userId, long plid, long groupId, String portletId,
224                            Map<String, String[]> parameterMap, File file)
225                    throws Exception {
226    
227                    try {
228                            ExportImportThreadLocal.setPortletValidationInProcess(true);
229    
230                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
231    
232                            ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
233    
234                            PortletDataContext portletDataContext =
235                                    PortletDataContextFactoryUtil.createImportPortletDataContext(
236                                            layout.getCompanyId(), groupId, parameterMap, null,
237                                            zipReader);
238    
239                            validateFile(portletDataContext, portletId);
240    
241                            MissingReferences missingReferences =
242                                    ExportImportHelperUtil.validateMissingReferences(
243                                            userId, groupId, parameterMap, file);
244    
245                            Map<String, MissingReference> dependencyMissingReferences =
246                                    missingReferences.getDependencyMissingReferences();
247    
248                            if (!dependencyMissingReferences.isEmpty()) {
249                                    throw new MissingReferenceException(missingReferences);
250                            }
251    
252                            return missingReferences;
253                    }
254                    finally {
255                            ExportImportThreadLocal.setPortletValidationInProcess(false);
256                    }
257            }
258    
259            protected void deletePortletData(
260                            PortletDataContext portletDataContext, String portletId, long plid)
261                    throws Exception {
262    
263                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
264                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
265    
266                    PortletPreferences portletPreferences =
267                            PortletPreferencesUtil.fetchByO_O_P_P(
268                                    ownerId, ownerType, plid, portletId);
269    
270                    if (portletPreferences == null) {
271                            portletPreferences =
272                                    new com.liferay.portal.model.impl.PortletPreferencesImpl();
273                    }
274    
275                    String xml = deletePortletData(
276                            portletDataContext, portletId, portletPreferences);
277    
278                    if (xml != null) {
279                            PortletPreferencesLocalServiceUtil.updatePreferences(
280                                    ownerId, ownerType, plid, portletId, xml);
281                    }
282            }
283    
284            protected String deletePortletData(
285                            PortletDataContext portletDataContext, String portletId,
286                            PortletPreferences portletPreferences)
287                    throws Exception {
288    
289                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
290                            portletDataContext.getCompanyId(), portletId);
291    
292                    if (portlet == null) {
293                            if (_log.isDebugEnabled()) {
294                                    _log.debug(
295                                            "Do not delete portlet data for " + portletId +
296                                                    " because the portlet does not exist");
297                            }
298    
299                            return null;
300                    }
301    
302                    PortletDataHandler portletDataHandler =
303                            portlet.getPortletDataHandlerInstance();
304    
305                    if (portletDataHandler == null) {
306                            if (_log.isDebugEnabled()) {
307                                    _log.debug(
308                                            "Do not delete portlet data for " + portletId +
309                                                    " because the portlet does not have a " +
310                                                            "PortletDataHandler");
311                            }
312    
313                            return null;
314                    }
315    
316                    if (_log.isDebugEnabled()) {
317                            _log.debug("Deleting data for " + portletId);
318                    }
319    
320                    PortletPreferencesImpl portletPreferencesImpl =
321                            (PortletPreferencesImpl)
322                                    PortletPreferencesFactoryUtil.fromDefaultXML(
323                                            portletPreferences.getPreferences());
324    
325                    try {
326                            portletPreferencesImpl =
327                                    (PortletPreferencesImpl)portletDataHandler.deleteData(
328                                            portletDataContext, portletId, portletPreferencesImpl);
329                    }
330                    finally {
331                            portletDataContext.setGroupId(portletDataContext.getScopeGroupId());
332                    }
333    
334                    if (portletPreferencesImpl == null) {
335                            return null;
336                    }
337    
338                    return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
339            }
340    
341            protected void doImportPortletInfo(
342                            long userId, long plid, long groupId, String portletId,
343                            Map<String, String[]> parameterMap, File file)
344                    throws Exception {
345    
346                    boolean deletePortletData = MapUtil.getBoolean(
347                            parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
348                    boolean importPermissions = MapUtil.getBoolean(
349                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
350                    String userIdStrategyString = MapUtil.getString(
351                            parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
352    
353                    StopWatch stopWatch = new StopWatch();
354    
355                    stopWatch.start();
356    
357                    User user = UserUtil.findByPrimaryKey(userId);
358    
359                    ServiceContext serviceContext =
360                            ServiceContextThreadLocal.getServiceContext();
361    
362                    if (serviceContext == null) {
363                            serviceContext = new ServiceContext();
364    
365                            serviceContext.setCompanyId(user.getCompanyId());
366                            serviceContext.setSignedIn(false);
367                            serviceContext.setUserId(userId);
368    
369                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
370                    }
371    
372                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
373    
374                    UserIdStrategy userIdStrategy = getUserIdStrategy(
375                            user, userIdStrategyString);
376    
377                    ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
378    
379                    PortletDataContext portletDataContext =
380                            PortletDataContextFactoryUtil.createImportPortletDataContext(
381                                    layout.getCompanyId(), groupId, parameterMap, userIdStrategy,
382                                    zipReader);
383    
384                    portletDataContext.setPortetDataContextListener(
385                            new PortletDataContextListenerImpl(portletDataContext));
386    
387                    portletDataContext.setPlid(plid);
388                    portletDataContext.setPrivateLayout(layout.isPrivateLayout());
389    
390                    // Manifest
391    
392                    validateFile(portletDataContext, portletId);
393    
394                    ManifestSummary manifestSummary =
395                            ExportImportHelperUtil.getManifestSummary(
396                                    userId, groupId, parameterMap, file);
397    
398                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
399                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
400                                    "portlet", portletId, manifestSummary);
401                    }
402    
403                    portletDataContext.setManifestSummary(manifestSummary);
404    
405                    // Company id
406    
407                    long sourceCompanyId = GetterUtil.getLong(
408                            _headerElement.attributeValue("company-id"));
409    
410                    portletDataContext.setSourceCompanyId(sourceCompanyId);
411    
412                    // Company group id
413    
414                    long sourceCompanyGroupId = GetterUtil.getLong(
415                            _headerElement.attributeValue("company-group-id"));
416    
417                    portletDataContext.setSourceCompanyGroupId(sourceCompanyGroupId);
418    
419                    // Group id
420    
421                    long sourceGroupId = GetterUtil.getLong(
422                            _headerElement.attributeValue("group-id"));
423    
424                    portletDataContext.setSourceGroupId(sourceGroupId);
425    
426                    // User personal site group id
427    
428                    long sourceUserPersonalSiteGroupId = GetterUtil.getLong(
429                            _headerElement.attributeValue("user-personal-site-group-id"));
430    
431                    portletDataContext.setSourceUserPersonalSiteGroupId(
432                            sourceUserPersonalSiteGroupId);
433    
434                    Element missingReferencesElement = _rootElement.element(
435                            "missing-references");
436    
437                    if (missingReferencesElement != null) {
438                            portletDataContext.setMissingReferencesElement(
439                                    missingReferencesElement);
440                    }
441    
442                    // Read asset categories, asset tags, comments, locks, and ratings
443                    // entries to make them available to the data handlers through the
444                    // portlet data context
445    
446                    Element portletElement = null;
447    
448                    try {
449                            portletElement = _rootElement.element("portlet");
450    
451                            Document portletDocument = SAXReaderUtil.read(
452                                    portletDataContext.getZipEntryAsString(
453                                            portletElement.attributeValue("path")));
454    
455                            portletElement = portletDocument.getRootElement();
456                    }
457                    catch (DocumentException de) {
458                            throw new SystemException(de);
459                    }
460    
461                    LayoutCache layoutCache = new LayoutCache();
462    
463                    if (importPermissions) {
464                            _permissionImporter.checkRoles(
465                                    layoutCache, layout.getCompanyId(), groupId, userId,
466                                    portletElement);
467    
468                            _permissionImporter.readPortletDataPermissions(portletDataContext);
469                    }
470    
471                    readAssetCategories(portletDataContext);
472                    readAssetTags(portletDataContext);
473                    readComments(portletDataContext);
474                    readExpandoTables(portletDataContext);
475                    readLocks(portletDataContext);
476                    readRatingsEntries(portletDataContext);
477    
478                    // Delete portlet data
479    
480                    if (_log.isDebugEnabled()) {
481                            _log.debug("Deleting portlet data");
482                    }
483    
484                    if (deletePortletData) {
485                            deletePortletData(portletDataContext, portletId, plid);
486                    }
487    
488                    Element portletDataElement = portletElement.element("portlet-data");
489    
490                    Map<String, Boolean> importPortletControlsMap =
491                            LayoutImporter.getImportPortletControlsMap(
492                                    layout.getCompanyId(), portletId, parameterMap,
493                                    portletDataElement, manifestSummary);
494    
495                    try {
496    
497                            // Portlet preferences
498    
499                            importPortletPreferences(
500                                    portletDataContext, layout.getCompanyId(), groupId, layout,
501                                    portletId, portletElement, true,
502                                    importPortletControlsMap.get(
503                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
504                                    importPortletControlsMap.get(
505                                            PortletDataHandlerKeys.PORTLET_DATA),
506                                    importPortletControlsMap.get(
507                                            PortletDataHandlerKeys.PORTLET_SETUP),
508                                    importPortletControlsMap.get(
509                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
510    
511                            // Portlet data
512    
513                            if (importPortletControlsMap.get(
514                                            PortletDataHandlerKeys.PORTLET_DATA)) {
515    
516                                    if (_log.isDebugEnabled()) {
517                                            _log.debug("Importing portlet data");
518                                    }
519    
520                                    importPortletData(
521                                            portletDataContext, portletId, plid, portletDataElement);
522                            }
523                    }
524                    finally {
525                            resetPortletScope(portletDataContext, groupId);
526                    }
527    
528                    // Portlet permissions
529    
530                    if (importPermissions) {
531                            if (_log.isDebugEnabled()) {
532                                    _log.debug("Importing portlet permissions");
533                            }
534    
535                            _permissionImporter.importPortletPermissions(
536                                    layoutCache, layout.getCompanyId(), groupId, userId, layout,
537                                    portletElement, portletId);
538    
539                            if (userId > 0) {
540                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
541                                            User.class);
542    
543                                    indexer.reindex(userId);
544                            }
545                    }
546    
547                    // Asset links
548    
549                    if (_log.isDebugEnabled()) {
550                            _log.debug("Importing asset links");
551                    }
552    
553                    readAssetLinks(portletDataContext);
554    
555                    // Deletion system events
556    
557                    _deletionSystemEventImporter.importDeletionSystemEvents(
558                            portletDataContext);
559    
560                    if (_log.isInfoEnabled()) {
561                            _log.info("Importing portlet takes " + stopWatch.getTime() + " ms");
562                    }
563    
564                    zipReader.close();
565            }
566    
567            protected String getAssetCategoryName(
568                            String uuid, long groupId, long parentCategoryId, String name,
569                            long vocabularyId, int count)
570                    throws Exception {
571    
572                    AssetCategory assetCategory = AssetCategoryUtil.fetchByG_P_N_V_First(
573                            groupId, parentCategoryId, name, vocabularyId, null);
574    
575                    if ((assetCategory == null) ||
576                            (Validator.isNotNull(uuid) &&
577                             uuid.equals(assetCategory.getUuid()))) {
578    
579                            return name;
580                    }
581    
582                    name = StringUtil.appendParentheticalSuffix(name, count);
583    
584                    return getAssetCategoryName(
585                            uuid, groupId, parentCategoryId, name, vocabularyId, ++count);
586            }
587    
588            protected String getAssetCategoryPath(
589                    PortletDataContext portletDataContext, long assetCategoryId) {
590    
591                    StringBundler sb = new StringBundler(6);
592    
593                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
594                    sb.append("/categories/");
595                    sb.append(assetCategoryId);
596                    sb.append(".xml");
597    
598                    return sb.toString();
599            }
600    
601            protected Map<Locale, String> getAssetCategoryTitleMap(
602                            long groupId, AssetCategory assetCategory, String name)
603                    throws PortalException, SystemException {
604    
605                    Map<Locale, String> titleMap = assetCategory.getTitleMap();
606    
607                    if (titleMap == null) {
608                            titleMap = new HashMap<Locale, String>();
609                    }
610    
611                    titleMap.put(PortalUtil.getSiteDefaultLocale(groupId), name);
612    
613                    return titleMap;
614            }
615    
616            protected String getAssetVocabularyName(
617                            String uuid, long groupId, String name, int count)
618                    throws Exception {
619    
620                    AssetVocabulary assetVocabulary = AssetVocabularyUtil.fetchByG_N(
621                            groupId, name);
622    
623                    if (assetVocabulary == null) {
624                            return name;
625                    }
626    
627                    if (Validator.isNotNull(uuid) &&
628                            uuid.equals(assetVocabulary.getUuid())) {
629    
630                            return name;
631                    }
632    
633                    name = StringUtil.appendParentheticalSuffix(name, count);
634    
635                    return getAssetVocabularyName(uuid, groupId, name, ++count);
636            }
637    
638            protected Map<Locale, String> getAssetVocabularyTitleMap(
639                            long groupId, AssetVocabulary assetVocabulary, String name)
640                    throws PortalException, SystemException {
641    
642                    Map<Locale, String> titleMap = assetVocabulary.getTitleMap();
643    
644                    if (titleMap == null) {
645                            titleMap = new HashMap<Locale, String>();
646                    }
647    
648                    titleMap.put(PortalUtil.getSiteDefaultLocale(groupId), name);
649    
650                    return titleMap;
651            }
652    
653            protected UserIdStrategy getUserIdStrategy(
654                    User user, String userIdStrategy) {
655    
656                    if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
657                            return new AlwaysCurrentUserIdStrategy(user);
658                    }
659    
660                    return new CurrentUserIdStrategy(user);
661            }
662    
663            protected void importAssetCategory(
664                            PortletDataContext portletDataContext,
665                            Map<Long, Long> assetVocabularyPKs,
666                            Map<Long, Long> assetCategoryPKs,
667                            Map<String, String> assetCategoryUuids,
668                            Element assetCategoryElement, AssetCategory assetCategory)
669                    throws Exception {
670    
671                    long userId = portletDataContext.getUserId(assetCategory.getUserUuid());
672                    long groupId = portletDataContext.getGroupId();
673                    long assetVocabularyId = MapUtil.getLong(
674                            assetVocabularyPKs, assetCategory.getVocabularyId(),
675                            assetCategory.getVocabularyId());
676                    long parentAssetCategoryId = MapUtil.getLong(
677                            assetCategoryPKs, assetCategory.getParentCategoryId(),
678                            assetCategory.getParentCategoryId());
679    
680                    if ((parentAssetCategoryId !=
681                                    AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
682                            (parentAssetCategoryId == assetCategory.getParentCategoryId())) {
683    
684                            String path = getAssetCategoryPath(
685                                    portletDataContext, parentAssetCategoryId);
686    
687                            AssetCategory parentAssetCategory =
688                                    (AssetCategory)portletDataContext.getZipEntryAsObject(path);
689    
690                            Node parentCategoryNode =
691                                    assetCategoryElement.getParent().selectSingleNode(
692                                            "./category[@path='" + path + "']");
693    
694                            if (parentCategoryNode != null) {
695                                    importAssetCategory(
696                                            portletDataContext, assetVocabularyPKs, assetCategoryPKs,
697                                            assetCategoryUuids, (Element)parentCategoryNode,
698                                            parentAssetCategory);
699    
700                                    parentAssetCategoryId = MapUtil.getLong(
701                                            assetCategoryPKs, assetCategory.getParentCategoryId(),
702                                            assetCategory.getParentCategoryId());
703                            }
704                    }
705    
706                    ServiceContext serviceContext = new ServiceContext();
707    
708                    serviceContext.setAddGroupPermissions(true);
709                    serviceContext.setAddGuestPermissions(true);
710                    serviceContext.setCreateDate(assetCategory.getCreateDate());
711                    serviceContext.setModifiedDate(assetCategory.getModifiedDate());
712                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
713    
714                    AssetCategory importedAssetCategory = null;
715    
716                    if ((parentAssetCategoryId !=
717                                    AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
718                            (AssetCategoryUtil.fetchByPrimaryKey(parentAssetCategoryId) ==
719                                    null)) {
720    
721                            _log.error(
722                                    "Could not find the parent category for category " +
723                                            assetCategory.getCategoryId());
724    
725                            return;
726                    }
727    
728                    List<Element> propertyElements = assetCategoryElement.elements(
729                            "property");
730    
731                    String[] properties = new String[propertyElements.size()];
732    
733                    for (int i = 0; i < propertyElements.size(); i++) {
734                            Element propertyElement = propertyElements.get(i);
735    
736                            String key = propertyElement.attributeValue("key");
737                            String value = propertyElement.attributeValue("value");
738    
739                            properties[i] = key.concat(
740                                    AssetCategoryConstants.PROPERTY_KEY_VALUE_SEPARATOR).concat(
741                                            value);
742                    }
743    
744                    AssetCategory existingAssetCategory = AssetCategoryUtil.fetchByUUID_G(
745                            assetCategory.getUuid(), groupId);
746    
747                    if (existingAssetCategory == null) {
748                            existingAssetCategory = AssetCategoryUtil.fetchByUUID_G(
749                                    assetCategory.getUuid(),
750                                    portletDataContext.getCompanyGroupId());
751                    }
752    
753                    if (existingAssetCategory == null) {
754                            String name = getAssetCategoryName(
755                                    null, groupId, parentAssetCategoryId, assetCategory.getName(),
756                                    assetVocabularyId, 2);
757    
758                            serviceContext.setUuid(assetCategory.getUuid());
759    
760                            importedAssetCategory =
761                                    AssetCategoryLocalServiceUtil.addCategory(
762                                            userId, parentAssetCategoryId,
763                                            getAssetCategoryTitleMap(groupId, assetCategory, name),
764                                            assetCategory.getDescriptionMap(), assetVocabularyId,
765                                            properties, serviceContext);
766                    }
767                    else if (portletDataContext.isCompanyStagedGroupedModel(
768                                            existingAssetCategory)) {
769    
770                            return;
771                    }
772                    else {
773                            String name = getAssetCategoryName(
774                                    assetCategory.getUuid(), groupId, parentAssetCategoryId,
775                                    assetCategory.getName(), assetVocabularyId, 2);
776    
777                            importedAssetCategory =
778                                    AssetCategoryLocalServiceUtil.updateCategory(
779                                            userId, existingAssetCategory.getCategoryId(),
780                                            parentAssetCategoryId,
781                                            getAssetCategoryTitleMap(groupId, assetCategory, name),
782                                            assetCategory.getDescriptionMap(), assetVocabularyId,
783                                            properties, serviceContext);
784                    }
785    
786                    assetCategoryPKs.put(
787                            assetCategory.getCategoryId(),
788                            importedAssetCategory.getCategoryId());
789    
790                    assetCategoryUuids.put(
791                            assetCategory.getUuid(), importedAssetCategory.getUuid());
792    
793                    portletDataContext.importPermissions(
794                            AssetCategory.class, assetCategory.getCategoryId(),
795                            importedAssetCategory.getCategoryId());
796            }
797    
798            protected void importAssetTag(
799                            PortletDataContext portletDataContext, Map<Long, Long> assetTagPKs,
800                            Element assetTagElement, AssetTag assetTag)
801                    throws PortalException, SystemException {
802    
803                    long userId = portletDataContext.getUserId(assetTag.getUserUuid());
804    
805                    ServiceContext serviceContext = new ServiceContext();
806    
807                    serviceContext.setAddGroupPermissions(true);
808                    serviceContext.setAddGuestPermissions(true);
809                    serviceContext.setCreateDate(assetTag.getCreateDate());
810                    serviceContext.setModifiedDate(assetTag.getModifiedDate());
811                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
812    
813                    AssetTag importedAssetTag = null;
814    
815                    List<Element> propertyElements = assetTagElement.elements("property");
816    
817                    String[] properties = new String[propertyElements.size()];
818    
819                    for (int i = 0; i < propertyElements.size(); i++) {
820                            Element propertyElement = propertyElements.get(i);
821    
822                            String key = propertyElement.attributeValue("key");
823                            String value = propertyElement.attributeValue("value");
824    
825                            properties[i] = key.concat(
826                                    AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR).concat(value);
827                    }
828    
829                    AssetTag existingAssetTag = null;
830    
831                    try {
832                            existingAssetTag = AssetTagUtil.findByG_N(
833                                    portletDataContext.getScopeGroupId(), assetTag.getName());
834                    }
835                    catch (NoSuchTagException nste) {
836                            if (_log.isDebugEnabled()) {
837                                    StringBundler sb = new StringBundler(5);
838    
839                                    sb.append("No AssetTag exists with the key {groupId=");
840                                    sb.append(portletDataContext.getScopeGroupId());
841                                    sb.append(", name=");
842                                    sb.append(assetTag.getName());
843                                    sb.append("}");
844    
845                                    _log.debug(sb.toString());
846                            }
847                    }
848    
849                    try {
850                            if (existingAssetTag == null) {
851                                    importedAssetTag = AssetTagLocalServiceUtil.addTag(
852                                            userId, assetTag.getName(), properties, serviceContext);
853                            }
854                            else {
855                                    importedAssetTag = AssetTagLocalServiceUtil.updateTag(
856                                            userId, existingAssetTag.getTagId(), assetTag.getName(),
857                                            properties, serviceContext);
858                            }
859    
860                            assetTagPKs.put(assetTag.getTagId(), importedAssetTag.getTagId());
861    
862                            portletDataContext.importPermissions(
863                                    AssetTag.class, assetTag.getTagId(),
864                                    importedAssetTag.getTagId());
865                    }
866                    catch (NoSuchTagException nste) {
867                            _log.error(
868                                    "Could not find the parent category for category " +
869                                            assetTag.getTagId());
870                    }
871            }
872    
873            protected void importAssetVocabulary(
874                            PortletDataContext portletDataContext,
875                            Map<Long, Long> assetVocabularyPKs, Element assetVocabularyElement,
876                            AssetVocabulary assetVocabulary)
877                    throws Exception {
878    
879                    long userId = portletDataContext.getUserId(
880                            assetVocabulary.getUserUuid());
881                    long groupId = portletDataContext.getScopeGroupId();
882    
883                    ServiceContext serviceContext = new ServiceContext();
884    
885                    serviceContext.setAddGroupPermissions(true);
886                    serviceContext.setAddGuestPermissions(true);
887                    serviceContext.setCreateDate(assetVocabulary.getCreateDate());
888                    serviceContext.setModifiedDate(assetVocabulary.getModifiedDate());
889                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
890    
891                    AssetVocabulary importedAssetVocabulary = null;
892    
893                    AssetVocabulary existingAssetVocabulary =
894                            AssetVocabularyUtil.fetchByUUID_G(
895                                    assetVocabulary.getUuid(), groupId);
896    
897                    if (existingAssetVocabulary == null) {
898                            existingAssetVocabulary = AssetVocabularyUtil.fetchByUUID_G(
899                                    assetVocabulary.getUuid(),
900                                    portletDataContext.getCompanyGroupId());
901                    }
902    
903                    if (existingAssetVocabulary == null) {
904                            String name = getAssetVocabularyName(
905                                    null, groupId, assetVocabulary.getName(), 2);
906    
907                            serviceContext.setUuid(assetVocabulary.getUuid());
908    
909                            importedAssetVocabulary =
910                                    AssetVocabularyLocalServiceUtil.addVocabulary(
911                                            userId, StringPool.BLANK,
912                                            getAssetVocabularyTitleMap(groupId, assetVocabulary, name),
913                                            assetVocabulary.getDescriptionMap(),
914                                            assetVocabulary.getSettings(), serviceContext);
915                    }
916                    else if (portletDataContext.isCompanyStagedGroupedModel(
917                                            existingAssetVocabulary)) {
918    
919                            return;
920                    }
921                    else {
922                            String name = getAssetVocabularyName(
923                                    assetVocabulary.getUuid(), groupId, assetVocabulary.getName(),
924                                    2);
925    
926                            importedAssetVocabulary =
927                                    AssetVocabularyLocalServiceUtil.updateVocabulary(
928                                            existingAssetVocabulary.getVocabularyId(), StringPool.BLANK,
929                                            getAssetVocabularyTitleMap(groupId, assetVocabulary, name),
930                                            assetVocabulary.getDescriptionMap(),
931                                            assetVocabulary.getSettings(), serviceContext);
932                    }
933    
934                    assetVocabularyPKs.put(
935                            assetVocabulary.getVocabularyId(),
936                            importedAssetVocabulary.getVocabularyId());
937    
938                    portletDataContext.importPermissions(
939                            AssetVocabulary.class, assetVocabulary.getVocabularyId(),
940                            importedAssetVocabulary.getVocabularyId());
941            }
942    
943            protected void importPortletData(
944                            PortletDataContext portletDataContext, String portletId, long plid,
945                            Element portletDataElement)
946                    throws Exception {
947    
948                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
949                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
950    
951                    PortletPreferences portletPreferences =
952                            PortletPreferencesUtil.fetchByO_O_P_P(
953                                    ownerId, ownerType, plid, portletId);
954    
955                    if (portletPreferences == null) {
956                            portletPreferences =
957                                    new com.liferay.portal.model.impl.PortletPreferencesImpl();
958                    }
959    
960                    String xml = importPortletData(
961                            portletDataContext, portletId, portletPreferences,
962                            portletDataElement);
963    
964                    if (Validator.isNotNull(xml)) {
965                            PortletPreferencesLocalServiceUtil.updatePreferences(
966                                    ownerId, ownerType, plid, portletId, xml);
967                    }
968            }
969    
970            protected void importPortletPreferences(
971                            PortletDataContext portletDataContext, long companyId, long groupId,
972                            Layout layout, String portletId, Element parentElement,
973                            boolean preserveScopeLayoutId, boolean importPortletArchivedSetups,
974                            boolean importPortletData, boolean importPortletSetup,
975                            boolean importPortletUserPreferences)
976                    throws Exception {
977    
978                    if (portletId == null) {
979                            portletId = parentElement.attributeValue("portlet-id");
980                    }
981    
982                    long plid = LayoutConstants.DEFAULT_PLID;
983                    String scopeType = StringPool.BLANK;
984                    String scopeLayoutUuid = StringPool.BLANK;
985    
986                    if (layout != null) {
987                            plid = layout.getPlid();
988    
989                            if (preserveScopeLayoutId && (portletId != null)) {
990                                    javax.portlet.PortletPreferences jxPortletPreferences =
991                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
992                                                    layout, portletId);
993    
994                                    scopeType = GetterUtil.getString(
995                                            jxPortletPreferences.getValue("lfrScopeType", null));
996                                    scopeLayoutUuid = GetterUtil.getString(
997                                            jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
998    
999                                    portletDataContext.setScopeType(scopeType);
1000                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1001                            }
1002                    }
1003    
1004                    List<Element> portletPreferencesElements = parentElement.elements(
1005                            "portlet-preferences");
1006    
1007                    for (Element portletPreferencesElement : portletPreferencesElements) {
1008                            String path = portletPreferencesElement.attributeValue("path");
1009    
1010                            if (portletDataContext.isPathNotProcessed(path)) {
1011                                    String xml = null;
1012    
1013                                    Element element = null;
1014    
1015                                    try {
1016                                            xml = portletDataContext.getZipEntryAsString(path);
1017    
1018                                            Document preferencesDocument = SAXReaderUtil.read(xml);
1019    
1020                                            element = preferencesDocument.getRootElement();
1021                                    }
1022                                    catch (DocumentException de) {
1023                                            throw new SystemException(de);
1024                                    }
1025    
1026                                    long ownerId = GetterUtil.getLong(
1027                                            element.attributeValue("owner-id"));
1028                                    int ownerType = GetterUtil.getInteger(
1029                                            element.attributeValue("owner-type"));
1030    
1031                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
1032                                            !importPortletSetup) {
1033    
1034                                            continue;
1035                                    }
1036    
1037                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
1038                                            !importPortletArchivedSetups) {
1039    
1040                                            continue;
1041                                    }
1042    
1043                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
1044                                            (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
1045                                            !importPortletUserPreferences) {
1046    
1047                                            continue;
1048                                    }
1049    
1050                                    long curPlid = plid;
1051                                    String curPortletId = portletId;
1052    
1053                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1054                                            curPlid = PortletKeys.PREFS_PLID_SHARED;
1055                                            curPortletId = PortletConstants.getRootPortletId(portletId);
1056                                            ownerId = portletDataContext.getScopeGroupId();
1057                                    }
1058    
1059                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1060                                            String userUuid = element.attributeValue(
1061                                                    "archive-user-uuid");
1062    
1063                                            long userId = portletDataContext.getUserId(userUuid);
1064    
1065                                            String name = element.attributeValue("archive-name");
1066    
1067                                            curPortletId = PortletConstants.getRootPortletId(portletId);
1068    
1069                                            PortletItem portletItem =
1070                                                    PortletItemLocalServiceUtil.updatePortletItem(
1071                                                            userId, groupId, name, curPortletId,
1072                                                            PortletPreferences.class.getName());
1073    
1074                                            curPlid = LayoutConstants.DEFAULT_PLID;
1075                                            ownerId = portletItem.getPortletItemId();
1076                                    }
1077    
1078                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1079                                            String userUuid = element.attributeValue("user-uuid");
1080    
1081                                            ownerId = portletDataContext.getUserId(userUuid);
1082                                    }
1083    
1084                                    boolean defaultUser = GetterUtil.getBoolean(
1085                                            element.attributeValue("default-user"));
1086    
1087                                    if (defaultUser) {
1088                                            ownerId = UserLocalServiceUtil.getDefaultUserId(companyId);
1089                                    }
1090    
1091                                    javax.portlet.PortletPreferences jxPortletPreferences =
1092                                            PortletPreferencesFactoryUtil.fromXML(
1093                                                    companyId, ownerId, ownerType, curPlid, curPortletId,
1094                                                    xml);
1095    
1096                                    Element importDataRootElement =
1097                                            portletDataContext.getImportDataRootElement();
1098    
1099                                    try {
1100                                            Element preferenceDataElement =
1101                                                    portletPreferencesElement.element("preference-data");
1102    
1103                                            if (preferenceDataElement != null) {
1104                                                    portletDataContext.setImportDataRootElement(
1105                                                            preferenceDataElement);
1106                                            }
1107    
1108                                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1109                                                    portletDataContext.getCompanyId(), curPortletId);
1110    
1111                                            PortletDataHandler portletDataHandler =
1112                                                    portlet.getPortletDataHandlerInstance();
1113    
1114                                            jxPortletPreferences =
1115                                                    portletDataHandler.processImportPortletPreferences(
1116                                                            portletDataContext, curPortletId,
1117                                                            jxPortletPreferences);
1118                                    }
1119                                    finally {
1120                                            portletDataContext.setImportDataRootElement(
1121                                                    importDataRootElement);
1122                                    }
1123    
1124                                    updatePortletPreferences(
1125                                            portletDataContext, ownerId, ownerType, curPlid,
1126                                            curPortletId,
1127                                            PortletPreferencesFactoryUtil.toXML(jxPortletPreferences),
1128                                            importPortletData);
1129                            }
1130                    }
1131    
1132                    if (preserveScopeLayoutId && (layout != null)) {
1133                            javax.portlet.PortletPreferences jxPortletPreferences =
1134                                    PortletPreferencesFactoryUtil.getLayoutPortletSetup(
1135                                            layout, portletId);
1136    
1137                            try {
1138                                    jxPortletPreferences.setValue("lfrScopeType", scopeType);
1139                                    jxPortletPreferences.setValue(
1140                                            "lfrScopeLayoutUuid", scopeLayoutUuid);
1141    
1142                                    jxPortletPreferences.store();
1143                            }
1144                            finally {
1145                                    portletDataContext.setScopeType(scopeType);
1146                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1147                            }
1148                    }
1149            }
1150    
1151            protected void readAssetCategories(PortletDataContext portletDataContext)
1152                    throws Exception {
1153    
1154                    String xml = portletDataContext.getZipEntryAsString(
1155                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1156                                    "/categories-hierarchy.xml");
1157    
1158                    if (xml == null) {
1159                            return;
1160                    }
1161    
1162                    Document document = SAXReaderUtil.read(xml);
1163    
1164                    Element rootElement = document.getRootElement();
1165    
1166                    Element assetVocabulariesElement = rootElement.element("vocabularies");
1167    
1168                    List<Element> assetVocabularyElements =
1169                            assetVocabulariesElement.elements("vocabulary");
1170    
1171                    Map<Long, Long> assetVocabularyPKs =
1172                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1173                                    AssetVocabulary.class);
1174    
1175                    for (Element assetVocabularyElement : assetVocabularyElements) {
1176                            String path = assetVocabularyElement.attributeValue("path");
1177    
1178                            if (!portletDataContext.isPathNotProcessed(path)) {
1179                                    continue;
1180                            }
1181    
1182                            AssetVocabulary assetVocabulary =
1183                                    (AssetVocabulary)portletDataContext.getZipEntryAsObject(path);
1184    
1185                            importAssetVocabulary(
1186                                    portletDataContext, assetVocabularyPKs, assetVocabularyElement,
1187                                    assetVocabulary);
1188                    }
1189    
1190                    Element assetCategoriesElement = rootElement.element("categories");
1191    
1192                    List<Element> assetCategoryElements = assetCategoriesElement.elements(
1193                            "category");
1194    
1195                    Map<Long, Long> assetCategoryPKs =
1196                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1197                                    AssetCategory.class);
1198    
1199                    Map<String, String> assetCategoryUuids =
1200                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1201                                    AssetCategory.class + ".uuid");
1202    
1203                    for (Element assetCategoryElement : assetCategoryElements) {
1204                            String path = assetCategoryElement.attributeValue("path");
1205    
1206                            if (!portletDataContext.isPathNotProcessed(path)) {
1207                                    continue;
1208                            }
1209    
1210                            AssetCategory assetCategory =
1211                                    (AssetCategory)portletDataContext.getZipEntryAsObject(path);
1212    
1213                            importAssetCategory(
1214                                    portletDataContext, assetVocabularyPKs, assetCategoryPKs,
1215                                    assetCategoryUuids, assetCategoryElement, assetCategory);
1216                    }
1217    
1218                    Element assetsElement = rootElement.element("assets");
1219    
1220                    List<Element> assetElements = assetsElement.elements("asset");
1221    
1222                    for (Element assetElement : assetElements) {
1223                            String className = GetterUtil.getString(
1224                                    assetElement.attributeValue("class-name"));
1225                            long classPK = GetterUtil.getLong(
1226                                    assetElement.attributeValue("class-pk"));
1227                            String[] assetCategoryUuidArray = StringUtil.split(
1228                                    GetterUtil.getString(
1229                                            assetElement.attributeValue("category-uuids")));
1230    
1231                            long[] assetCategoryIds = new long[0];
1232    
1233                            for (String assetCategoryUuid : assetCategoryUuidArray) {
1234                                    assetCategoryUuid = MapUtil.getString(
1235                                            assetCategoryUuids, assetCategoryUuid, assetCategoryUuid);
1236    
1237                                    AssetCategory assetCategory = AssetCategoryUtil.fetchByUUID_G(
1238                                            assetCategoryUuid, portletDataContext.getScopeGroupId());
1239    
1240                                    if (assetCategory == null) {
1241                                            Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1242                                                    portletDataContext.getCompanyId());
1243    
1244                                            assetCategory = AssetCategoryUtil.fetchByUUID_G(
1245                                                    assetCategoryUuid, companyGroup.getGroupId());
1246                                    }
1247    
1248                                    if (assetCategory != null) {
1249                                            assetCategoryIds = ArrayUtil.append(
1250                                                    assetCategoryIds, assetCategory.getCategoryId());
1251                                    }
1252                            }
1253    
1254                            portletDataContext.addAssetCategories(
1255                                    className, classPK, assetCategoryIds);
1256                    }
1257            }
1258    
1259            protected void readAssetLinks(PortletDataContext portletDataContext)
1260                    throws Exception {
1261    
1262                    String xml = portletDataContext.getZipEntryAsString(
1263                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1264                                    "/links.xml");
1265    
1266                    if (xml == null) {
1267                            return;
1268                    }
1269    
1270                    Document document = SAXReaderUtil.read(xml);
1271    
1272                    Element rootElement = document.getRootElement();
1273    
1274                    List<Element> assetLinkGroupElements = rootElement.elements(
1275                            "asset-link-group");
1276    
1277                    for (Element assetLinkGroupElement : assetLinkGroupElements) {
1278                            String sourceUuid = assetLinkGroupElement.attributeValue(
1279                                    "source-uuid");
1280    
1281                            AssetEntry sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1282                                    portletDataContext.getScopeGroupId(), sourceUuid);
1283    
1284                            if (sourceAssetEntry == null) {
1285                                    sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1286                                            portletDataContext.getCompanyGroupId(), sourceUuid);
1287                            }
1288    
1289                            if (sourceAssetEntry == null) {
1290                                    if (_log.isWarnEnabled()) {
1291                                            _log.warn(
1292                                                    "Unable to find asset entry with uuid " + sourceUuid);
1293                                    }
1294    
1295                                    continue;
1296                            }
1297    
1298                            List<Element> assetLinksElements = assetLinkGroupElement.elements(
1299                                    "asset-link");
1300    
1301                            for (Element assetLinkElement : assetLinksElements) {
1302                                    String path = assetLinkElement.attributeValue("path");
1303    
1304                                    if (!portletDataContext.isPathNotProcessed(path)) {
1305                                            continue;
1306                                    }
1307    
1308                                    String targetUuid = assetLinkElement.attributeValue(
1309                                            "target-uuid");
1310    
1311                                    AssetEntry targetAssetEntry =
1312                                            AssetEntryLocalServiceUtil.fetchEntry(
1313                                                    portletDataContext.getScopeGroupId(), targetUuid);
1314    
1315                                    if (targetAssetEntry == null) {
1316                                            targetAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1317                                                    portletDataContext.getCompanyGroupId(), targetUuid);
1318                                    }
1319    
1320                                    if (targetAssetEntry == null) {
1321                                            if (_log.isWarnEnabled()) {
1322                                                    _log.warn(
1323                                                            "Unable to find asset entry with uuid " +
1324                                                                    targetUuid);
1325                                            }
1326    
1327                                            continue;
1328                                    }
1329    
1330                                    AssetLink assetLink =
1331                                            (AssetLink)portletDataContext.getZipEntryAsObject(path);
1332    
1333                                    long userId = portletDataContext.getUserId(
1334                                            assetLink.getUserUuid());
1335    
1336                                    AssetLinkLocalServiceUtil.updateLink(
1337                                            userId, sourceAssetEntry.getEntryId(),
1338                                            targetAssetEntry.getEntryId(), assetLink.getType(),
1339                                            assetLink.getWeight());
1340                            }
1341                    }
1342            }
1343    
1344            protected void readAssetTags(PortletDataContext portletDataContext)
1345                    throws Exception {
1346    
1347                    String xml = portletDataContext.getZipEntryAsString(
1348                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1349                                    "/tags.xml");
1350    
1351                    if (xml == null) {
1352                            return;
1353                    }
1354    
1355                    Document document = SAXReaderUtil.read(xml);
1356    
1357                    Element rootElement = document.getRootElement();
1358    
1359                    List<Element> assetTagElements = rootElement.elements("tag");
1360    
1361                    for (Element assetTagElement : assetTagElements) {
1362                            String path = assetTagElement.attributeValue("path");
1363    
1364                            if (!portletDataContext.isPathNotProcessed(path)) {
1365                                    continue;
1366                            }
1367    
1368                            AssetTag assetTag =
1369                                    (AssetTag)portletDataContext.getZipEntryAsObject(path);
1370    
1371                            Map<Long, Long> assetTagPKs =
1372                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1373                                            AssetTag.class);
1374    
1375                            importAssetTag(
1376                                    portletDataContext, assetTagPKs, assetTagElement, assetTag);
1377                    }
1378    
1379                    List<Element> assetElements = rootElement.elements("asset");
1380    
1381                    for (Element assetElement : assetElements) {
1382                            String className = GetterUtil.getString(
1383                                    assetElement.attributeValue("class-name"));
1384                            long classPK = GetterUtil.getLong(
1385                                    assetElement.attributeValue("class-pk"));
1386                            String assetTagNames = GetterUtil.getString(
1387                                    assetElement.attributeValue("tags"));
1388    
1389                            portletDataContext.addAssetTags(
1390                                    className, classPK, StringUtil.split(assetTagNames));
1391                    }
1392            }
1393    
1394            protected void readComments(PortletDataContext portletDataContext)
1395                    throws Exception {
1396    
1397                    String xml = portletDataContext.getZipEntryAsString(
1398                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1399                                    "/comments.xml");
1400    
1401                    if (xml == null) {
1402                            return;
1403                    }
1404    
1405                    Document document = SAXReaderUtil.read(xml);
1406    
1407                    Element rootElement = document.getRootElement();
1408    
1409                    List<Element> assetElements = rootElement.elements("asset");
1410    
1411                    for (Element assetElement : assetElements) {
1412                            String path = assetElement.attributeValue("path");
1413                            String className = assetElement.attributeValue("class-name");
1414                            long classPK = GetterUtil.getLong(
1415                                    assetElement.attributeValue("class-pk"));
1416    
1417                            List<String> zipFolderEntries =
1418                                    portletDataContext.getZipFolderEntries(path);
1419    
1420                            List<MBMessage> mbMessages = new ArrayList<MBMessage>();
1421    
1422                            for (String zipFolderEntry : zipFolderEntries) {
1423                                    MBMessage mbMessage =
1424                                            (MBMessage)portletDataContext.getZipEntryAsObject(
1425                                                    zipFolderEntry);
1426    
1427                                    if (mbMessage != null) {
1428                                            mbMessages.add(mbMessage);
1429                                    }
1430                            }
1431    
1432                            portletDataContext.addComments(className, classPK, mbMessages);
1433                    }
1434            }
1435    
1436            protected void readExpandoTables(PortletDataContext portletDataContext)
1437                    throws Exception {
1438    
1439                    String xml = portletDataContext.getZipEntryAsString(
1440                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1441                                    "/expando-tables.xml");
1442    
1443                    if (xml == null) {
1444                            return;
1445                    }
1446    
1447                    Document document = SAXReaderUtil.read(xml);
1448    
1449                    Element rootElement = document.getRootElement();
1450    
1451                    List<Element> expandoTableElements = rootElement.elements(
1452                            "expando-table");
1453    
1454                    for (Element expandoTableElement : expandoTableElements) {
1455                            String className = expandoTableElement.attributeValue("class-name");
1456    
1457                            ExpandoTable expandoTable = null;
1458    
1459                            try {
1460                                    expandoTable = ExpandoTableLocalServiceUtil.getDefaultTable(
1461                                            portletDataContext.getCompanyId(), className);
1462                            }
1463                            catch (NoSuchTableException nste) {
1464                                    expandoTable = ExpandoTableLocalServiceUtil.addDefaultTable(
1465                                            portletDataContext.getCompanyId(), className);
1466                            }
1467    
1468                            List<Element> expandoColumnElements = expandoTableElement.elements(
1469                                    "expando-column");
1470    
1471                            for (Element expandoColumnElement : expandoColumnElements) {
1472                                    long columnId = GetterUtil.getLong(
1473                                            expandoColumnElement.attributeValue("column-id"));
1474                                    String name = expandoColumnElement.attributeValue("name");
1475                                    int type = GetterUtil.getInteger(
1476                                            expandoColumnElement.attributeValue("type"));
1477                                    String defaultData = expandoColumnElement.elementText(
1478                                            "default-data");
1479                                    String typeSettings = expandoColumnElement.elementText(
1480                                            "type-settings");
1481    
1482                                    Serializable defaultDataObject =
1483                                            ExpandoConverterUtil.getAttributeFromString(
1484                                                    type, defaultData);
1485    
1486                                    ExpandoColumn expandoColumn =
1487                                            ExpandoColumnLocalServiceUtil.getColumn(
1488                                                    expandoTable.getTableId(), name);
1489    
1490                                    if (expandoColumn != null) {
1491                                            ExpandoColumnLocalServiceUtil.updateColumn(
1492                                                    expandoColumn.getColumnId(), name, type,
1493                                                    defaultDataObject);
1494                                    }
1495                                    else {
1496                                            expandoColumn = ExpandoColumnLocalServiceUtil.addColumn(
1497                                                    expandoTable.getTableId(), name, type,
1498                                                    defaultDataObject);
1499                                    }
1500    
1501                                    ExpandoColumnLocalServiceUtil.updateTypeSettings(
1502                                            expandoColumn.getColumnId(), typeSettings);
1503    
1504                                    portletDataContext.importPermissions(
1505                                            ExpandoColumn.class, columnId, expandoColumn.getColumnId());
1506                            }
1507                    }
1508            }
1509    
1510            protected void readLocks(PortletDataContext portletDataContext)
1511                    throws Exception {
1512    
1513                    String xml = portletDataContext.getZipEntryAsString(
1514                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1515                                    "/locks.xml");
1516    
1517                    if (xml == null) {
1518                            return;
1519                    }
1520    
1521                    Document document = SAXReaderUtil.read(xml);
1522    
1523                    Element rootElement = document.getRootElement();
1524    
1525                    List<Element> assetElements = rootElement.elements("asset");
1526    
1527                    for (Element assetElement : assetElements) {
1528                            String path = assetElement.attributeValue("path");
1529                            String className = assetElement.attributeValue("class-name");
1530                            String key = assetElement.attributeValue("key");
1531    
1532                            Lock lock = (Lock)portletDataContext.getZipEntryAsObject(path);
1533    
1534                            if (lock != null) {
1535                                    portletDataContext.addLocks(className, key, lock);
1536                            }
1537                    }
1538            }
1539    
1540            protected void readRatingsEntries(PortletDataContext portletDataContext)
1541                    throws Exception {
1542    
1543                    String xml = portletDataContext.getZipEntryAsString(
1544                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1545                                    "/ratings.xml");
1546    
1547                    if (xml == null) {
1548                            return;
1549                    }
1550    
1551                    Document document = SAXReaderUtil.read(xml);
1552    
1553                    Element rootElement = document.getRootElement();
1554    
1555                    List<Element> assetElements = rootElement.elements("asset");
1556    
1557                    for (Element assetElement : assetElements) {
1558                            String path = assetElement.attributeValue("path");
1559                            String className = assetElement.attributeValue("class-name");
1560                            long classPK = GetterUtil.getLong(
1561                                    assetElement.attributeValue("class-pk"));
1562    
1563                            List<String> zipFolderEntries =
1564                                    portletDataContext.getZipFolderEntries(path);
1565    
1566                            List<RatingsEntry> ratingsEntries = new ArrayList<RatingsEntry>();
1567    
1568                            for (String zipFolderEntry : zipFolderEntries) {
1569                                    RatingsEntry ratingsEntry =
1570                                            (RatingsEntry)portletDataContext.getZipEntryAsObject(
1571                                                    zipFolderEntry);
1572    
1573                                    if (ratingsEntry != null) {
1574                                            ratingsEntries.add(ratingsEntry);
1575                                    }
1576                            }
1577    
1578                            portletDataContext.addRatingsEntries(
1579                                    className, classPK, ratingsEntries);
1580                    }
1581            }
1582    
1583            protected void readXML(PortletDataContext portletDataContext)
1584                    throws Exception {
1585    
1586                    if ((_rootElement != null) && (_headerElement != null)) {
1587                            return;
1588                    }
1589    
1590                    String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
1591    
1592                    if (xml == null) {
1593                            throw new LARFileException("manifest.xml not found in the LAR");
1594                    }
1595    
1596                    try {
1597                            Document document = SAXReaderUtil.read(xml);
1598    
1599                            _rootElement = document.getRootElement();
1600    
1601                            portletDataContext.setImportDataRootElement(_rootElement);
1602                    }
1603                    catch (Exception e) {
1604                            throw new LARFileException(e);
1605                    }
1606    
1607                    _headerElement = _rootElement.element("header");
1608            }
1609    
1610            protected void resetPortletScope(
1611                    PortletDataContext portletDataContext, long groupId) {
1612    
1613                    portletDataContext.setScopeGroupId(groupId);
1614                    portletDataContext.setScopeLayoutUuid(StringPool.BLANK);
1615                    portletDataContext.setScopeType(StringPool.BLANK);
1616            }
1617    
1618            protected void updatePortletPreferences(
1619                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1620                            long plid, String portletId, String xml, boolean importData)
1621                    throws Exception {
1622    
1623                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1624                            portletDataContext.getCompanyId(), portletId);
1625    
1626                    if (portlet == null) {
1627                            if (_log.isDebugEnabled()) {
1628                                    _log.debug(
1629                                            "Do not update portlet preferences for " + portletId +
1630                                                    " because the portlet does not exist");
1631                            }
1632    
1633                            return;
1634                    }
1635    
1636                    PortletDataHandler portletDataHandler =
1637                            portlet.getPortletDataHandlerInstance();
1638    
1639                    if (importData || !MergeLayoutPrototypesThreadLocal.isInProgress()) {
1640                            PortletPreferencesLocalServiceUtil.updatePreferences(
1641                                    ownerId, ownerType, plid, portletId, xml);
1642    
1643                            return;
1644                    }
1645    
1646                    // Portlet preferences to be updated only when importing data
1647    
1648                    String[] dataPortletPreferences =
1649                            portletDataHandler.getDataPortletPreferences();
1650    
1651                    // Current portlet preferences
1652    
1653                    javax.portlet.PortletPreferences portletPreferences =
1654                            PortletPreferencesLocalServiceUtil.getPreferences(
1655                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1656                                    portletId);
1657    
1658                    // New portlet preferences
1659    
1660                    javax.portlet.PortletPreferences jxPortletPreferences =
1661                            PortletPreferencesFactoryUtil.fromXML(
1662                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1663                                    portletId, xml);
1664    
1665                    Enumeration<String> enu = jxPortletPreferences.getNames();
1666    
1667                    while (enu.hasMoreElements()) {
1668                            String name = enu.nextElement();
1669    
1670                            String scopeLayoutUuid = portletDataContext.getScopeLayoutUuid();
1671                            String scopeType = portletDataContext.getScopeType();
1672    
1673                            if (!ArrayUtil.contains(dataPortletPreferences, name) ||
1674                                    (Validator.isNull(scopeLayoutUuid) &&
1675                                     scopeType.equals("company"))) {
1676    
1677                                    String[] values = jxPortletPreferences.getValues(name, null);
1678    
1679                                    portletPreferences.setValues(name, values);
1680                            }
1681                    }
1682    
1683                    PortletPreferencesLocalServiceUtil.updatePreferences(
1684                            ownerId, ownerType, plid, portletId, portletPreferences);
1685            }
1686    
1687            protected void validateFile(
1688                            PortletDataContext portletDataContext, String portletId)
1689                    throws Exception {
1690    
1691                    // Build compatibility
1692    
1693                    readXML(portletDataContext);
1694    
1695                    int buildNumber = ReleaseInfo.getBuildNumber();
1696    
1697                    int importBuildNumber = GetterUtil.getInteger(
1698                            _headerElement.attributeValue("build-number"));
1699    
1700                    if (buildNumber != importBuildNumber) {
1701                            throw new LayoutImportException(
1702                                    "LAR build number " + importBuildNumber + " does not match " +
1703                                            "portal build number " + buildNumber);
1704                    }
1705    
1706                    // Type
1707    
1708                    String larType = _headerElement.attributeValue("type");
1709    
1710                    if (!larType.equals("portlet")) {
1711                            throw new LARTypeException(larType);
1712                    }
1713    
1714                    // Portlet compatibility
1715    
1716                    String rootPortletId = _headerElement.attributeValue("root-portlet-id");
1717    
1718                    if (!PortletConstants.getRootPortletId(portletId).equals(
1719                                    rootPortletId)) {
1720    
1721                            throw new PortletIdException("Invalid portlet id " + rootPortletId);
1722                    }
1723    
1724                    // Available locales
1725    
1726                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1727                            portletDataContext.getCompanyId(), portletId);
1728    
1729                    PortletDataHandler portletDataHandler =
1730                            portlet.getPortletDataHandlerInstance();
1731    
1732                    if (portletDataHandler.isDataLocalized()) {
1733                            Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1734                                    StringUtil.split(
1735                                            _headerElement.attributeValue("available-locales")));
1736    
1737                            Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1738                                    PortalUtil.getSiteGroupId(
1739                                            portletDataContext.getScopeGroupId()));
1740    
1741                            for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1742                                    if (!ArrayUtil.contains(
1743                                                    targetAvailableLocales, sourceAvailableLocale)) {
1744    
1745                                            LocaleException le = new LocaleException(
1746                                                    LocaleException.TYPE_EXPORT_IMPORT,
1747                                                    "Locale " + sourceAvailableLocale + " is not " +
1748                                                            "available in company " +
1749                                                                    portletDataContext.getCompanyId());
1750    
1751                                            le.setSourceAvailableLocales(sourceAvailableLocales);
1752                                            le.setTargetAvailableLocales(targetAvailableLocales);
1753    
1754                                            throw le;
1755                                    }
1756                            }
1757                    }
1758            }
1759    
1760            private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
1761    
1762            private DeletionSystemEventImporter _deletionSystemEventImporter =
1763                    new DeletionSystemEventImporter();
1764            private Element _headerElement;
1765            private PermissionImporter _permissionImporter = new PermissionImporter();
1766            private Element _rootElement;
1767    
1768    }