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