001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.LARFileException;
018    import com.liferay.portal.LARTypeException;
019    import com.liferay.portal.LayoutImportException;
020    import com.liferay.portal.LocaleException;
021    import com.liferay.portal.MissingReferenceException;
022    import com.liferay.portal.NoSuchPortletPreferencesException;
023    import com.liferay.portal.PortletIdException;
024    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.language.LanguageUtil;
028    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
029    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
030    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
031    import com.liferay.portal.kernel.lar.ManifestSummary;
032    import com.liferay.portal.kernel.lar.MissingReference;
033    import com.liferay.portal.kernel.lar.MissingReferences;
034    import com.liferay.portal.kernel.lar.PortletDataContext;
035    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
036    import com.liferay.portal.kernel.lar.PortletDataHandler;
037    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
038    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
039    import com.liferay.portal.kernel.lar.UserIdStrategy;
040    import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleConstants;
041    import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleManager;
042    import com.liferay.portal.kernel.log.Log;
043    import com.liferay.portal.kernel.log.LogFactoryUtil;
044    import com.liferay.portal.kernel.search.Indexer;
045    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
046    import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
047    import com.liferay.portal.kernel.util.ArrayUtil;
048    import com.liferay.portal.kernel.util.GetterUtil;
049    import com.liferay.portal.kernel.util.LocaleUtil;
050    import com.liferay.portal.kernel.util.MapUtil;
051    import com.liferay.portal.kernel.util.ReleaseInfo;
052    import com.liferay.portal.kernel.util.StringBundler;
053    import com.liferay.portal.kernel.util.StringPool;
054    import com.liferay.portal.kernel.util.StringUtil;
055    import com.liferay.portal.kernel.util.Validator;
056    import com.liferay.portal.kernel.xml.Attribute;
057    import com.liferay.portal.kernel.xml.Document;
058    import com.liferay.portal.kernel.xml.DocumentException;
059    import com.liferay.portal.kernel.xml.Element;
060    import com.liferay.portal.kernel.xml.SAXReaderUtil;
061    import com.liferay.portal.kernel.zip.ZipReader;
062    import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
063    import com.liferay.portal.model.Group;
064    import com.liferay.portal.model.Layout;
065    import com.liferay.portal.model.LayoutConstants;
066    import com.liferay.portal.model.Lock;
067    import com.liferay.portal.model.Portlet;
068    import com.liferay.portal.model.PortletConstants;
069    import com.liferay.portal.model.PortletItem;
070    import com.liferay.portal.model.PortletPreferences;
071    import com.liferay.portal.model.User;
072    import com.liferay.portal.security.permission.PermissionCacheUtil;
073    import com.liferay.portal.service.LayoutLocalServiceUtil;
074    import com.liferay.portal.service.PortletItemLocalServiceUtil;
075    import com.liferay.portal.service.PortletLocalServiceUtil;
076    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
077    import com.liferay.portal.service.ServiceContext;
078    import com.liferay.portal.service.ServiceContextThreadLocal;
079    import com.liferay.portal.service.UserLocalServiceUtil;
080    import com.liferay.portal.service.persistence.PortletPreferencesUtil;
081    import com.liferay.portal.servlet.filters.cache.CacheUtil;
082    import com.liferay.portal.util.PortalUtil;
083    import com.liferay.portal.util.PortletKeys;
084    import com.liferay.portlet.PortletPreferencesFactoryUtil;
085    import com.liferay.portlet.PortletPreferencesImpl;
086    import com.liferay.portlet.asset.NoSuchTagException;
087    import com.liferay.portlet.asset.model.AssetEntry;
088    import com.liferay.portlet.asset.model.AssetLink;
089    import com.liferay.portlet.asset.model.AssetTag;
090    import com.liferay.portlet.asset.model.AssetTagConstants;
091    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
092    import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
093    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
094    import com.liferay.portlet.asset.service.persistence.AssetTagUtil;
095    import com.liferay.portlet.expando.NoSuchTableException;
096    import com.liferay.portlet.expando.model.ExpandoColumn;
097    import com.liferay.portlet.expando.model.ExpandoTable;
098    import com.liferay.portlet.expando.service.ExpandoColumnLocalServiceUtil;
099    import com.liferay.portlet.expando.service.ExpandoTableLocalServiceUtil;
100    import com.liferay.portlet.expando.util.ExpandoConverterUtil;
101    import com.liferay.portlet.journal.util.JournalContentUtil;
102    
103    import java.io.File;
104    import java.io.Serializable;
105    
106    import java.util.Enumeration;
107    import java.util.List;
108    import java.util.Locale;
109    import java.util.Map;
110    
111    import org.apache.commons.lang.time.StopWatch;
112    
113    /**
114     * @author Brian Wing Shun Chan
115     * @author Joel Kozikowski
116     * @author Charles May
117     * @author Raymond Aug??
118     * @author Jorge Ferrer
119     * @author Bruno Farache
120     * @author Zsigmond Rab
121     * @author Douglas Wong
122     * @author Mate Thurzo
123     */
124    public class PortletImporter {
125    
126            public static PortletImporter getInstance() {
127                    return _instance;
128            }
129    
130            public String importPortletData(
131                            PortletDataContext portletDataContext,
132                            PortletPreferences portletPreferences, Element portletDataElement)
133                    throws Exception {
134    
135                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
136                            portletDataContext.getCompanyId(),
137                            portletDataContext.getPortletId());
138    
139                    if (portlet == null) {
140                            if (_log.isDebugEnabled()) {
141                                    _log.debug(
142                                            "Do not import portlet data for " +
143                                                    portletDataContext.getPortletId() +
144                                                            " because the portlet does not exist");
145                            }
146    
147                            return null;
148                    }
149    
150                    PortletDataHandler portletDataHandler =
151                            portlet.getPortletDataHandlerInstance();
152    
153                    if ((portletDataHandler == null) ||
154                            portletDataHandler.isDataPortletInstanceLevel()) {
155    
156                            if (_log.isDebugEnabled()) {
157                                    StringBundler sb = new StringBundler(4);
158    
159                                    sb.append("Do not import portlet data for ");
160                                    sb.append(portletDataContext.getPortletId());
161                                    sb.append(" because the portlet does not have a ");
162                                    sb.append("PortletDataHandler");
163    
164                                    _log.debug(sb.toString());
165                            }
166    
167                            return null;
168                    }
169    
170                    if (_log.isDebugEnabled()) {
171                            _log.debug(
172                                    "Importing data for " + portletDataContext.getPortletId());
173                    }
174    
175                    PortletPreferencesImpl portletPreferencesImpl = null;
176    
177                    if (portletPreferences != null) {
178                            portletPreferencesImpl =
179                                    (PortletPreferencesImpl)
180                                            PortletPreferencesFactoryUtil.fromDefaultXML(
181                                                    portletPreferences.getPreferences());
182                    }
183    
184                    String portletData = portletDataContext.getZipEntryAsString(
185                            portletDataElement.attributeValue("path"));
186    
187                    if (Validator.isNull(portletData)) {
188                            return null;
189                    }
190    
191                    portletPreferencesImpl =
192                            (PortletPreferencesImpl)portletDataHandler.importData(
193                                    portletDataContext, portletDataContext.getPortletId(),
194                                    portletPreferencesImpl, portletData);
195    
196                    if (portletPreferencesImpl == null) {
197                            return null;
198                    }
199    
200                    return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
201            }
202    
203            public void importPortletInfo(
204                            long userId, long plid, long groupId, String portletId,
205                            Map<String, String[]> parameterMap, File file)
206                    throws Exception {
207    
208                    PortletDataContext portletDataContext = null;
209    
210                    try {
211                            ExportImportThreadLocal.setPortletImportInProcess(true);
212    
213                            portletDataContext = getPortletDataContext(
214                                    userId, plid, groupId, portletId, parameterMap, file);
215    
216                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
217                                    ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_STARTED,
218                                    PortletDataContextFactoryUtil.clonePortletDataContext(
219                                            portletDataContext));
220    
221                            doImportPortletInfo(portletDataContext, userId);
222    
223                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
224                                    ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_SUCCEEDED,
225                                    PortletDataContextFactoryUtil.clonePortletDataContext(
226                                            portletDataContext));
227                    }
228                    catch (Throwable t) {
229                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
230                                    ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_FAILED,
231                                    PortletDataContextFactoryUtil.clonePortletDataContext(
232                                            portletDataContext),
233                                    t);
234    
235                            throw t;
236                    }
237                    finally {
238                            ExportImportThreadLocal.setPortletImportInProcess(false);
239    
240                            CacheUtil.clearCache();
241                            JournalContentUtil.clearCache();
242                            PermissionCacheUtil.clearCache();
243                    }
244            }
245    
246            public MissingReferences validateFile(
247                            long userId, long plid, long groupId, String portletId,
248                            Map<String, String[]> parameterMap, File file)
249                    throws Exception {
250    
251                    ZipReader zipReader = null;
252    
253                    try {
254                            ExportImportThreadLocal.setPortletValidationInProcess(true);
255    
256                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
257    
258                            zipReader = ZipReaderFactoryUtil.getZipReader(file);
259    
260                            validateFile(layout.getCompanyId(), groupId, portletId, zipReader);
261    
262                            PortletDataContext portletDataContext = getPortletDataContext(
263                                    userId, plid, groupId, portletId, parameterMap, file);
264    
265                            MissingReferences missingReferences =
266                                    ExportImportHelperUtil.validateMissingReferences(
267                                            portletDataContext);
268    
269                            Map<String, MissingReference> dependencyMissingReferences =
270                                    missingReferences.getDependencyMissingReferences();
271    
272                            if (!dependencyMissingReferences.isEmpty()) {
273                                    throw new MissingReferenceException(missingReferences);
274                            }
275    
276                            return missingReferences;
277                    }
278                    finally {
279                            ExportImportThreadLocal.setPortletValidationInProcess(false);
280    
281                            if (zipReader != null) {
282                                    zipReader.close();
283                            }
284                    }
285            }
286    
287            protected void deletePortletData(PortletDataContext portletDataContext)
288                    throws Exception {
289    
290                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
291                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
292    
293                    PortletPreferences portletPreferences =
294                            PortletPreferencesUtil.fetchByO_O_P_P(
295                                    ownerId, ownerType, portletDataContext.getPlid(),
296                                    portletDataContext.getPortletId());
297    
298                    if (portletPreferences == null) {
299                            portletPreferences =
300                                    new com.liferay.portal.model.impl.PortletPreferencesImpl();
301                    }
302    
303                    String xml = deletePortletData(portletDataContext, portletPreferences);
304    
305                    if (xml != null) {
306                            PortletPreferencesLocalServiceUtil.updatePreferences(
307                                    ownerId, ownerType, portletDataContext.getPlid(),
308                                    portletDataContext.getPortletId(), xml);
309                    }
310            }
311    
312            protected String deletePortletData(
313                            PortletDataContext portletDataContext,
314                            PortletPreferences portletPreferences)
315                    throws Exception {
316    
317                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
318                            portletDataContext.getCompanyId(),
319                            portletDataContext.getPortletId());
320    
321                    if (portlet == null) {
322                            if (_log.isDebugEnabled()) {
323                                    _log.debug(
324                                            "Do not delete portlet data for " +
325                                                    portletDataContext.getPortletId() +
326                                                            " because the portlet does not exist");
327                            }
328    
329                            return null;
330                    }
331    
332                    PortletDataHandler portletDataHandler =
333                            portlet.getPortletDataHandlerInstance();
334    
335                    if (portletDataHandler == null) {
336                            if (_log.isDebugEnabled()) {
337                                    StringBundler sb = new StringBundler(4);
338    
339                                    sb.append("Do not delete portlet data for ");
340                                    sb.append(portletDataContext.getPortletId());
341                                    sb.append(" because the portlet does not have a ");
342                                    sb.append("PortletDataHandler");
343    
344                                    _log.debug(sb.toString());
345                            }
346    
347                            return null;
348                    }
349    
350                    if (_log.isDebugEnabled()) {
351                            _log.debug(
352                                    "Deleting data for " + portletDataContext.getPortletId());
353                    }
354    
355                    PortletPreferencesImpl portletPreferencesImpl =
356                            (PortletPreferencesImpl)
357                                    PortletPreferencesFactoryUtil.fromDefaultXML(
358                                            portletPreferences.getPreferences());
359    
360                    try {
361                            portletPreferencesImpl =
362                                    (PortletPreferencesImpl)portletDataHandler.deleteData(
363                                            portletDataContext, portletDataContext.getPortletId(),
364                                            portletPreferencesImpl);
365                    }
366                    finally {
367                            portletDataContext.setGroupId(portletDataContext.getScopeGroupId());
368                    }
369    
370                    if (portletPreferencesImpl == null) {
371                            return null;
372                    }
373    
374                    return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
375            }
376    
377            protected void doImportPortletInfo(
378                            PortletDataContext portletDataContext, long userId)
379                    throws Exception {
380    
381                    Map<String, String[]> parameterMap =
382                            portletDataContext.getParameterMap();
383    
384                    boolean deletePortletData = MapUtil.getBoolean(
385                            parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
386                    boolean importPermissions = MapUtil.getBoolean(
387                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
388    
389                    StopWatch stopWatch = new StopWatch();
390    
391                    stopWatch.start();
392    
393                    ServiceContext serviceContext =
394                            ServiceContextThreadLocal.getServiceContext();
395    
396                    if (serviceContext == null) {
397                            serviceContext = new ServiceContext();
398    
399                            serviceContext.setCompanyId(portletDataContext.getCompanyId());
400                            serviceContext.setSignedIn(false);
401                            serviceContext.setUserId(userId);
402    
403                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
404                    }
405    
406                    // LAR validation
407    
408                    validateFile(
409                            portletDataContext.getCompanyId(), portletDataContext.getGroupId(),
410                            portletDataContext.getPortletId(),
411                            portletDataContext.getZipReader());
412    
413                    // Source and target group id
414    
415                    Map<Long, Long> groupIds =
416                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
417                                    Group.class);
418    
419                    groupIds.put(
420                            portletDataContext.getSourceGroupId(),
421                            portletDataContext.getGroupId());
422    
423                    // Manifest
424    
425                    ManifestSummary manifestSummary =
426                            ExportImportHelperUtil.getManifestSummary(portletDataContext);
427    
428                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
429                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
430                                    "portlet", portletDataContext.getPortletId(), manifestSummary);
431                    }
432    
433                    portletDataContext.setManifestSummary(manifestSummary);
434    
435                    // Read asset tags, expando tables, locks and permissions to make them
436                    // available to the data handlers through the portlet data context
437    
438                    Element rootElement = portletDataContext.getImportDataRootElement();
439    
440                    Element portletElement = null;
441    
442                    try {
443                            portletElement = rootElement.element("portlet");
444    
445                            Document portletDocument = SAXReaderUtil.read(
446                                    portletDataContext.getZipEntryAsString(
447                                            portletElement.attributeValue("path")));
448    
449                            portletElement = portletDocument.getRootElement();
450                    }
451                    catch (DocumentException de) {
452                            throw new SystemException(de);
453                    }
454    
455                    LayoutCache layoutCache = new LayoutCache();
456    
457                    if (importPermissions) {
458                            _permissionImporter.checkRoles(
459                                    layoutCache, portletDataContext.getCompanyId(),
460                                    portletDataContext.getGroupId(), userId, portletElement);
461    
462                            _permissionImporter.readPortletDataPermissions(portletDataContext);
463                    }
464    
465                    readAssetTags(portletDataContext);
466                    readExpandoTables(portletDataContext);
467                    readLocks(portletDataContext);
468    
469                    // Delete portlet data
470    
471                    if (_log.isDebugEnabled()) {
472                            _log.debug("Deleting portlet data");
473                    }
474    
475                    if (deletePortletData) {
476                            deletePortletData(portletDataContext);
477                    }
478    
479                    Element portletDataElement = portletElement.element("portlet-data");
480    
481                    Map<String, Boolean> importPortletControlsMap =
482                            ExportImportHelperUtil.getImportPortletControlsMap(
483                                    portletDataContext.getCompanyId(),
484                                    portletDataContext.getPortletId(), parameterMap,
485                                    portletDataElement, manifestSummary);
486    
487                    Layout layout = LayoutLocalServiceUtil.getLayout(
488                            portletDataContext.getPlid());
489    
490                    try {
491    
492                            // Portlet preferences
493    
494                            importPortletPreferences(
495                                    portletDataContext, layout.getCompanyId(),
496                                    portletDataContext.getGroupId(), layout, portletElement, true,
497                                    importPortletControlsMap.get(
498                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
499                                    importPortletControlsMap.get(
500                                            PortletDataHandlerKeys.PORTLET_DATA),
501                                    importPortletControlsMap.get(
502                                            PortletDataHandlerKeys.PORTLET_SETUP),
503                                    importPortletControlsMap.get(
504                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
505    
506                            // Portlet data
507    
508                            if (importPortletControlsMap.get(
509                                            PortletDataHandlerKeys.PORTLET_DATA)) {
510    
511                                    if (_log.isDebugEnabled()) {
512                                            _log.debug("Importing portlet data");
513                                    }
514    
515                                    importPortletData(portletDataContext, portletDataElement);
516                            }
517                    }
518                    finally {
519                            resetPortletScope(
520                                    portletDataContext, portletDataContext.getGroupId());
521                    }
522    
523                    // Portlet permissions
524    
525                    if (importPermissions) {
526                            if (_log.isDebugEnabled()) {
527                                    _log.debug("Importing portlet permissions");
528                            }
529    
530                            _permissionImporter.importPortletPermissions(
531                                    layoutCache, portletDataContext.getCompanyId(),
532                                    portletDataContext.getGroupId(), userId, layout, portletElement,
533                                    portletDataContext.getPortletId());
534    
535                            if (userId > 0) {
536                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
537                                            User.class);
538    
539                                    indexer.reindex(userId);
540                            }
541                    }
542    
543                    // Asset links
544    
545                    if (_log.isDebugEnabled()) {
546                            _log.debug("Importing asset links");
547                    }
548    
549                    readAssetLinks(portletDataContext);
550    
551                    // Deletion system events
552    
553                    _deletionSystemEventImporter.importDeletionSystemEvents(
554                            portletDataContext);
555    
556                    if (_log.isInfoEnabled()) {
557                            _log.info("Importing portlet takes " + stopWatch.getTime() + " ms");
558                    }
559    
560                    // Service portlet preferences
561    
562                    boolean importPortletSetup = importPortletControlsMap.get(
563                            PortletDataHandlerKeys.PORTLET_SETUP);
564    
565                    if (importPortletSetup) {
566                            try {
567                                    List<Element> serviceElements = rootElement.elements("service");
568    
569                                    for (Element serviceElement : serviceElements) {
570                                            Document serviceDocument = SAXReaderUtil.read(
571                                                    portletDataContext.getZipEntryAsString(
572                                                            serviceElement.attributeValue("path")));
573    
574                                            importServicePortletPreferences(
575                                                    portletDataContext, serviceDocument.getRootElement());
576                                    }
577                            }
578                            catch (DocumentException de) {
579                                    throw new SystemException(de);
580                            }
581                    }
582    
583                    ZipReader zipReader = portletDataContext.getZipReader();
584    
585                    zipReader.close();
586            }
587    
588            protected PortletDataContext getPortletDataContext(
589                            long userId, long plid, long groupId, String portletId,
590                            Map<String, String[]> parameterMap, File file)
591                    throws PortalException {
592    
593                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
594    
595                    String userIdStrategyString = MapUtil.getString(
596                            parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
597    
598                    UserIdStrategy userIdStrategy =
599                            ExportImportHelperUtil.getUserIdStrategy(
600                                    userId, userIdStrategyString);
601    
602                    ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
603    
604                    PortletDataContext portletDataContext =
605                            PortletDataContextFactoryUtil.createImportPortletDataContext(
606                                    layout.getCompanyId(), groupId, parameterMap, userIdStrategy,
607                                    zipReader);
608    
609                    portletDataContext.setOldPlid(plid);
610                    portletDataContext.setPlid(plid);
611                    portletDataContext.setPortletId(portletId);
612                    portletDataContext.setPrivateLayout(layout.isPrivateLayout());
613    
614                    return portletDataContext;
615            }
616    
617            protected PortletPreferences getPortletPreferences(
618                            long companyId, long ownerId, int ownerType, long plid,
619                            String serviceName)
620                    throws PortalException {
621    
622                    PortletPreferences portletPreferences = null;
623    
624                    try {
625                            if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) ||
626                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
627                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP)) {
628    
629                                    portletPreferences =
630                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
631                                                    ownerId, ownerType, LayoutConstants.DEFAULT_PLID,
632                                                    serviceName);
633                            }
634                            else {
635                                    portletPreferences =
636                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
637                                                    ownerId, ownerType, plid, serviceName);
638                            }
639                    }
640                    catch (NoSuchPortletPreferencesException nsppe) {
641                            portletPreferences =
642                                    PortletPreferencesLocalServiceUtil.addPortletPreferences(
643                                            companyId, ownerId, ownerType, plid, serviceName, null,
644                                            null);
645                    }
646    
647                    return portletPreferences;
648            }
649    
650            protected void importAssetTag(
651                            PortletDataContext portletDataContext, Map<Long, Long> assetTagPKs,
652                            Element assetTagElement, AssetTag assetTag)
653                    throws PortalException {
654    
655                    long userId = portletDataContext.getUserId(assetTag.getUserUuid());
656    
657                    ServiceContext serviceContext = new ServiceContext();
658    
659                    serviceContext.setAddGroupPermissions(true);
660                    serviceContext.setAddGuestPermissions(true);
661                    serviceContext.setCreateDate(assetTag.getCreateDate());
662                    serviceContext.setModifiedDate(assetTag.getModifiedDate());
663                    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
664    
665                    AssetTag importedAssetTag = null;
666    
667                    List<Element> propertyElements = assetTagElement.elements("property");
668    
669                    String[] properties = new String[propertyElements.size()];
670    
671                    for (int i = 0; i < propertyElements.size(); i++) {
672                            Element propertyElement = propertyElements.get(i);
673    
674                            String key = propertyElement.attributeValue("key");
675                            String value = propertyElement.attributeValue("value");
676    
677                            properties[i] = key.concat(
678                                    AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR).concat(value);
679                    }
680    
681                    AssetTag existingAssetTag = null;
682    
683                    try {
684                            existingAssetTag = AssetTagUtil.findByG_N(
685                                    portletDataContext.getScopeGroupId(), assetTag.getName());
686                    }
687                    catch (NoSuchTagException nste) {
688                            if (_log.isDebugEnabled()) {
689                                    StringBundler sb = new StringBundler(5);
690    
691                                    sb.append("No AssetTag exists with the key {groupId=");
692                                    sb.append(portletDataContext.getScopeGroupId());
693                                    sb.append(", name=");
694                                    sb.append(assetTag.getName());
695                                    sb.append("}");
696    
697                                    _log.debug(sb.toString());
698                            }
699                    }
700    
701                    try {
702                            if (existingAssetTag == null) {
703                                    importedAssetTag = AssetTagLocalServiceUtil.addTag(
704                                            userId, assetTag.getName(), properties, serviceContext);
705                            }
706                            else {
707                                    importedAssetTag = AssetTagLocalServiceUtil.updateTag(
708                                            userId, existingAssetTag.getTagId(), assetTag.getName(),
709                                            properties, serviceContext);
710                            }
711    
712                            assetTagPKs.put(assetTag.getTagId(), importedAssetTag.getTagId());
713    
714                            portletDataContext.importPermissions(
715                                    AssetTag.class, assetTag.getTagId(),
716                                    importedAssetTag.getTagId());
717                    }
718                    catch (NoSuchTagException nste) {
719                            _log.error(
720                                    "Could not find the parent category for category " +
721                                            assetTag.getTagId());
722                    }
723            }
724    
725            protected void importPortletData(
726                            PortletDataContext portletDataContext, Element portletDataElement)
727                    throws Exception {
728    
729                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
730                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
731    
732                    PortletPreferences portletPreferences =
733                            PortletPreferencesUtil.fetchByO_O_P_P(
734                                    ownerId, ownerType, portletDataContext.getPlid(),
735                                    portletDataContext.getPortletId());
736    
737                    if (portletPreferences == null) {
738                            portletPreferences =
739                                    new com.liferay.portal.model.impl.PortletPreferencesImpl();
740                    }
741    
742                    String xml = importPortletData(
743                            portletDataContext, portletPreferences, portletDataElement);
744    
745                    if (Validator.isNotNull(xml)) {
746                            PortletPreferencesLocalServiceUtil.updatePreferences(
747                                    ownerId, ownerType, portletDataContext.getPlid(),
748                                    portletDataContext.getPortletId(), xml);
749                    }
750            }
751    
752            protected void importPortletPreferences(
753                            PortletDataContext portletDataContext, long companyId, long groupId,
754                            Layout layout, Element parentElement, boolean preserveScopeLayoutId,
755                            boolean importPortletArchivedSetups, boolean importPortletData,
756                            boolean importPortletSetup, boolean importPortletUserPreferences)
757                    throws Exception {
758    
759                    long plid = LayoutConstants.DEFAULT_PLID;
760                    String scopeType = StringPool.BLANK;
761                    String scopeLayoutUuid = StringPool.BLANK;
762    
763                    if (layout != null) {
764                            plid = layout.getPlid();
765    
766                            if (preserveScopeLayoutId) {
767                                    javax.portlet.PortletPreferences jxPortletPreferences =
768                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
769                                                    layout, portletDataContext.getPortletId());
770    
771                                    scopeType = GetterUtil.getString(
772                                            jxPortletPreferences.getValue("lfrScopeType", null));
773                                    scopeLayoutUuid = GetterUtil.getString(
774                                            jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
775    
776                                    portletDataContext.setScopeType(scopeType);
777                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
778                            }
779                    }
780    
781                    List<Element> portletPreferencesElements = parentElement.elements(
782                            "portlet-preferences");
783    
784                    for (Element portletPreferencesElement : portletPreferencesElements) {
785                            String path = portletPreferencesElement.attributeValue("path");
786    
787                            if (portletDataContext.isPathNotProcessed(path)) {
788                                    String xml = null;
789    
790                                    Element element = null;
791    
792                                    try {
793                                            xml = portletDataContext.getZipEntryAsString(path);
794    
795                                            Document preferencesDocument = SAXReaderUtil.read(xml);
796    
797                                            element = preferencesDocument.getRootElement();
798                                    }
799                                    catch (DocumentException de) {
800                                            throw new SystemException(de);
801                                    }
802    
803                                    long ownerId = GetterUtil.getLong(
804                                            element.attributeValue("owner-id"));
805                                    int ownerType = GetterUtil.getInteger(
806                                            element.attributeValue("owner-type"));
807    
808                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
809                                            !importPortletSetup) {
810    
811                                            continue;
812                                    }
813    
814                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
815                                            !importPortletArchivedSetups) {
816    
817                                            continue;
818                                    }
819    
820                                    if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
821                                            (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
822                                            !importPortletUserPreferences) {
823    
824                                            continue;
825                                    }
826    
827                                    long curPlid = plid;
828                                    String curPortletId = portletDataContext.getPortletId();
829    
830                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
831                                            curPlid = PortletKeys.PREFS_PLID_SHARED;
832                                            curPortletId = portletDataContext.getRootPortletId();
833                                            ownerId = portletDataContext.getScopeGroupId();
834                                    }
835    
836                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
837                                            String userUuid = element.attributeValue(
838                                                    "archive-user-uuid");
839    
840                                            long userId = portletDataContext.getUserId(userUuid);
841    
842                                            String name = element.attributeValue("archive-name");
843    
844                                            curPortletId = portletDataContext.getRootPortletId();
845    
846                                            PortletItem portletItem =
847                                                    PortletItemLocalServiceUtil.updatePortletItem(
848                                                            userId, groupId, name, curPortletId,
849                                                            PortletPreferences.class.getName());
850    
851                                            curPlid = LayoutConstants.DEFAULT_PLID;
852                                            ownerId = portletItem.getPortletItemId();
853                                    }
854    
855                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
856                                            String userUuid = element.attributeValue("user-uuid");
857    
858                                            ownerId = portletDataContext.getUserId(userUuid);
859                                    }
860    
861                                    boolean defaultUser = GetterUtil.getBoolean(
862                                            element.attributeValue("default-user"));
863    
864                                    if (defaultUser) {
865                                            ownerId = UserLocalServiceUtil.getDefaultUserId(companyId);
866                                    }
867    
868                                    javax.portlet.PortletPreferences jxPortletPreferences =
869                                            PortletPreferencesFactoryUtil.fromXML(
870                                                    companyId, ownerId, ownerType, curPlid, curPortletId,
871                                                    xml);
872    
873                                    Element importDataRootElement =
874                                            portletDataContext.getImportDataRootElement();
875    
876                                    try {
877                                            Element preferenceDataElement =
878                                                    portletPreferencesElement.element("preference-data");
879    
880                                            if (preferenceDataElement != null) {
881                                                    portletDataContext.setImportDataRootElement(
882                                                            preferenceDataElement);
883                                            }
884    
885                                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
886                                                    portletDataContext.getCompanyId(), curPortletId);
887    
888                                            PortletDataHandler portletDataHandler =
889                                                    portlet.getPortletDataHandlerInstance();
890    
891                                            jxPortletPreferences =
892                                                    portletDataHandler.processImportPortletPreferences(
893                                                            portletDataContext, curPortletId,
894                                                            jxPortletPreferences);
895                                    }
896                                    finally {
897                                            portletDataContext.setImportDataRootElement(
898                                                    importDataRootElement);
899                                    }
900    
901                                    updatePortletPreferences(
902                                            portletDataContext, ownerId, ownerType, curPlid,
903                                            curPortletId,
904                                            PortletPreferencesFactoryUtil.toXML(jxPortletPreferences),
905                                            importPortletData);
906                            }
907                    }
908    
909                    if (preserveScopeLayoutId && (layout != null)) {
910                            javax.portlet.PortletPreferences jxPortletPreferences =
911                                    PortletPreferencesFactoryUtil.getLayoutPortletSetup(
912                                            layout, portletDataContext.getPortletId());
913    
914                            try {
915                                    jxPortletPreferences.setValue("lfrScopeType", scopeType);
916                                    jxPortletPreferences.setValue(
917                                            "lfrScopeLayoutUuid", scopeLayoutUuid);
918    
919                                    jxPortletPreferences.store();
920                            }
921                            finally {
922                                    portletDataContext.setScopeType(scopeType);
923                                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
924                            }
925                    }
926            }
927    
928            protected void importServicePortletPreferences(
929                            PortletDataContext portletDataContext, Element serviceElement)
930                    throws PortalException {
931    
932                    long ownerId = GetterUtil.getLong(
933                            serviceElement.attributeValue("owner-id"));
934                    int ownerType = GetterUtil.getInteger(
935                            serviceElement.attributeValue("owner-type"));
936                    String serviceName = serviceElement.attributeValue("service-name");
937    
938                    PortletPreferences portletPreferences = getPortletPreferences(
939                            portletDataContext.getCompanyId(), ownerId, ownerType,
940                            LayoutConstants.DEFAULT_PLID, serviceName);
941    
942                    for (Attribute attribute : serviceElement.attributes()) {
943                            serviceElement.remove(attribute);
944                    }
945    
946                    String xml = serviceElement.asXML();
947    
948                    portletPreferences.setPreferences(xml);
949    
950                    PortletPreferencesLocalServiceUtil.updatePortletPreferences(
951                            portletPreferences);
952            }
953    
954            protected void readAssetLinks(PortletDataContext portletDataContext)
955                    throws Exception {
956    
957                    String xml = portletDataContext.getZipEntryAsString(
958                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
959                                    "/links.xml");
960    
961                    if (xml == null) {
962                            return;
963                    }
964    
965                    Document document = SAXReaderUtil.read(xml);
966    
967                    Element rootElement = document.getRootElement();
968    
969                    List<Element> assetLinkGroupElements = rootElement.elements(
970                            "asset-link-group");
971    
972                    for (Element assetLinkGroupElement : assetLinkGroupElements) {
973                            String sourceUuid = assetLinkGroupElement.attributeValue(
974                                    "source-uuid");
975    
976                            AssetEntry sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
977                                    portletDataContext.getScopeGroupId(), sourceUuid);
978    
979                            if (sourceAssetEntry == null) {
980                                    sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
981                                            portletDataContext.getCompanyGroupId(), sourceUuid);
982                            }
983    
984                            if (sourceAssetEntry == null) {
985                                    if (_log.isWarnEnabled()) {
986                                            _log.warn(
987                                                    "Unable to find asset entry with uuid " + sourceUuid);
988                                    }
989    
990                                    continue;
991                            }
992    
993                            List<Element> assetLinksElements = assetLinkGroupElement.elements(
994                                    "asset-link");
995    
996                            for (Element assetLinkElement : assetLinksElements) {
997                                    String path = assetLinkElement.attributeValue("path");
998    
999                                    if (!portletDataContext.isPathNotProcessed(path)) {
1000                                            continue;
1001                                    }
1002    
1003                                    String targetUuid = assetLinkElement.attributeValue(
1004                                            "target-uuid");
1005    
1006                                    AssetEntry targetAssetEntry =
1007                                            AssetEntryLocalServiceUtil.fetchEntry(
1008                                                    portletDataContext.getScopeGroupId(), targetUuid);
1009    
1010                                    if (targetAssetEntry == null) {
1011                                            targetAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
1012                                                    portletDataContext.getCompanyGroupId(), targetUuid);
1013                                    }
1014    
1015                                    if (targetAssetEntry == null) {
1016                                            if (_log.isWarnEnabled()) {
1017                                                    _log.warn(
1018                                                            "Unable to find asset entry with uuid " +
1019                                                                    targetUuid);
1020                                            }
1021    
1022                                            continue;
1023                                    }
1024    
1025                                    AssetLink assetLink =
1026                                            (AssetLink)portletDataContext.getZipEntryAsObject(path);
1027    
1028                                    long userId = portletDataContext.getUserId(
1029                                            assetLink.getUserUuid());
1030    
1031                                    AssetLinkLocalServiceUtil.updateLink(
1032                                            userId, sourceAssetEntry.getEntryId(),
1033                                            targetAssetEntry.getEntryId(), assetLink.getType(),
1034                                            assetLink.getWeight());
1035                            }
1036                    }
1037            }
1038    
1039            protected void readAssetTags(PortletDataContext portletDataContext)
1040                    throws Exception {
1041    
1042                    String xml = portletDataContext.getZipEntryAsString(
1043                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1044                                    "/tags.xml");
1045    
1046                    if (xml == null) {
1047                            return;
1048                    }
1049    
1050                    Document document = SAXReaderUtil.read(xml);
1051    
1052                    Element rootElement = document.getRootElement();
1053    
1054                    List<Element> assetTagElements = rootElement.elements("tag");
1055    
1056                    for (Element assetTagElement : assetTagElements) {
1057                            String path = assetTagElement.attributeValue("path");
1058    
1059                            if (!portletDataContext.isPathNotProcessed(path)) {
1060                                    continue;
1061                            }
1062    
1063                            AssetTag assetTag =
1064                                    (AssetTag)portletDataContext.getZipEntryAsObject(path);
1065    
1066                            Map<Long, Long> assetTagPKs =
1067                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1068                                            AssetTag.class);
1069    
1070                            importAssetTag(
1071                                    portletDataContext, assetTagPKs, assetTagElement, assetTag);
1072                    }
1073    
1074                    List<Element> assetElements = rootElement.elements("asset");
1075    
1076                    for (Element assetElement : assetElements) {
1077                            String className = GetterUtil.getString(
1078                                    assetElement.attributeValue("class-name"));
1079                            long classPK = GetterUtil.getLong(
1080                                    assetElement.attributeValue("class-pk"));
1081                            String assetTagNames = GetterUtil.getString(
1082                                    assetElement.attributeValue("tags"));
1083    
1084                            portletDataContext.addAssetTags(
1085                                    className, classPK, StringUtil.split(assetTagNames));
1086                    }
1087            }
1088    
1089            protected void readExpandoTables(PortletDataContext portletDataContext)
1090                    throws Exception {
1091    
1092                    String xml = portletDataContext.getZipEntryAsString(
1093                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1094                                    "/expando-tables.xml");
1095    
1096                    if (xml == null) {
1097                            return;
1098                    }
1099    
1100                    Document document = SAXReaderUtil.read(xml);
1101    
1102                    Element rootElement = document.getRootElement();
1103    
1104                    List<Element> expandoTableElements = rootElement.elements(
1105                            "expando-table");
1106    
1107                    for (Element expandoTableElement : expandoTableElements) {
1108                            String className = expandoTableElement.attributeValue("class-name");
1109    
1110                            ExpandoTable expandoTable = null;
1111    
1112                            try {
1113                                    expandoTable = ExpandoTableLocalServiceUtil.getDefaultTable(
1114                                            portletDataContext.getCompanyId(), className);
1115                            }
1116                            catch (NoSuchTableException nste) {
1117                                    expandoTable = ExpandoTableLocalServiceUtil.addDefaultTable(
1118                                            portletDataContext.getCompanyId(), className);
1119                            }
1120    
1121                            List<Element> expandoColumnElements = expandoTableElement.elements(
1122                                    "expando-column");
1123    
1124                            for (Element expandoColumnElement : expandoColumnElements) {
1125                                    long columnId = GetterUtil.getLong(
1126                                            expandoColumnElement.attributeValue("column-id"));
1127                                    String name = expandoColumnElement.attributeValue("name");
1128                                    int type = GetterUtil.getInteger(
1129                                            expandoColumnElement.attributeValue("type"));
1130                                    String defaultData = expandoColumnElement.elementText(
1131                                            "default-data");
1132                                    String typeSettings = expandoColumnElement.elementText(
1133                                            "type-settings");
1134    
1135                                    Serializable defaultDataObject =
1136                                            ExpandoConverterUtil.getAttributeFromString(
1137                                                    type, defaultData);
1138    
1139                                    ExpandoColumn expandoColumn =
1140                                            ExpandoColumnLocalServiceUtil.getColumn(
1141                                                    expandoTable.getTableId(), name);
1142    
1143                                    if (expandoColumn != null) {
1144                                            ExpandoColumnLocalServiceUtil.updateColumn(
1145                                                    expandoColumn.getColumnId(), name, type,
1146                                                    defaultDataObject);
1147                                    }
1148                                    else {
1149                                            expandoColumn = ExpandoColumnLocalServiceUtil.addColumn(
1150                                                    expandoTable.getTableId(), name, type,
1151                                                    defaultDataObject);
1152                                    }
1153    
1154                                    ExpandoColumnLocalServiceUtil.updateTypeSettings(
1155                                            expandoColumn.getColumnId(), typeSettings);
1156    
1157                                    portletDataContext.importPermissions(
1158                                            ExpandoColumn.class, columnId, expandoColumn.getColumnId());
1159                            }
1160                    }
1161            }
1162    
1163            protected void readLocks(PortletDataContext portletDataContext)
1164                    throws Exception {
1165    
1166                    String xml = portletDataContext.getZipEntryAsString(
1167                            ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1168                                    "/locks.xml");
1169    
1170                    if (xml == null) {
1171                            return;
1172                    }
1173    
1174                    Document document = SAXReaderUtil.read(xml);
1175    
1176                    Element rootElement = document.getRootElement();
1177    
1178                    List<Element> assetElements = rootElement.elements("asset");
1179    
1180                    for (Element assetElement : assetElements) {
1181                            String path = assetElement.attributeValue("path");
1182                            String className = assetElement.attributeValue("class-name");
1183                            String key = assetElement.attributeValue("key");
1184    
1185                            Lock lock = (Lock)portletDataContext.getZipEntryAsObject(path);
1186    
1187                            if (lock != null) {
1188                                    portletDataContext.addLocks(className, key, lock);
1189                            }
1190                    }
1191            }
1192    
1193            protected void resetPortletScope(
1194                    PortletDataContext portletDataContext, long groupId) {
1195    
1196                    portletDataContext.setScopeGroupId(groupId);
1197                    portletDataContext.setScopeLayoutUuid(StringPool.BLANK);
1198                    portletDataContext.setScopeType(StringPool.BLANK);
1199            }
1200    
1201            protected void updatePortletPreferences(
1202                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1203                            long plid, String portletId, String xml, boolean importData)
1204                    throws Exception {
1205    
1206                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1207                            portletDataContext.getCompanyId(), portletId);
1208    
1209                    if (portlet == null) {
1210                            if (_log.isDebugEnabled()) {
1211                                    _log.debug(
1212                                            "Do not update portlet preferences for " + portletId +
1213                                                    " because the portlet does not exist");
1214                            }
1215    
1216                            return;
1217                    }
1218    
1219                    PortletDataHandler portletDataHandler =
1220                            portlet.getPortletDataHandlerInstance();
1221    
1222                    if (importData || !MergeLayoutPrototypesThreadLocal.isInProgress()) {
1223                            PortletPreferencesLocalServiceUtil.updatePreferences(
1224                                    ownerId, ownerType, plid, portletId, xml);
1225    
1226                            return;
1227                    }
1228    
1229                    // Portlet preferences to be updated only when importing data
1230    
1231                    String[] dataPortletPreferences =
1232                            portletDataHandler.getDataPortletPreferences();
1233    
1234                    // Current portlet preferences
1235    
1236                    javax.portlet.PortletPreferences portletPreferences =
1237                            PortletPreferencesLocalServiceUtil.getPreferences(
1238                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1239                                    portletId);
1240    
1241                    // New portlet preferences
1242    
1243                    javax.portlet.PortletPreferences jxPortletPreferences =
1244                            PortletPreferencesFactoryUtil.fromXML(
1245                                    portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1246                                    portletId, xml);
1247    
1248                    Enumeration<String> enu = jxPortletPreferences.getNames();
1249    
1250                    while (enu.hasMoreElements()) {
1251                            String name = enu.nextElement();
1252    
1253                            String scopeLayoutUuid = portletDataContext.getScopeLayoutUuid();
1254                            String scopeType = portletDataContext.getScopeType();
1255    
1256                            if (!ArrayUtil.contains(dataPortletPreferences, name) ||
1257                                    (Validator.isNull(scopeLayoutUuid) &&
1258                                     scopeType.equals("company"))) {
1259    
1260                                    String[] values = jxPortletPreferences.getValues(name, null);
1261    
1262                                    portletPreferences.setValues(name, values);
1263                            }
1264                    }
1265    
1266                    PortletPreferencesLocalServiceUtil.updatePreferences(
1267                            ownerId, ownerType, plid, portletId, portletPreferences);
1268            }
1269    
1270            protected void validateFile(
1271                            long companyId, long groupId, String portletId, ZipReader zipReader)
1272                    throws Exception {
1273    
1274                    // XML
1275    
1276                    String xml = zipReader.getEntryAsString("/manifest.xml");
1277    
1278                    if (xml == null) {
1279                            throw new LARFileException("manifest.xml not found in the LAR");
1280                    }
1281    
1282                    Element rootElement = null;
1283    
1284                    try {
1285                            Document document = SAXReaderUtil.read(xml);
1286    
1287                            rootElement = document.getRootElement();
1288                    }
1289                    catch (Exception e) {
1290                            throw new LARFileException(e);
1291                    }
1292    
1293                    // Build compatibility
1294    
1295                    int buildNumber = ReleaseInfo.getBuildNumber();
1296    
1297                    Element headerElement = rootElement.element("header");
1298    
1299                    int importBuildNumber = GetterUtil.getInteger(
1300                            headerElement.attributeValue("build-number"));
1301    
1302                    if (buildNumber != importBuildNumber) {
1303                            throw new LayoutImportException(
1304                                    "LAR build number " + importBuildNumber + " does not match " +
1305                                            "portal build number " + buildNumber);
1306                    }
1307    
1308                    // Type
1309    
1310                    String larType = headerElement.attributeValue("type");
1311    
1312                    if (!larType.equals("portlet")) {
1313                            throw new LARTypeException(larType);
1314                    }
1315    
1316                    // Portlet compatibility
1317    
1318                    String rootPortletId = headerElement.attributeValue("root-portlet-id");
1319    
1320                    if (!PortletConstants.getRootPortletId(portletId).equals(
1321                                    rootPortletId)) {
1322    
1323                            throw new PortletIdException("Invalid portlet id " + rootPortletId);
1324                    }
1325    
1326                    // Available locales
1327    
1328                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1329                            companyId, portletId);
1330    
1331                    PortletDataHandler portletDataHandler =
1332                            portlet.getPortletDataHandlerInstance();
1333    
1334                    if (portletDataHandler.isDataLocalized()) {
1335                            Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1336                                    StringUtil.split(
1337                                            headerElement.attributeValue("available-locales")));
1338    
1339                            Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1340                                    PortalUtil.getSiteGroupId(groupId));
1341    
1342                            for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1343                                    if (!ArrayUtil.contains(
1344                                                    targetAvailableLocales, sourceAvailableLocale)) {
1345    
1346                                            LocaleException le = new LocaleException(
1347                                                    LocaleException.TYPE_EXPORT_IMPORT,
1348                                                    "Locale " + sourceAvailableLocale + " is not " +
1349                                                            "available in company " + companyId);
1350    
1351                                            le.setSourceAvailableLocales(sourceAvailableLocales);
1352                                            le.setTargetAvailableLocales(targetAvailableLocales);
1353    
1354                                            throw le;
1355                                    }
1356                            }
1357                    }
1358            }
1359    
1360            private PortletImporter() {
1361            }
1362    
1363            private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
1364    
1365            private static PortletImporter _instance = new PortletImporter();
1366    
1367            private DeletionSystemEventImporter _deletionSystemEventImporter =
1368                    DeletionSystemEventImporter.getInstance();
1369            private PermissionImporter _permissionImporter =
1370                    PermissionImporter.getInstance();
1371    
1372    }