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 groupId = portletDataContext.getGroupId();
692                    long userId = portletDataContext.getUserId(assetCategory.getUserUuid());
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                            (portletDataContext.getSourceGroupId() !=
769                                    portletDataContext.getCompanyGroupId())) {
770    
771                            existingAssetCategory = AssetCategoryUtil.fetchByUUID_G(
772                                    assetCategory.getUuid(),
773                                    portletDataContext.getCompanyGroupId());
774                    }
775    
776                    if (existingAssetCategory == null) {
777                            existingAssetCategory = AssetCategoryUtil.fetchByG_P_N_V_First(
778                                    groupId, parentAssetCategoryId, assetCategory.getName(),
779                                    assetVocabularyId, null);
780                    }
781    
782                    if (existingAssetCategory == null) {
783                            serviceContext.setUuid(assetCategory.getUuid());
784    
785                            importedAssetCategory = AssetCategoryLocalServiceUtil.addCategory(
786                                    userId, parentAssetCategoryId,
787                                    getAssetCategoryTitleMap(
788                                            groupId, assetCategory, assetCategory.getName()),
789                                    assetCategory.getDescriptionMap(), assetVocabularyId,
790                                    properties, serviceContext);
791                    }
792                    else if (portletDataContext.isCompanyStagedGroupedModel(
793                                            existingAssetCategory)) {
794    
795                            return;
796                    }
797                    else {
798                            String name = getAssetCategoryName(
799                                    existingAssetCategory.getUuid(), groupId, parentAssetCategoryId,
800                                    assetCategory.getName(), assetVocabularyId, 2);
801    
802                            if (!Validator.equals(existingAssetCategory.getName(), name)) {
803                                    List<AssetEntry> assetCategoryAssetEntries =
804                                            AssetEntryLocalServiceUtil.getAssetCategoryAssetEntries(
805                                                    existingAssetCategory.getCategoryId());
806    
807                                    for (AssetEntry assetCategoryAssetEntry :
808                                                    assetCategoryAssetEntries) {
809    
810                                            String className = PortalUtil.getClassName(
811                                                    assetCategoryAssetEntry.getClassNameId());
812    
813                                            Map<Long, Long> newPrimaryKeysMap =
814                                                    (Map<Long, Long>)
815                                                            portletDataContext.getNewPrimaryKeysMap(className);
816    
817                                            // Force reindex
818    
819                                            newPrimaryKeysMap.put(
820                                                    assetCategoryAssetEntry.getClassPK(),
821                                                    assetCategoryAssetEntry.getClassPK());
822                                    }
823                            }
824    
825                            importedAssetCategory =
826                                    AssetCategoryLocalServiceUtil.updateCategory(
827                                            userId, existingAssetCategory.getCategoryId(),
828                                            parentAssetCategoryId,
829                                            getAssetCategoryTitleMap(groupId, assetCategory, name),
830                                            assetCategory.getDescriptionMap(), assetVocabularyId,
831                                            properties, serviceContext);
832    
833                            String assetCategoryUuid = assetCategory.getUuid();
834    
835                            if (!assetCategoryUuid.equals(importedAssetCategory.getUuid())) {
836                                    importedAssetCategory.setUuid(assetCategory.getUuid());
837    
838                                    AssetCategoryLocalServiceUtil.updateAssetCategory(
839                                            importedAssetCategory);
840                            }
841                    }
842    
843                    assetCategoryPKs.put(
844                            assetCategory.getCategoryId(),
845                            importedAssetCategory.getCategoryId());
846    
847                    assetCategoryUuids.put(
848                            assetCategory.getUuid(), importedAssetCategory.getUuid());
849    
850                    portletDataContext.importPermissions(
851                            AssetCategory.class, assetCategory.getCategoryId(),
852                            importedAssetCategory.getCategoryId());
853            }
854    
855            protected void importAssetTag(
856                            PortletDataContext portletDataContext, Map<Long, Long> assetTagPKs,
857                            Element assetTagElement, AssetTag assetTag)
858                    throws PortalException, SystemException {
859    
860                    long userId = portletDataContext.getUserId(assetTag.getUserUuid());
861    
862                    ServiceContext serviceContext = new ServiceContext();
863    
864                    serviceContext.setAddGroupPermissions(true);
865                    serviceContext.setAddGuestPermissions(true);
866                    serviceContext.setCreateDate(assetTag.getCreateDate());
867                    serviceContext.setModifiedDate(assetTag.getModifiedDate());
868                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
869    
870                    AssetTag importedAssetTag = null;
871    
872                    List<Element> propertyElements = assetTagElement.elements("property");
873    
874                    String[] properties = new String[propertyElements.size()];
875    
876                    for (int i = 0; i < propertyElements.size(); i++) {
877                            Element propertyElement = propertyElements.get(i);
878    
879                            String key = propertyElement.attributeValue("key");
880                            String value = propertyElement.attributeValue("value");
881    
882                            properties[i] = key.concat(
883                                    AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR).concat(value);
884                    }
885    
886                    AssetTag existingAssetTag = null;
887    
888                    try {
889                            existingAssetTag = AssetTagUtil.findByG_N(
890                                    portletDataContext.getScopeGroupId(), assetTag.getName());
891                    }
892                    catch (NoSuchTagException nste) {
893                            if (_log.isDebugEnabled()) {
894                                    StringBundler sb = new StringBundler(5);
895    
896                                    sb.append("No AssetTag exists with the key {groupId=");
897                                    sb.append(portletDataContext.getScopeGroupId());
898                                    sb.append(", name=");
899                                    sb.append(assetTag.getName());
900                                    sb.append("}");
901    
902                                    _log.debug(sb.toString());
903                            }
904                    }
905    
906                    try {
907                            if (existingAssetTag == null) {
908                                    importedAssetTag = AssetTagLocalServiceUtil.addTag(
909                                            userId, assetTag.getName(), properties, serviceContext);
910                            }
911                            else {
912                                    importedAssetTag = AssetTagLocalServiceUtil.updateTag(
913                                            userId, existingAssetTag.getTagId(), assetTag.getName(),
914                                            properties, serviceContext);
915                            }
916    
917                            assetTagPKs.put(assetTag.getTagId(), importedAssetTag.getTagId());
918    
919                            portletDataContext.importPermissions(
920                                    AssetTag.class, assetTag.getTagId(),
921                                    importedAssetTag.getTagId());
922                    }
923                    catch (NoSuchTagException nste) {
924                            _log.error(
925                                    "Could not find the parent category for category " +
926                                            assetTag.getTagId());
927                    }
928            }
929    
930            protected void importAssetVocabulary(
931                            PortletDataContext portletDataContext,
932                            Map<Long, Long> assetVocabularyPKs, Element assetVocabularyElement,
933                            AssetVocabulary assetVocabulary)
934                    throws Exception {
935    
936                    long groupId = portletDataContext.getScopeGroupId();
937                    long userId = portletDataContext.getUserId(
938                            assetVocabulary.getUserUuid());
939    
940                    ServiceContext serviceContext = new ServiceContext();
941    
942                    serviceContext.setAddGroupPermissions(true);
943                    serviceContext.setAddGuestPermissions(true);
944                    serviceContext.setCreateDate(assetVocabulary.getCreateDate());
945                    serviceContext.setModifiedDate(assetVocabulary.getModifiedDate());
946                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
947    
948                    AssetVocabulary importedAssetVocabulary = null;
949    
950                    AssetVocabulary existingAssetVocabulary =
951                            AssetVocabularyUtil.fetchByUUID_G(
952                                    assetVocabulary.getUuid(), groupId);
953    
954                    if ((existingAssetVocabulary == null) &&
955                            (portletDataContext.getSourceGroupId() !=
956                                    portletDataContext.getCompanyGroupId())) {
957    
958                            existingAssetVocabulary = AssetVocabularyUtil.fetchByUUID_G(
959                                    assetVocabulary.getUuid(),
960                                    portletDataContext.getCompanyGroupId());
961                    }
962    
963                    if (existingAssetVocabulary == null) {
964                            existingAssetVocabulary = AssetVocabularyUtil.fetchByG_N(
965                                    groupId, assetVocabulary.getName());
966                    }
967    
968                    if (existingAssetVocabulary == null) {
969                            serviceContext.setUuid(assetVocabulary.getUuid());
970    
971                            importedAssetVocabulary =
972                                    AssetVocabularyLocalServiceUtil.addVocabulary(
973                                            userId, StringPool.BLANK,
974                                            getAssetVocabularyTitleMap(
975                                                    groupId, assetVocabulary, assetVocabulary.getName()),
976                                            assetVocabulary.getDescriptionMap(),
977                                            assetVocabulary.getSettings(), serviceContext);
978                    }
979                    else if (portletDataContext.isCompanyStagedGroupedModel(
980                                            existingAssetVocabulary)) {
981    
982                            return;
983                    }
984                    else {
985                            String name = getAssetVocabularyName(
986                                    existingAssetVocabulary.getUuid(), groupId,
987                                    assetVocabulary.getName(), 2);
988    
989                            importedAssetVocabulary =
990                                    AssetVocabularyLocalServiceUtil.updateVocabulary(
991                                            existingAssetVocabulary.getVocabularyId(), StringPool.BLANK,
992                                            getAssetVocabularyTitleMap(groupId, assetVocabulary, name),
993                                            assetVocabulary.getDescriptionMap(),
994                                            assetVocabulary.getSettings(), serviceContext);
995    
996                            String assetVocabularyUuid = assetVocabulary.getUuid();
997    
998                            if (!assetVocabularyUuid.equals(
999                                            importedAssetVocabulary.getUuid())) {
1000    
1001                                    importedAssetVocabulary.setUuid(assetVocabulary.getUuid());
1002    
1003                                    AssetVocabularyLocalServiceUtil.updateAssetVocabulary(
1004                                            importedAssetVocabulary);
1005                            }
1006                    }
1007    
1008                    assetVocabularyPKs.put(
1009                            assetVocabulary.getVocabularyId(),
1010                            importedAssetVocabulary.getVocabularyId());
1011    
1012                    portletDataContext.importPermissions(
1013                            AssetVocabulary.class, assetVocabulary.getVocabularyId(),
1014                            importedAssetVocabulary.getVocabularyId());
1015            }
1016    
1017            protected void importPortletData(
1018                            PortletDataContext portletDataContext, String portletId, long plid,
1019                            Element portletDataElement)
1020                    throws Exception {
1021    
1022                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
1023                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
1024    
1025                    PortletPreferences portletPreferences =
1026                            PortletPreferencesUtil.fetchByO_O_P_P(
1027                                    ownerId, ownerType, plid, portletId);
1028    
1029                    if (portletPreferences == null) {
1030                            portletPreferences =
1031                                    new com.liferay.portal.model.impl.PortletPreferencesImpl();
1032                    }
1033    
1034                    String xml = importPortletData(
1035                            portletDataContext, portletId, portletPreferences,
1036                            portletDataElement);
1037    
1038                    if (Validator.isNotNull(xml)) {
1039                            PortletPreferencesLocalServiceUtil.updatePreferences(
1040                                    ownerId, ownerType, plid, portletId, xml);
1041                    }
1042            }
1043    
1044            protected void importPortletPreferences(
1045                            PortletDataContext portletDataContext, long companyId, long groupId,
1046                            Layout layout, String portletId, Element parentElement,
1047                            boolean preserveScopeLayoutId, boolean importPortletArchivedSetups,
1048                            boolean importPortletData, boolean importPortletSetup,
1049                            boolean importPortletUserPreferences)
1050                    throws Exception {
1051    
1052                    if (portletId == null) {
1053                            portletId = parentElement.attributeValue("portlet-id");
1054                    }
1055    
1056                    long plid = LayoutConstants.DEFAULT_PLID;
1057                    String scopeType = StringPool.BLANK;
1058                    String scopeLayoutUuid = StringPool.BLANK;
1059    
1060                    if (layout != null) {
1061                            plid = layout.getPlid();
1062    
1063                            if (preserveScopeLayoutId && (portletId != null)) {
1064                                    javax.portlet.PortletPreferences jxPortletPreferences =
1065                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
1066                                                    layout, portletId);
1067    
1068                                    scopeType = GetterUtil.getString(
1069                                            jxPortletPreferences.getValue("lfrScopeType", null));
1070                                    scopeLayoutUuid = GetterUtil.getString(
1071                                            jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
1072    
1073                                    portletDataContext.setScopeType(scopeType);
1074                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1075                            }
1076                    }
1077    
1078                    List<Element> portletPreferencesElements = parentElement.elements(
1079                            "portlet-preferences");
1080    
1081                    for (Element portletPreferencesElement : portletPreferencesElements) {
1082                            String path = portletPreferencesElement.attributeValue("path");
1083    
1084                            if (portletDataContext.isPathNotProcessed(path)) {
1085                                    String xml = null;
1086    
1087                                    Element element = null;
1088    
1089                                    try {
1090                                            xml = portletDataContext.getZipEntryAsString(path);
1091    
1092                                            Document preferencesDocument = SAXReaderUtil.read(xml);
1093    
1094                                            element = preferencesDocument.getRootElement();
1095                                    }
1096                                    catch (DocumentException de) {
1097                                            throw new SystemException(de);
1098                                    }
1099    
1100                                    long ownerId = GetterUtil.getLong(
1101                                            element.attributeValue("owner-id"));
1102                                    int ownerType = GetterUtil.getInteger(
1103                                            element.attributeValue("owner-type"));
1104    
1105                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
1106                                            !importPortletSetup) {
1107    
1108                                            continue;
1109                                    }
1110    
1111                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
1112                                            !importPortletArchivedSetups) {
1113    
1114                                            continue;
1115                                    }
1116    
1117                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
1118                                            (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
1119                                            !importPortletUserPreferences) {
1120    
1121                                            continue;
1122                                    }
1123    
1124                                    long curPlid = plid;
1125                                    String curPortletId = portletId;
1126    
1127                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1128                                            curPlid = PortletKeys.PREFS_PLID_SHARED;
1129                                            curPortletId = PortletConstants.getRootPortletId(portletId);
1130                                            ownerId = portletDataContext.getScopeGroupId();
1131                                    }
1132    
1133                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1134                                            String userUuid = element.attributeValue(
1135                                                    "archive-user-uuid");
1136    
1137                                            long userId = portletDataContext.getUserId(userUuid);
1138    
1139                                            String name = element.attributeValue("archive-name");
1140    
1141                                            curPortletId = PortletConstants.getRootPortletId(portletId);
1142    
1143                                            PortletItem portletItem =
1144                                                    PortletItemLocalServiceUtil.updatePortletItem(
1145                                                            userId, groupId, name, curPortletId,
1146                                                            PortletPreferences.class.getName());
1147    
1148                                            curPlid = LayoutConstants.DEFAULT_PLID;
1149                                            ownerId = portletItem.getPortletItemId();
1150                                    }
1151    
1152                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1153                                            String userUuid = element.attributeValue("user-uuid");
1154    
1155                                            ownerId = portletDataContext.getUserId(userUuid);
1156                                    }
1157    
1158                                    boolean defaultUser = GetterUtil.getBoolean(
1159                                            element.attributeValue("default-user"));
1160    
1161                                    if (defaultUser) {
1162                                            ownerId = UserLocalServiceUtil.getDefaultUserId(companyId);
1163                                    }
1164    
1165                                    javax.portlet.PortletPreferences jxPortletPreferences =
1166                                            PortletPreferencesFactoryUtil.fromXML(
1167                                                    companyId, ownerId, ownerType, curPlid, curPortletId,
1168                                                    xml);
1169    
1170                                    Element importDataRootElement =
1171                                            portletDataContext.getImportDataRootElement();
1172    
1173                                    try {
1174                                            Element preferenceDataElement =
1175                                                    portletPreferencesElement.element("preference-data");
1176    
1177                                            if (preferenceDataElement != null) {
1178                                                    portletDataContext.setImportDataRootElement(
1179                                                            preferenceDataElement);
1180                                            }
1181    
1182                                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1183                                                    portletDataContext.getCompanyId(), curPortletId);
1184    
1185                                            PortletDataHandler portletDataHandler =
1186                                                    portlet.getPortletDataHandlerInstance();
1187    
1188                                            jxPortletPreferences =
1189                                                    portletDataHandler.processImportPortletPreferences(
1190                                                            portletDataContext, curPortletId,
1191                                                            jxPortletPreferences);
1192                                    }
1193                                    finally {
1194                                            portletDataContext.setImportDataRootElement(
1195                                                    importDataRootElement);
1196                                    }
1197    
1198                                    updatePortletPreferences(
1199                                            portletDataContext, ownerId, ownerType, curPlid,
1200                                            curPortletId,
1201                                            PortletPreferencesFactoryUtil.toXML(jxPortletPreferences),
1202                                            importPortletData);
1203                            }
1204                    }
1205    
1206                    if (preserveScopeLayoutId && (layout != null)) {
1207                            javax.portlet.PortletPreferences jxPortletPreferences =
1208                                    PortletPreferencesFactoryUtil.getLayoutPortletSetup(
1209                                            layout, portletId);
1210    
1211                            try {
1212                                    jxPortletPreferences.setValue("lfrScopeType", scopeType);
1213                                    jxPortletPreferences.setValue(
1214                                            "lfrScopeLayoutUuid", scopeLayoutUuid);
1215    
1216                                    jxPortletPreferences.store();
1217                            }
1218                            finally {
1219                                    portletDataContext.setScopeType(scopeType);
1220                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1221                            }
1222                    }
1223            }
1224    
1225            protected void readAssetCategories(PortletDataContext portletDataContext)
1226                    throws Exception {
1227    
1228                    String xml = portletDataContext.getZipEntryAsString(
1229                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1230                                    "/categories-hierarchy.xml");
1231    
1232                    if (xml == null) {
1233                            return;
1234                    }
1235    
1236                    Document document = SAXReaderUtil.read(xml);
1237    
1238                    Element rootElement = document.getRootElement();
1239    
1240                    Element assetVocabulariesElement = rootElement.element("vocabularies");
1241    
1242                    List<Element> assetVocabularyElements =
1243                            assetVocabulariesElement.elements("vocabulary");
1244    
1245                    Map<Long, Long> assetVocabularyPKs =
1246                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1247                                    AssetVocabulary.class);
1248    
1249                    for (Element assetVocabularyElement : assetVocabularyElements) {
1250                            String path = assetVocabularyElement.attributeValue("path");
1251    
1252                            if (!portletDataContext.isPathNotProcessed(path)) {
1253                                    continue;
1254                            }
1255    
1256                            AssetVocabulary assetVocabulary =
1257                                    (AssetVocabulary)portletDataContext.getZipEntryAsObject(path);
1258    
1259                            importAssetVocabulary(
1260                                    portletDataContext, assetVocabularyPKs, assetVocabularyElement,
1261                                    assetVocabulary);
1262                    }
1263    
1264                    Element assetCategoriesElement = rootElement.element("categories");
1265    
1266                    List<Element> assetCategoryElements = assetCategoriesElement.elements(
1267                            "category");
1268    
1269                    Map<Long, Long> assetCategoryPKs =
1270                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1271                                    AssetCategory.class);
1272    
1273                    Map<String, String> assetCategoryUuids =
1274                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1275                                    AssetCategory.class + ".uuid");
1276    
1277                    for (Element assetCategoryElement : assetCategoryElements) {
1278                            String path = assetCategoryElement.attributeValue("path");
1279    
1280                            if (!portletDataContext.isPathNotProcessed(path)) {
1281                                    continue;
1282                            }
1283    
1284                            AssetCategory assetCategory =
1285                                    (AssetCategory)portletDataContext.getZipEntryAsObject(path);
1286    
1287                            importAssetCategory(
1288                                    portletDataContext, assetVocabularyPKs, assetCategoryPKs,
1289                                    assetCategoryUuids, assetCategoryElement, assetCategory);
1290                    }
1291    
1292                    Element assetsElement = rootElement.element("assets");
1293    
1294                    List<Element> assetElements = assetsElement.elements("asset");
1295    
1296                    for (Element assetElement : assetElements) {
1297                            String className = GetterUtil.getString(
1298                                    assetElement.attributeValue("class-name"));
1299                            long classPK = GetterUtil.getLong(
1300                                    assetElement.attributeValue("class-pk"));
1301                            String[] assetCategoryUuidArray = StringUtil.split(
1302                                    GetterUtil.getString(
1303                                            assetElement.attributeValue("category-uuids")));
1304    
1305                            long[] assetCategoryIds = new long[0];
1306    
1307                            for (String assetCategoryUuid : assetCategoryUuidArray) {
1308                                    assetCategoryUuid = MapUtil.getString(
1309                                            assetCategoryUuids, assetCategoryUuid, assetCategoryUuid);
1310    
1311                                    AssetCategory assetCategory = AssetCategoryUtil.fetchByUUID_G(
1312                                            assetCategoryUuid, portletDataContext.getScopeGroupId());
1313    
1314                                    if (assetCategory == null) {
1315                                            Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1316                                                    portletDataContext.getCompanyId());
1317    
1318                                            assetCategory = AssetCategoryUtil.fetchByUUID_G(
1319                                                    assetCategoryUuid, companyGroup.getGroupId());
1320                                    }
1321    
1322                                    if (assetCategory != null) {
1323                                            assetCategoryIds = ArrayUtil.append(
1324                                                    assetCategoryIds, assetCategory.getCategoryId());
1325                                    }
1326                            }
1327    
1328                            portletDataContext.addAssetCategories(
1329                                    className, classPK, assetCategoryIds);
1330                    }
1331            }
1332    
1333            protected void readAssetLinks(PortletDataContext portletDataContext)
1334                    throws Exception {
1335    
1336                    String xml = portletDataContext.getZipEntryAsString(
1337                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1338                                    "/links.xml");
1339    
1340                    if (xml == null) {
1341                            return;
1342                    }
1343    
1344                    Document document = SAXReaderUtil.read(xml);
1345    
1346                    Element rootElement = document.getRootElement();
1347    
1348                    List<Element> assetLinkGroupElements = rootElement.elements(
1349                            "asset-link-group");
1350    
1351                    for (Element assetLinkGroupElement : assetLinkGroupElements) {
1352                            String sourceUuid = assetLinkGroupElement.attributeValue(
1353                                    "source-uuid");
1354    
1355                            AssetEntry sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1356                                    portletDataContext.getScopeGroupId(), sourceUuid);
1357    
1358                            if (sourceAssetEntry == null) {
1359                                    sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1360                                            portletDataContext.getCompanyGroupId(), sourceUuid);
1361                            }
1362    
1363                            if (sourceAssetEntry == null) {
1364                                    if (_log.isWarnEnabled()) {
1365                                            _log.warn(
1366                                                    "Unable to find asset entry with uuid " + sourceUuid);
1367                                    }
1368    
1369                                    continue;
1370                            }
1371    
1372                            List<Element> assetLinksElements = assetLinkGroupElement.elements(
1373                                    "asset-link");
1374    
1375                            for (Element assetLinkElement : assetLinksElements) {
1376                                    String path = assetLinkElement.attributeValue("path");
1377    
1378                                    if (!portletDataContext.isPathNotProcessed(path)) {
1379                                            continue;
1380                                    }
1381    
1382                                    String targetUuid = assetLinkElement.attributeValue(
1383                                            "target-uuid");
1384    
1385                                    AssetEntry targetAssetEntry =
1386                                            AssetEntryLocalServiceUtil.fetchEntry(
1387                                                    portletDataContext.getScopeGroupId(), targetUuid);
1388    
1389                                    if (targetAssetEntry == null) {
1390                                            targetAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1391                                                    portletDataContext.getCompanyGroupId(), targetUuid);
1392                                    }
1393    
1394                                    if (targetAssetEntry == null) {
1395                                            if (_log.isWarnEnabled()) {
1396                                                    _log.warn(
1397                                                            "Unable to find asset entry with uuid " +
1398                                                                    targetUuid);
1399                                            }
1400    
1401                                            continue;
1402                                    }
1403    
1404                                    AssetLink assetLink =
1405                                            (AssetLink)portletDataContext.getZipEntryAsObject(path);
1406    
1407                                    long userId = portletDataContext.getUserId(
1408                                            assetLink.getUserUuid());
1409    
1410                                    AssetLinkLocalServiceUtil.updateLink(
1411                                            userId, sourceAssetEntry.getEntryId(),
1412                                            targetAssetEntry.getEntryId(), assetLink.getType(),
1413                                            assetLink.getWeight());
1414                            }
1415                    }
1416            }
1417    
1418            protected void readAssetTags(PortletDataContext portletDataContext)
1419                    throws Exception {
1420    
1421                    String xml = portletDataContext.getZipEntryAsString(
1422                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1423                                    "/tags.xml");
1424    
1425                    if (xml == null) {
1426                            return;
1427                    }
1428    
1429                    Document document = SAXReaderUtil.read(xml);
1430    
1431                    Element rootElement = document.getRootElement();
1432    
1433                    List<Element> assetTagElements = rootElement.elements("tag");
1434    
1435                    for (Element assetTagElement : assetTagElements) {
1436                            String path = assetTagElement.attributeValue("path");
1437    
1438                            if (!portletDataContext.isPathNotProcessed(path)) {
1439                                    continue;
1440                            }
1441    
1442                            AssetTag assetTag =
1443                                    (AssetTag)portletDataContext.getZipEntryAsObject(path);
1444    
1445                            Map<Long, Long> assetTagPKs =
1446                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1447                                            AssetTag.class);
1448    
1449                            importAssetTag(
1450                                    portletDataContext, assetTagPKs, assetTagElement, assetTag);
1451                    }
1452    
1453                    List<Element> assetElements = rootElement.elements("asset");
1454    
1455                    for (Element assetElement : assetElements) {
1456                            String className = GetterUtil.getString(
1457                                    assetElement.attributeValue("class-name"));
1458                            long classPK = GetterUtil.getLong(
1459                                    assetElement.attributeValue("class-pk"));
1460                            String assetTagNames = GetterUtil.getString(
1461                                    assetElement.attributeValue("tags"));
1462    
1463                            portletDataContext.addAssetTags(
1464                                    className, classPK, StringUtil.split(assetTagNames));
1465                    }
1466            }
1467    
1468            protected void readComments(PortletDataContext portletDataContext)
1469                    throws Exception {
1470    
1471                    String xml = portletDataContext.getZipEntryAsString(
1472                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1473                                    "/comments.xml");
1474    
1475                    if (xml == null) {
1476                            return;
1477                    }
1478    
1479                    Document document = SAXReaderUtil.read(xml);
1480    
1481                    Element rootElement = document.getRootElement();
1482    
1483                    List<Element> assetElements = rootElement.elements("asset");
1484    
1485                    for (Element assetElement : assetElements) {
1486                            String path = assetElement.attributeValue("path");
1487                            String className = assetElement.attributeValue("class-name");
1488                            long classPK = GetterUtil.getLong(
1489                                    assetElement.attributeValue("class-pk"));
1490    
1491                            List<String> zipFolderEntries =
1492                                    portletDataContext.getZipFolderEntries(path);
1493    
1494                            List<MBMessage> mbMessages = new ArrayList<MBMessage>();
1495    
1496                            for (String zipFolderEntry : zipFolderEntries) {
1497                                    MBMessage mbMessage =
1498                                            (MBMessage)portletDataContext.getZipEntryAsObject(
1499                                                    zipFolderEntry);
1500    
1501                                    if (mbMessage != null) {
1502                                            mbMessages.add(mbMessage);
1503                                    }
1504                            }
1505    
1506                            portletDataContext.addComments(className, classPK, mbMessages);
1507                    }
1508            }
1509    
1510            protected void readExpandoTables(PortletDataContext portletDataContext)
1511                    throws Exception {
1512    
1513                    String xml = portletDataContext.getZipEntryAsString(
1514                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1515                                    "/expando-tables.xml");
1516    
1517                    if (xml == null) {
1518                            return;
1519                    }
1520    
1521                    Document document = SAXReaderUtil.read(xml);
1522    
1523                    Element rootElement = document.getRootElement();
1524    
1525                    List<Element> expandoTableElements = rootElement.elements(
1526                            "expando-table");
1527    
1528                    for (Element expandoTableElement : expandoTableElements) {
1529                            String className = expandoTableElement.attributeValue("class-name");
1530    
1531                            ExpandoTable expandoTable = null;
1532    
1533                            try {
1534                                    expandoTable = ExpandoTableLocalServiceUtil.getDefaultTable(
1535                                            portletDataContext.getCompanyId(), className);
1536                            }
1537                            catch (NoSuchTableException nste) {
1538                                    expandoTable = ExpandoTableLocalServiceUtil.addDefaultTable(
1539                                            portletDataContext.getCompanyId(), className);
1540                            }
1541    
1542                            List<Element> expandoColumnElements = expandoTableElement.elements(
1543                                    "expando-column");
1544    
1545                            for (Element expandoColumnElement : expandoColumnElements) {
1546                                    long columnId = GetterUtil.getLong(
1547                                            expandoColumnElement.attributeValue("column-id"));
1548                                    String name = expandoColumnElement.attributeValue("name");
1549                                    int type = GetterUtil.getInteger(
1550                                            expandoColumnElement.attributeValue("type"));
1551                                    String defaultData = expandoColumnElement.elementText(
1552                                            "default-data");
1553                                    String typeSettings = expandoColumnElement.elementText(
1554                                            "type-settings");
1555    
1556                                    Serializable defaultDataObject =
1557                                            ExpandoConverterUtil.getAttributeFromString(
1558                                                    type, defaultData);
1559    
1560                                    ExpandoColumn expandoColumn =
1561                                            ExpandoColumnLocalServiceUtil.getColumn(
1562                                                    expandoTable.getTableId(), name);
1563    
1564                                    if (expandoColumn != null) {
1565                                            ExpandoColumnLocalServiceUtil.updateColumn(
1566                                                    expandoColumn.getColumnId(), name, type,
1567                                                    defaultDataObject);
1568                                    }
1569                                    else {
1570                                            expandoColumn = ExpandoColumnLocalServiceUtil.addColumn(
1571                                                    expandoTable.getTableId(), name, type,
1572                                                    defaultDataObject);
1573                                    }
1574    
1575                                    ExpandoColumnLocalServiceUtil.updateTypeSettings(
1576                                            expandoColumn.getColumnId(), typeSettings);
1577    
1578                                    portletDataContext.importPermissions(
1579                                            ExpandoColumn.class, columnId, expandoColumn.getColumnId());
1580                            }
1581                    }
1582            }
1583    
1584            protected void readLocks(PortletDataContext portletDataContext)
1585                    throws Exception {
1586    
1587                    String xml = portletDataContext.getZipEntryAsString(
1588                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1589                                    "/locks.xml");
1590    
1591                    if (xml == null) {
1592                            return;
1593                    }
1594    
1595                    Document document = SAXReaderUtil.read(xml);
1596    
1597                    Element rootElement = document.getRootElement();
1598    
1599                    List<Element> assetElements = rootElement.elements("asset");
1600    
1601                    for (Element assetElement : assetElements) {
1602                            String path = assetElement.attributeValue("path");
1603                            String className = assetElement.attributeValue("class-name");
1604                            String key = assetElement.attributeValue("key");
1605    
1606                            Lock lock = (Lock)portletDataContext.getZipEntryAsObject(path);
1607    
1608                            if (lock != null) {
1609                                    portletDataContext.addLocks(className, key, lock);
1610                            }
1611                    }
1612            }
1613    
1614            protected void readRatingsEntries(PortletDataContext portletDataContext)
1615                    throws Exception {
1616    
1617                    String xml = portletDataContext.getZipEntryAsString(
1618                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1619                                    "/ratings.xml");
1620    
1621                    if (xml == null) {
1622                            return;
1623                    }
1624    
1625                    Document document = SAXReaderUtil.read(xml);
1626    
1627                    Element rootElement = document.getRootElement();
1628    
1629                    List<Element> assetElements = rootElement.elements("asset");
1630    
1631                    for (Element assetElement : assetElements) {
1632                            String path = assetElement.attributeValue("path");
1633                            String className = assetElement.attributeValue("class-name");
1634                            long classPK = GetterUtil.getLong(
1635                                    assetElement.attributeValue("class-pk"));
1636    
1637                            List<String> zipFolderEntries =
1638                                    portletDataContext.getZipFolderEntries(path);
1639    
1640                            List<RatingsEntry> ratingsEntries = new ArrayList<RatingsEntry>();
1641    
1642                            for (String zipFolderEntry : zipFolderEntries) {
1643                                    RatingsEntry ratingsEntry =
1644                                            (RatingsEntry)portletDataContext.getZipEntryAsObject(
1645                                                    zipFolderEntry);
1646    
1647                                    if (ratingsEntry != null) {
1648                                            ratingsEntries.add(ratingsEntry);
1649                                    }
1650                            }
1651    
1652                            portletDataContext.addRatingsEntries(
1653                                    className, classPK, ratingsEntries);
1654                    }
1655            }
1656    
1657            protected void readXML(PortletDataContext portletDataContext)
1658                    throws Exception {
1659    
1660                    if ((_rootElement != null) && (_headerElement != null)) {
1661                            return;
1662                    }
1663    
1664                    String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
1665    
1666                    if (xml == null) {
1667                            throw new LARFileException("manifest.xml not found in the LAR");
1668                    }
1669    
1670                    try {
1671                            Document document = SAXReaderUtil.read(xml);
1672    
1673                            _rootElement = document.getRootElement();
1674    
1675                            portletDataContext.setImportDataRootElement(_rootElement);
1676                    }
1677                    catch (Exception e) {
1678                            throw new LARFileException(e);
1679                    }
1680    
1681                    _headerElement = _rootElement.element("header");
1682            }
1683    
1684            protected void resetPortletScope(
1685                    PortletDataContext portletDataContext, long groupId) {
1686    
1687                    portletDataContext.setScopeGroupId(groupId);
1688                    portletDataContext.setScopeLayoutUuid(StringPool.BLANK);
1689                    portletDataContext.setScopeType(StringPool.BLANK);
1690            }
1691    
1692            protected void updatePortletPreferences(
1693                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1694                            long plid, String portletId, String xml, boolean importData)
1695                    throws Exception {
1696    
1697                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1698                            portletDataContext.getCompanyId(), portletId);
1699    
1700                    if (portlet == null) {
1701                            if (_log.isDebugEnabled()) {
1702                                    _log.debug(
1703                                            "Do not update portlet preferences for " + portletId +
1704                                                    " because the portlet does not exist");
1705                            }
1706    
1707                            return;
1708                    }
1709    
1710                    PortletDataHandler portletDataHandler =
1711                            portlet.getPortletDataHandlerInstance();
1712    
1713                    if (importData || !MergeLayoutPrototypesThreadLocal.isInProgress()) {
1714                            PortletPreferencesLocalServiceUtil.updatePreferences(
1715                                    ownerId, ownerType, plid, portletId, xml);
1716    
1717                            return;
1718                    }
1719    
1720                    // Portlet preferences to be updated only when importing data
1721    
1722                    String[] dataPortletPreferences =
1723                            portletDataHandler.getDataPortletPreferences();
1724    
1725                    // Current portlet preferences
1726    
1727                    javax.portlet.PortletPreferences portletPreferences =
1728                            PortletPreferencesLocalServiceUtil.getPreferences(
1729                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1730                                    portletId);
1731    
1732                    // New portlet preferences
1733    
1734                    javax.portlet.PortletPreferences jxPortletPreferences =
1735                            PortletPreferencesFactoryUtil.fromXML(
1736                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1737                                    portletId, xml);
1738    
1739                    Enumeration<String> enu = jxPortletPreferences.getNames();
1740    
1741                    while (enu.hasMoreElements()) {
1742                            String name = enu.nextElement();
1743    
1744                            String scopeLayoutUuid = portletDataContext.getScopeLayoutUuid();
1745                            String scopeType = portletDataContext.getScopeType();
1746    
1747                            if (!ArrayUtil.contains(dataPortletPreferences, name) ||
1748                                    (Validator.isNull(scopeLayoutUuid) &&
1749                                     scopeType.equals("company"))) {
1750    
1751                                    String[] values = jxPortletPreferences.getValues(name, null);
1752    
1753                                    portletPreferences.setValues(name, values);
1754                            }
1755                    }
1756    
1757                    PortletPreferencesLocalServiceUtil.updatePreferences(
1758                            ownerId, ownerType, plid, portletId, portletPreferences);
1759            }
1760    
1761            protected void validateFile(
1762                            PortletDataContext portletDataContext, String portletId)
1763                    throws Exception {
1764    
1765                    // Build compatibility
1766    
1767                    readXML(portletDataContext);
1768    
1769                    int buildNumber = ReleaseInfo.getBuildNumber();
1770    
1771                    int importBuildNumber = GetterUtil.getInteger(
1772                            _headerElement.attributeValue("build-number"));
1773    
1774                    if (buildNumber != importBuildNumber) {
1775                            throw new LayoutImportException(
1776                                    "LAR build number " + importBuildNumber + " does not match " +
1777                                            "portal build number " + buildNumber);
1778                    }
1779    
1780                    // Type
1781    
1782                    String larType = _headerElement.attributeValue("type");
1783    
1784                    if (!larType.equals("portlet")) {
1785                            throw new LARTypeException(larType);
1786                    }
1787    
1788                    // Portlet compatibility
1789    
1790                    String rootPortletId = _headerElement.attributeValue("root-portlet-id");
1791    
1792                    if (!PortletConstants.getRootPortletId(portletId).equals(
1793                                    rootPortletId)) {
1794    
1795                            throw new PortletIdException("Invalid portlet id " + rootPortletId);
1796                    }
1797    
1798                    // Available locales
1799    
1800                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1801                            portletDataContext.getCompanyId(), portletId);
1802    
1803                    PortletDataHandler portletDataHandler =
1804                            portlet.getPortletDataHandlerInstance();
1805    
1806                    if (portletDataHandler.isDataLocalized()) {
1807                            Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1808                                    StringUtil.split(
1809                                            _headerElement.attributeValue("available-locales")));
1810    
1811                            Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1812                                    PortalUtil.getSiteGroupId(
1813                                            portletDataContext.getScopeGroupId()));
1814    
1815                            for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1816                                    if (!ArrayUtil.contains(
1817                                                    targetAvailableLocales, sourceAvailableLocale)) {
1818    
1819                                            LocaleException le = new LocaleException(
1820                                                    LocaleException.TYPE_EXPORT_IMPORT,
1821                                                    "Locale " + sourceAvailableLocale + " is not " +
1822                                                            "available in company " +
1823                                                                    portletDataContext.getCompanyId());
1824    
1825                                            le.setSourceAvailableLocales(sourceAvailableLocales);
1826                                            le.setTargetAvailableLocales(targetAvailableLocales);
1827    
1828                                            throw le;
1829                                    }
1830                            }
1831                    }
1832            }
1833    
1834            private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
1835    
1836            private DeletionSystemEventImporter _deletionSystemEventImporter =
1837                    new DeletionSystemEventImporter();
1838            private Element _headerElement;
1839            private PermissionImporter _permissionImporter = new PermissionImporter();
1840            private Element _rootElement;
1841    
1842    }