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