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