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