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