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