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.LayoutPrototypeException;
021    import com.liferay.portal.LocaleException;
022    import com.liferay.portal.MissingReferenceException;
023    import com.liferay.portal.NoSuchLayoutException;
024    import com.liferay.portal.NoSuchLayoutPrototypeException;
025    import com.liferay.portal.NoSuchLayoutSetPrototypeException;
026    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.exception.SystemException;
029    import com.liferay.portal.kernel.language.LanguageUtil;
030    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
031    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
032    import com.liferay.portal.kernel.lar.ManifestSummary;
033    import com.liferay.portal.kernel.lar.MissingReference;
034    import com.liferay.portal.kernel.lar.MissingReferences;
035    import com.liferay.portal.kernel.lar.PortletDataContext;
036    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
037    import com.liferay.portal.kernel.lar.PortletDataHandler;
038    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
039    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
040    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
041    import com.liferay.portal.kernel.lar.UserIdStrategy;
042    import com.liferay.portal.kernel.log.Log;
043    import com.liferay.portal.kernel.log.LogFactoryUtil;
044    import com.liferay.portal.kernel.search.SearchEngineUtil;
045    import com.liferay.portal.kernel.util.ArrayUtil;
046    import com.liferay.portal.kernel.util.Constants;
047    import com.liferay.portal.kernel.util.GetterUtil;
048    import com.liferay.portal.kernel.util.LocaleUtil;
049    import com.liferay.portal.kernel.util.MapUtil;
050    import com.liferay.portal.kernel.util.ReleaseInfo;
051    import com.liferay.portal.kernel.util.StringPool;
052    import com.liferay.portal.kernel.util.StringUtil;
053    import com.liferay.portal.kernel.util.Tuple;
054    import com.liferay.portal.kernel.util.UnicodeProperties;
055    import com.liferay.portal.kernel.util.Validator;
056    import com.liferay.portal.kernel.xml.Document;
057    import com.liferay.portal.kernel.xml.Element;
058    import com.liferay.portal.kernel.xml.SAXReaderUtil;
059    import com.liferay.portal.kernel.zip.ZipReader;
060    import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
061    import com.liferay.portal.model.Group;
062    import com.liferay.portal.model.GroupConstants;
063    import com.liferay.portal.model.Layout;
064    import com.liferay.portal.model.LayoutConstants;
065    import com.liferay.portal.model.LayoutPrototype;
066    import com.liferay.portal.model.LayoutSet;
067    import com.liferay.portal.model.LayoutSetPrototype;
068    import com.liferay.portal.model.Portlet;
069    import com.liferay.portal.model.PortletConstants;
070    import com.liferay.portal.model.User;
071    import com.liferay.portal.security.permission.PermissionCacheUtil;
072    import com.liferay.portal.service.GroupLocalServiceUtil;
073    import com.liferay.portal.service.LayoutLocalServiceUtil;
074    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
075    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
076    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
077    import com.liferay.portal.service.PortletLocalServiceUtil;
078    import com.liferay.portal.service.ServiceContext;
079    import com.liferay.portal.service.ServiceContextThreadLocal;
080    import com.liferay.portal.service.persistence.LayoutUtil;
081    import com.liferay.portal.service.persistence.UserUtil;
082    import com.liferay.portal.servlet.filters.cache.CacheUtil;
083    import com.liferay.portlet.journal.model.JournalArticle;
084    import com.liferay.portlet.journalcontent.util.JournalContentUtil;
085    import com.liferay.portlet.sites.util.Sites;
086    
087    import java.io.File;
088    
089    import java.util.ArrayList;
090    import java.util.HashMap;
091    import java.util.List;
092    import java.util.Locale;
093    import java.util.Map;
094    
095    import org.apache.commons.lang.time.StopWatch;
096    
097    /**
098     * @author Brian Wing Shun Chan
099     * @author Joel Kozikowski
100     * @author Charles May
101     * @author Raymond Augé
102     * @author Jorge Ferrer
103     * @author Bruno Farache
104     * @author Wesley Gong
105     * @author Zsigmond Rab
106     * @author Douglas Wong
107     * @author Julio Camarero
108     * @author Zsolt Berentey
109     */
110    public class LayoutImporter {
111    
112            public static Map<String, Boolean> getImportPortletControlsMap(
113                            long companyId, String portletId,
114                            Map<String, String[]> parameterMap, Element portletDataElement,
115                            ManifestSummary manifestSummary)
116                    throws Exception {
117    
118                    boolean importPortletConfiguration = MapUtil.getBoolean(
119                            parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION);
120                    boolean importPortletConfigurationAll = MapUtil.getBoolean(
121                            parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL);
122                    boolean importPortletData = MapUtil.getBoolean(
123                            parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
124                    boolean importPortletDataAll = MapUtil.getBoolean(
125                            parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
126    
127                    if (_log.isDebugEnabled()) {
128                            _log.debug("Import portlet data " + importPortletData);
129                            _log.debug("Import all portlet data " + importPortletDataAll);
130                            _log.debug(
131                                    "Import portlet configuration " + importPortletConfiguration);
132                    }
133    
134                    boolean importCurPortletData = importPortletData;
135    
136                    String rootPortletId =
137                            ExportImportHelperUtil.getExportableRootPortletId(
138                                    companyId, portletId);
139    
140                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
141                            companyId, portletId);
142    
143                    PortletDataHandler portletDataHandler =
144                            portlet.getPortletDataHandlerInstance();
145    
146                    if ((portletDataHandler == null) ||
147                            ((portletDataElement == null) &&
148                             !portletDataHandler.isDisplayPortlet())) {
149    
150                            importCurPortletData = false;
151                    }
152                    else if (importPortletDataAll) {
153                            importCurPortletData = true;
154                    }
155                    else if (rootPortletId != null) {
156                            importCurPortletData =
157                                    importPortletData &&
158                                    MapUtil.getBoolean(
159                                            parameterMap,
160                                            PortletDataHandlerKeys.PORTLET_DATA +
161                                                    StringPool.UNDERLINE + rootPortletId);
162                    }
163    
164                    boolean importCurPortletArchivedSetups = importPortletConfiguration;
165                    boolean importCurPortletConfiguration = importPortletConfiguration;
166                    boolean importCurPortletSetup = importPortletConfiguration;
167                    boolean importCurPortletUserPreferences = importPortletConfiguration;
168    
169                    if (importPortletConfigurationAll) {
170                            importCurPortletConfiguration = true;
171    
172                            if ((manifestSummary != null) &&
173                                    (manifestSummary.getConfigurationPortletOptions(
174                                            rootPortletId) == null)) {
175    
176                                    importCurPortletConfiguration = false;
177                            }
178    
179                            importCurPortletArchivedSetups =
180                                    importCurPortletConfiguration &&
181                                    MapUtil.getBoolean(
182                                            parameterMap,
183                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS_ALL);
184                            importCurPortletSetup =
185                                    importCurPortletConfiguration &&
186                                    MapUtil.getBoolean(
187                                            parameterMap, PortletDataHandlerKeys.PORTLET_SETUP_ALL);
188                            importCurPortletUserPreferences =
189                                    importCurPortletConfiguration &&
190                                    MapUtil.getBoolean(
191                                            parameterMap,
192                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES_ALL);
193                    }
194                    else if (rootPortletId != null) {
195                            importCurPortletConfiguration =
196                                    importPortletConfiguration &&
197                                    MapUtil.getBoolean(
198                                            parameterMap,
199                                            PortletDataHandlerKeys.PORTLET_CONFIGURATION +
200                                                    StringPool.UNDERLINE + rootPortletId);
201    
202                            importCurPortletArchivedSetups =
203                                    importCurPortletConfiguration &&
204                                    MapUtil.getBoolean(
205                                            parameterMap,
206                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS +
207                                                    StringPool.UNDERLINE + rootPortletId);
208                            importCurPortletSetup =
209                                    importCurPortletConfiguration &&
210                                    MapUtil.getBoolean(
211                                            parameterMap,
212                                            PortletDataHandlerKeys.PORTLET_SETUP +
213                                                    StringPool.UNDERLINE + rootPortletId);
214                            importCurPortletUserPreferences =
215                                    importCurPortletConfiguration &&
216                                    MapUtil.getBoolean(
217                                            parameterMap,
218                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES +
219                                                    StringPool.UNDERLINE + rootPortletId);
220                    }
221    
222                    Map<String, Boolean> importPortletControlsMap =
223                            new HashMap<String, Boolean>();
224    
225                    importPortletControlsMap.put(
226                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS,
227                            importCurPortletArchivedSetups);
228                    importPortletControlsMap.put(
229                            PortletDataHandlerKeys.PORTLET_CONFIGURATION,
230                            importCurPortletConfiguration);
231                    importPortletControlsMap.put(
232                            PortletDataHandlerKeys.PORTLET_DATA, importCurPortletData);
233                    importPortletControlsMap.put(
234                            PortletDataHandlerKeys.PORTLET_SETUP, importCurPortletSetup);
235                    importPortletControlsMap.put(
236                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
237                            importCurPortletUserPreferences);
238    
239                    return importPortletControlsMap;
240            }
241    
242            public void importLayouts(
243                            long userId, long groupId, boolean privateLayout,
244                            Map<String, String[]> parameterMap, File file)
245                    throws Exception {
246    
247                    boolean indexReadOnly = SearchEngineUtil.isIndexReadOnly();
248    
249                    try {
250                            ExportImportThreadLocal.setLayoutImportInProcess(true);
251    
252                            SearchEngineUtil.setIndexReadOnly(true);
253    
254                            doImportLayouts(
255                                    userId, groupId, privateLayout, parameterMap, file,
256                                    indexReadOnly);
257                    }
258                    finally {
259                            ExportImportThreadLocal.setLayoutImportInProcess(false);
260    
261                            CacheUtil.clearCache();
262                            JournalContentUtil.clearCache();
263                            PermissionCacheUtil.clearCache();
264    
265                            SearchEngineUtil.setIndexReadOnly(indexReadOnly);
266                    }
267            }
268    
269            public MissingReferences validateFile(
270                            long userId, long groupId, boolean privateLayout,
271                            Map<String, String[]> parameterMap, File file)
272                    throws Exception {
273    
274                    try {
275                            ExportImportThreadLocal.setLayoutValidationInProcess(true);
276    
277                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
278                                    groupId, privateLayout);
279    
280                            ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
281    
282                            PortletDataContext portletDataContext =
283                                    PortletDataContextFactoryUtil.createImportPortletDataContext(
284                                            layoutSet.getCompanyId(), groupId, parameterMap, null,
285                                            zipReader);
286    
287                            validateFile(portletDataContext);
288    
289                            MissingReferences missingReferences =
290                                    ExportImportHelperUtil.validateMissingReferences(
291                                            userId, groupId, parameterMap, file);
292    
293                            Map<String, MissingReference> dependencyMissingReferences =
294                                    missingReferences.getDependencyMissingReferences();
295    
296                            if (!dependencyMissingReferences.isEmpty()) {
297                                    throw new MissingReferenceException(missingReferences);
298                            }
299    
300                            return missingReferences;
301                    }
302                    finally {
303                            ExportImportThreadLocal.setLayoutValidationInProcess(false);
304                    }
305            }
306    
307            protected void deleteMissingLayouts(
308                            List<String> sourceLayoutUuids, List<Layout> previousLayouts,
309                            ServiceContext serviceContext)
310                    throws Exception {
311    
312                    if (_log.isDebugEnabled() && !sourceLayoutUuids.isEmpty()) {
313                            _log.debug("Delete missing layouts");
314                    }
315    
316                    for (Layout layout : previousLayouts) {
317                            if (!sourceLayoutUuids.contains(layout.getUuid())) {
318                                    try {
319                                            LayoutLocalServiceUtil.deleteLayout(
320                                                    layout, false, serviceContext);
321                                    }
322                                    catch (NoSuchLayoutException nsle) {
323                                    }
324                            }
325                    }
326            }
327    
328            protected void doImportLayouts(
329                            long userId, long groupId, boolean privateLayout,
330                            Map<String, String[]> parameterMap, File file,
331                            boolean indexReadOnly)
332                    throws Exception {
333    
334                    boolean deleteMissingLayouts = MapUtil.getBoolean(
335                            parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
336                            Boolean.TRUE.booleanValue());
337                    boolean deletePortletData = MapUtil.getBoolean(
338                            parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
339                    boolean importCategories = MapUtil.getBoolean(
340                            parameterMap, PortletDataHandlerKeys.CATEGORIES);
341                    boolean importPermissions = MapUtil.getBoolean(
342                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
343                    boolean importLogo = MapUtil.getBoolean(
344                            parameterMap, PortletDataHandlerKeys.LOGO);
345                    boolean importLayoutSetSettings = MapUtil.getBoolean(
346                            parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
347    
348                    boolean layoutSetPrototypeLinkEnabled = MapUtil.getBoolean(
349                            parameterMap,
350                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED);
351    
352                    Group group = GroupLocalServiceUtil.getGroup(groupId);
353    
354                    if (group.isLayoutSetPrototype()) {
355                            layoutSetPrototypeLinkEnabled = false;
356                    }
357    
358                    String layoutsImportMode = MapUtil.getString(
359                            parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
360                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
361                    String userIdStrategy = MapUtil.getString(
362                            parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
363    
364                    if (_log.isDebugEnabled()) {
365                            _log.debug("Delete portlet data " + deletePortletData);
366                            _log.debug("Import categories " + importCategories);
367                            _log.debug("Import permissions " + importPermissions);
368                    }
369    
370                    StopWatch stopWatch = new StopWatch();
371    
372                    stopWatch.start();
373    
374                    LayoutCache layoutCache = new LayoutCache();
375    
376                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
377                            groupId, privateLayout);
378    
379                    long companyId = layoutSet.getCompanyId();
380    
381                    User user = UserUtil.findByPrimaryKey(userId);
382    
383                    ServiceContext serviceContext =
384                            ServiceContextThreadLocal.getServiceContext();
385    
386                    if (serviceContext == null) {
387                            serviceContext = new ServiceContext();
388    
389                            serviceContext.setCompanyId(companyId);
390                            serviceContext.setSignedIn(false);
391                            serviceContext.setUserId(userId);
392    
393                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
394                    }
395    
396                    UserIdStrategy strategy = _portletImporter.getUserIdStrategy(
397                            user, userIdStrategy);
398    
399                    ManifestSummary manifestSummary =
400                            ExportImportHelperUtil.getManifestSummary(
401                                    userId, groupId, parameterMap, file);
402    
403                    ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
404    
405                    final PortletDataContext portletDataContext =
406                            PortletDataContextFactoryUtil.createImportPortletDataContext(
407                                    companyId, groupId, parameterMap, strategy, zipReader);
408    
409                    portletDataContext.setManifestSummary(manifestSummary);
410                    portletDataContext.setPortetDataContextListener(
411                            new PortletDataContextListenerImpl(portletDataContext));
412    
413                    portletDataContext.setPrivateLayout(privateLayout);
414    
415                    // Zip
416    
417                    validateFile(portletDataContext);
418    
419                    // Company id
420    
421                    long sourceCompanyId = GetterUtil.getLong(
422                            _headerElement.attributeValue("company-id"));
423    
424                    portletDataContext.setSourceCompanyId(sourceCompanyId);
425    
426                    // Company group id
427    
428                    long sourceCompanyGroupId = GetterUtil.getLong(
429                            _headerElement.attributeValue("company-group-id"));
430    
431                    portletDataContext.setSourceCompanyGroupId(sourceCompanyGroupId);
432    
433                    // Group id
434    
435                    long sourceGroupId = GetterUtil.getLong(
436                            _headerElement.attributeValue("group-id"));
437    
438                    portletDataContext.setSourceGroupId(sourceGroupId);
439    
440                    // User personal site group id
441    
442                    long sourceUserPersonalSiteGroupId = GetterUtil.getLong(
443                            _headerElement.attributeValue("user-personal-site-group-id"));
444    
445                    portletDataContext.setSourceUserPersonalSiteGroupId(
446                            sourceUserPersonalSiteGroupId);
447    
448                    // Layout and layout set prototype
449    
450                    String layoutSetPrototypeUuid = _layoutsElement.attributeValue(
451                            "layout-set-prototype-uuid");
452    
453                    String larType = _headerElement.attributeValue("type");
454    
455                    if (group.isLayoutPrototype() && larType.equals("layout-prototype")) {
456                            deleteMissingLayouts = false;
457    
458                            LayoutPrototype layoutPrototype =
459                                    LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
460                                            group.getClassPK());
461    
462                            String layoutPrototypeUuid = GetterUtil.getString(
463                                    _headerElement.attributeValue("type-uuid"));
464    
465                            LayoutPrototype existingLayoutPrototype = null;
466    
467                            if (Validator.isNotNull(layoutPrototypeUuid)) {
468                                    try {
469                                            existingLayoutPrototype =
470                                                    LayoutPrototypeLocalServiceUtil.
471                                                            getLayoutPrototypeByUuidAndCompanyId(
472                                                                    layoutPrototypeUuid, companyId);
473                                    }
474                                    catch (NoSuchLayoutPrototypeException nslpe) {
475                                    }
476                            }
477    
478                            if (existingLayoutPrototype == null) {
479                                    List<Layout> layouts =
480                                            LayoutLocalServiceUtil.getLayoutsByLayoutPrototypeUuid(
481                                                    layoutPrototype.getUuid());
482    
483                                    layoutPrototype.setUuid(layoutPrototypeUuid);
484    
485                                    LayoutPrototypeLocalServiceUtil.updateLayoutPrototype(
486                                            layoutPrototype);
487    
488                                    for (Layout layout : layouts) {
489                                            layout.setLayoutPrototypeUuid(layoutPrototypeUuid);
490    
491                                            LayoutLocalServiceUtil.updateLayout(layout);
492                                    }
493                            }
494                    }
495                    else if (group.isLayoutSetPrototype() &&
496                                     larType.equals("layout-set-prototype")) {
497    
498                            LayoutSetPrototype layoutSetPrototype =
499                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
500                                            group.getClassPK());
501    
502                            String importedLayoutSetPrototypeUuid = GetterUtil.getString(
503                                    _headerElement.attributeValue("type-uuid"));
504    
505                            LayoutSetPrototype existingLayoutSetPrototype = null;
506    
507                            if (Validator.isNotNull(importedLayoutSetPrototypeUuid)) {
508                                    try {
509                                            existingLayoutSetPrototype =
510                                                    LayoutSetPrototypeLocalServiceUtil.
511                                                            getLayoutSetPrototypeByUuidAndCompanyId(
512                                                                    importedLayoutSetPrototypeUuid, companyId);
513                                    }
514                                    catch (NoSuchLayoutSetPrototypeException nslspe) {
515                                    }
516                            }
517    
518                            if (existingLayoutSetPrototype == null) {
519                                    layoutSetPrototype.setUuid(importedLayoutSetPrototypeUuid);
520    
521                                    LayoutSetPrototypeLocalServiceUtil.updateLayoutSetPrototype(
522                                            layoutSetPrototype);
523                            }
524                    }
525                    else if (larType.equals("layout-set-prototype")) {
526                            layoutSetPrototypeUuid = GetterUtil.getString(
527                                    _headerElement.attributeValue("type-uuid"));
528                    }
529    
530                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
531                            layoutSet.setLayoutSetPrototypeUuid(layoutSetPrototypeUuid);
532                            layoutSet.setLayoutSetPrototypeLinkEnabled(
533                                    layoutSetPrototypeLinkEnabled);
534    
535                            LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
536                    }
537    
538                    Element missingReferencesElement = _rootElement.element(
539                            "missing-references");
540    
541                    if (missingReferencesElement != null) {
542                            portletDataContext.setMissingReferencesElement(
543                                    missingReferencesElement);
544                    }
545    
546                    // Look and feel
547    
548                    if (importLogo) {
549                            String logoPath = _headerElement.attributeValue("logo-path");
550    
551                            byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
552                                    logoPath);
553    
554                            if (ArrayUtil.isNotEmpty(iconBytes)) {
555                                    LayoutSetLocalServiceUtil.updateLogo(
556                                            groupId, privateLayout, true, iconBytes);
557                            }
558                            else {
559                                    LayoutSetLocalServiceUtil.updateLogo(
560                                            groupId, privateLayout, false, (File)null);
561                            }
562                    }
563    
564                    _themeImporter.importTheme(portletDataContext, layoutSet);
565    
566                    if (importLayoutSetSettings) {
567                            String settings = GetterUtil.getString(
568                                    _headerElement.elementText("settings"));
569    
570                            LayoutSetLocalServiceUtil.updateSettings(
571                                    groupId, privateLayout, settings);
572                    }
573    
574                    Element portletsElement = _rootElement.element("portlets");
575    
576                    List<Element> portletElements = portletsElement.elements("portlet");
577    
578                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
579                            List<String> portletIds = new ArrayList<String>();
580    
581                            for (Element portletElement : portletElements) {
582                                    String portletId = portletElement.attributeValue("portlet-id");
583    
584                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
585                                            portletDataContext.getCompanyId(), portletId);
586    
587                                    if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
588                                            continue;
589                                    }
590    
591                                    portletIds.add(portletId);
592                            }
593    
594                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
595                                    "layout", portletIds.toArray(new String[portletIds.size()]),
596                                    manifestSummary);
597                    }
598    
599                    // Read asset categories, asset tags, comments, locks, permissions, and
600                    // ratings entries to make them available to the data handlers through
601                    // the portlet data context
602    
603                    if (importPermissions) {
604                            for (Element portletElement : portletElements) {
605                                    String portletPath = portletElement.attributeValue("path");
606    
607                                    Document portletDocument = SAXReaderUtil.read(
608                                            portletDataContext.getZipEntryAsString(portletPath));
609    
610                                    _permissionImporter.checkRoles(
611                                            layoutCache, companyId, groupId, userId,
612                                            portletDocument.getRootElement());
613                            }
614    
615                            _permissionImporter.readPortletDataPermissions(portletDataContext);
616                    }
617    
618                    _portletImporter.readAssetCategories(portletDataContext);
619                    _portletImporter.readAssetTags(portletDataContext);
620                    _portletImporter.readComments(portletDataContext);
621                    _portletImporter.readExpandoTables(portletDataContext);
622                    _portletImporter.readLocks(portletDataContext);
623                    _portletImporter.readRatingsEntries(portletDataContext);
624    
625                    // Layouts
626    
627                    List<Layout> previousLayouts = LayoutUtil.findByG_P(
628                            groupId, privateLayout);
629    
630                    // Remove layouts that were deleted from the layout set prototype
631    
632                    if (Validator.isNotNull(layoutSetPrototypeUuid) &&
633                            layoutSetPrototypeLinkEnabled) {
634    
635                            LayoutSetPrototype layoutSetPrototype =
636                                    LayoutSetPrototypeLocalServiceUtil.
637                                            getLayoutSetPrototypeByUuidAndCompanyId(
638                                                    layoutSetPrototypeUuid, companyId);
639    
640                            for (Layout layout : previousLayouts) {
641                                    String sourcePrototypeLayoutUuid =
642                                            layout.getSourcePrototypeLayoutUuid();
643    
644                                    if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
645                                            continue;
646                                    }
647    
648                                    Layout sourcePrototypeLayout = LayoutUtil.fetchByUUID_G_P(
649                                            sourcePrototypeLayoutUuid, layoutSetPrototype.getGroupId(),
650                                            true);
651    
652                                    if (sourcePrototypeLayout == null) {
653                                            LayoutLocalServiceUtil.deleteLayout(
654                                                    layout, false, serviceContext);
655                                    }
656                            }
657                    }
658    
659                    List<String> sourceLayoutsUuids = new ArrayList<String>();
660                    List<Layout> newLayouts = new ArrayList<Layout>();
661    
662                    if (_log.isDebugEnabled()) {
663                            if (_layoutElements.size() > 0) {
664                                    _log.debug("Importing layouts");
665                            }
666                    }
667    
668                    for (Element layoutElement : _layoutElements) {
669                            importLayout(
670                                    portletDataContext, sourceLayoutsUuids, newLayouts,
671                                    layoutElement);
672                    }
673    
674                    // Delete portlet data
675    
676                    Map<Long, Layout> newLayoutsMap =
677                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
678                                    Layout.class + ".layout");
679    
680                    if (deletePortletData) {
681                            if (_log.isDebugEnabled()) {
682                                    if (portletElements.size() > 0) {
683                                            _log.debug("Deleting portlet data");
684                                    }
685                            }
686    
687                            for (Element portletElement : portletElements) {
688                                    String portletId = portletElement.attributeValue("portlet-id");
689                                    long layoutId = GetterUtil.getLong(
690                                            portletElement.attributeValue("layout-id"));
691    
692                                    Layout layout = newLayoutsMap.get(layoutId);
693    
694                                    long plid = layout.getPlid();
695    
696                                    portletDataContext.setPlid(plid);
697    
698                                    _portletImporter.deletePortletData(
699                                            portletDataContext, portletId, plid);
700                            }
701                    }
702    
703                    // Import portlets
704    
705                    if (_log.isDebugEnabled()) {
706                            if (portletElements.size() > 0) {
707                                    _log.debug("Importing portlets");
708                            }
709                    }
710    
711                    for (Element portletElement : portletElements) {
712                            String portletPath = portletElement.attributeValue("path");
713                            String portletId = portletElement.attributeValue("portlet-id");
714                            long layoutId = GetterUtil.getLong(
715                                    portletElement.attributeValue("layout-id"));
716                            long oldPlid = GetterUtil.getLong(
717                                    portletElement.attributeValue("old-plid"));
718    
719                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
720                                    portletDataContext.getCompanyId(), portletId);
721    
722                            if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
723                                    continue;
724                            }
725    
726                            Layout layout = newLayoutsMap.get(layoutId);
727    
728                            long plid = LayoutConstants.DEFAULT_PLID;
729    
730                            if (layout != null) {
731                                    plid = layout.getPlid();
732                            }
733    
734                            portletDataContext.setPlid(plid);
735                            portletDataContext.setOldPlid(oldPlid);
736    
737                            if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
738                                    PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
739                                            "portlet", portletId, manifestSummary);
740                            }
741    
742                            Document portletDocument = SAXReaderUtil.read(
743                                    portletDataContext.getZipEntryAsString(portletPath));
744    
745                            portletElement = portletDocument.getRootElement();
746    
747                            // The order of the import is important. You must always import the
748                            // portlet preferences first, then the portlet data, then the
749                            // portlet permissions. The import of the portlet data assumes that
750                            // portlet preferences already exist.
751    
752                            setPortletScope(portletDataContext, portletElement);
753    
754                            long portletPreferencesGroupId = groupId;
755    
756                            Element portletDataElement = portletElement.element("portlet-data");
757    
758                            Map<String, Boolean> importPortletControlsMap =
759                                    getImportPortletControlsMap(
760                                            companyId, portletId, parameterMap, portletDataElement,
761                                            manifestSummary);
762    
763                            try {
764                                    portletDataContext.setRootPortletId(
765                                            PortletConstants.getRootPortletId(portletId));
766    
767                                    if (layout != null) {
768                                            portletPreferencesGroupId = layout.getGroupId();
769                                    }
770    
771                                    // Portlet preferences
772    
773                                    _portletImporter.importPortletPreferences(
774                                            portletDataContext, layoutSet.getCompanyId(),
775                                            portletPreferencesGroupId, layout, null, portletElement,
776                                            false,
777                                            importPortletControlsMap.get(
778                                                    PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
779                                            importPortletControlsMap.get(
780                                                    PortletDataHandlerKeys.PORTLET_DATA),
781                                            importPortletControlsMap.get(
782                                                    PortletDataHandlerKeys.PORTLET_SETUP),
783                                            importPortletControlsMap.get(
784                                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
785    
786                                    // Portlet data
787    
788                                    if (importPortletControlsMap.get(
789                                                    PortletDataHandlerKeys.PORTLET_DATA)) {
790    
791                                            _portletImporter.importPortletData(
792                                                    portletDataContext, portletId, plid,
793                                                    portletDataElement);
794                                    }
795                            }
796                            finally {
797                                    portletDataContext.setRootPortletId(StringPool.BLANK);
798    
799                                    _portletImporter.resetPortletScope(
800                                            portletDataContext, portletPreferencesGroupId);
801                            }
802    
803                            // Portlet permissions
804    
805                            if (importPermissions) {
806                                    _permissionImporter.importPortletPermissions(
807                                            layoutCache, companyId, groupId, userId, layout,
808                                            portletElement, portletId);
809                            }
810    
811                            // Archived setups
812    
813                            _portletImporter.importPortletPreferences(
814                                    portletDataContext, layoutSet.getCompanyId(), groupId, null,
815                                    null, portletElement, false,
816                                    importPortletControlsMap.get(
817                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
818                                    importPortletControlsMap.get(
819                                            PortletDataHandlerKeys.PORTLET_DATA),
820                                    importPortletControlsMap.get(
821                                            PortletDataHandlerKeys.PORTLET_SETUP),
822                                    importPortletControlsMap.get(
823                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
824                    }
825    
826                    // Asset links
827    
828                    _portletImporter.readAssetLinks(portletDataContext);
829    
830                    // Delete missing layouts
831    
832                    if (deleteMissingLayouts) {
833                            deleteMissingLayouts(
834                                    sourceLayoutsUuids, previousLayouts, serviceContext);
835                    }
836    
837                    // Page count
838    
839                    layoutSet = LayoutSetLocalServiceUtil.updatePageCount(
840                            groupId, privateLayout);
841    
842                    // Site
843    
844                    GroupLocalServiceUtil.updateSite(groupId, true);
845    
846                    // Last merge time must be the same for merged layouts and the layout
847                    // set
848    
849                    long lastMergeTime = System.currentTimeMillis();
850    
851                    for (Layout layout : newLayouts) {
852                            boolean modifiedTypeSettingsProperties = false;
853    
854                            UnicodeProperties typeSettingsProperties =
855                                    layout.getTypeSettingsProperties();
856    
857                            // Journal article layout type
858    
859                            String articleId = typeSettingsProperties.getProperty("article-id");
860    
861                            if (Validator.isNotNull(articleId)) {
862                                    Map<String, String> articleIds =
863                                            (Map<String, String>)portletDataContext.
864                                                    getNewPrimaryKeysMap(
865                                                            JournalArticle.class + ".articleId");
866    
867                                    typeSettingsProperties.setProperty(
868                                            "article-id",
869                                            MapUtil.getString(articleIds, articleId, articleId));
870    
871                                    modifiedTypeSettingsProperties = true;
872                            }
873    
874                            // Last merge time for layout
875    
876                            if (layoutsImportMode.equals(
877                                            PortletDataHandlerKeys.
878                                                    LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
879    
880                                    typeSettingsProperties.setProperty(
881                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
882    
883                                    modifiedTypeSettingsProperties = true;
884                            }
885    
886                            if (modifiedTypeSettingsProperties) {
887                                    LayoutUtil.update(layout);
888                            }
889                    }
890    
891                    // Last merge time for layout set
892    
893                    if (layoutsImportMode.equals(
894                                    PortletDataHandlerKeys.
895                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
896    
897                            UnicodeProperties settingsProperties =
898                                    layoutSet.getSettingsProperties();
899    
900                            String mergeFailFriendlyURLLayouts =
901                                    settingsProperties.getProperty(
902                                            Sites.MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
903    
904                            if (Validator.isNull(mergeFailFriendlyURLLayouts)) {
905                                    settingsProperties.setProperty(
906                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
907    
908                                    LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
909                            }
910                    }
911    
912                    // Page priorities
913    
914                    updateLayoutPriorities(
915                            portletDataContext, _layoutElements, privateLayout);
916    
917                    // Deletion system events
918    
919                    _deletionSystemEventImporter.importDeletionSystemEvents(
920                            portletDataContext);
921    
922                    if (_log.isInfoEnabled()) {
923                            _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
924                    }
925    
926                    zipReader.close();
927    
928                    if (!indexReadOnly) {
929                            ExportImportHelperUtil.reindex(portletDataContext, userId);
930                    }
931            }
932    
933            protected void importLayout(
934                            PortletDataContext portletDataContext,
935                            List<String> sourceLayoutsUuids, List<Layout> newLayouts,
936                            Element layoutElement)
937                    throws Exception {
938    
939                    String action = layoutElement.attributeValue("action");
940    
941                    if (!action.equals(Constants.SKIP)) {
942                            StagedModelDataHandlerUtil.importStagedModel(
943                                    portletDataContext, layoutElement);
944    
945                            List<Layout> portletDataContextNewLayouts =
946                                    portletDataContext.getNewLayouts();
947    
948                            newLayouts.addAll(portletDataContextNewLayouts);
949    
950                            portletDataContextNewLayouts.clear();
951                    }
952    
953                    if (!action.equals(Constants.DELETE)) {
954                            sourceLayoutsUuids.add(layoutElement.attributeValue("uuid"));
955                    }
956            }
957    
958            protected void readXML(PortletDataContext portletDataContext)
959                    throws Exception {
960    
961                    if ((_rootElement != null) && (_headerElement != null) &&
962                            (_layoutsElement != null) && (_layoutElements != null)) {
963    
964                            return;
965                    }
966    
967                    String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
968    
969                    if (xml == null) {
970                            throw new LARFileException("manifest.xml not found in the LAR");
971                    }
972    
973                    try {
974                            Document document = SAXReaderUtil.read(xml);
975    
976                            _rootElement = document.getRootElement();
977    
978                            portletDataContext.setImportDataRootElement(_rootElement);
979                    }
980                    catch (Exception e) {
981                            throw new LARFileException(e);
982                    }
983    
984                    _headerElement = _rootElement.element("header");
985    
986                    _layoutsElement = portletDataContext.getImportDataGroupElement(
987                            Layout.class);
988    
989                    _layoutElements = _layoutsElement.elements();
990            }
991    
992            protected void setPortletScope(
993                    PortletDataContext portletDataContext, Element portletElement) {
994    
995                    // Portlet data scope
996    
997                    String scopeLayoutUuid = GetterUtil.getString(
998                            portletElement.attributeValue("scope-layout-uuid"));
999                    String scopeLayoutType = GetterUtil.getString(
1000                            portletElement.attributeValue("scope-layout-type"));
1001    
1002                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1003                    portletDataContext.setScopeType(scopeLayoutType);
1004    
1005                    // Layout scope
1006    
1007                    try {
1008                            Group scopeGroup = null;
1009    
1010                            if (scopeLayoutType.equals("company")) {
1011                                    scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
1012                                            portletDataContext.getCompanyId());
1013                            }
1014                            else if (Validator.isNotNull(scopeLayoutUuid)) {
1015                                    boolean privateLayout = GetterUtil.getBoolean(
1016                                            portletElement.attributeValue("private-layout"));
1017    
1018                                    Layout scopeLayout =
1019                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1020                                                    scopeLayoutUuid, portletDataContext.getGroupId(),
1021                                                    privateLayout);
1022    
1023                                    if (scopeLayout.hasScopeGroup()) {
1024                                            scopeGroup = scopeLayout.getScopeGroup();
1025                                    }
1026                                    else {
1027                                            String name = String.valueOf(scopeLayout.getPlid());
1028    
1029                                            scopeGroup = GroupLocalServiceUtil.addGroup(
1030                                                    portletDataContext.getUserId(null),
1031                                                    GroupConstants.DEFAULT_PARENT_GROUP_ID,
1032                                                    Layout.class.getName(), scopeLayout.getPlid(),
1033                                                    GroupConstants.DEFAULT_LIVE_GROUP_ID, name, null, 0,
1034                                                    true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
1035                                                    null, false, true, null);
1036                                    }
1037    
1038                                    Group group = scopeLayout.getGroup();
1039    
1040                                    if (group.isStaged() && !group.isStagedRemotely()) {
1041                                            try {
1042                                                    Layout oldLayout =
1043                                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1044                                                                    scopeLayoutUuid,
1045                                                                    portletDataContext.getSourceGroupId(),
1046                                                                    privateLayout);
1047    
1048                                                    Group oldScopeGroup = oldLayout.getScopeGroup();
1049    
1050                                                    if (group.isStagingGroup()) {
1051                                                            scopeGroup.setLiveGroupId(
1052                                                                    oldScopeGroup.getGroupId());
1053    
1054                                                            GroupLocalServiceUtil.updateGroup(scopeGroup);
1055                                                    }
1056                                                    else {
1057                                                            oldScopeGroup.setLiveGroupId(
1058                                                                    scopeGroup.getGroupId());
1059    
1060                                                            GroupLocalServiceUtil.updateGroup(oldScopeGroup);
1061                                                    }
1062                                            }
1063                                            catch (NoSuchLayoutException nsle) {
1064                                                    if (_log.isWarnEnabled()) {
1065                                                            _log.warn(nsle);
1066                                                    }
1067                                            }
1068                                    }
1069                            }
1070    
1071                            if (scopeGroup != null) {
1072                                    portletDataContext.setScopeGroupId(scopeGroup.getGroupId());
1073                            }
1074                    }
1075                    catch (PortalException pe) {
1076                    }
1077                    catch (Exception e) {
1078                            _log.error(e, e);
1079                    }
1080            }
1081    
1082            protected void updateLayoutPriorities(
1083                            PortletDataContext portletDataContext, List<Element> layoutElements,
1084                            boolean privateLayout)
1085                    throws SystemException {
1086    
1087                    Map<Long, Layout> layouts =
1088                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
1089                                    Layout.class + ".layout");
1090    
1091                    Map<Long, Integer> layoutPriorities = new HashMap<Long, Integer>();
1092    
1093                    int maxPriority = Integer.MIN_VALUE;
1094    
1095                    for (Element layoutElement : layoutElements) {
1096                            String action = layoutElement.attributeValue(Constants.ACTION);
1097    
1098                            if (action.equals(Constants.SKIP)) {
1099    
1100                                    // We only want to update priorites if there are no elements
1101                                    // with the SKIP action
1102    
1103                                    return;
1104                            }
1105    
1106                            if (action.equals(Constants.ADD)) {
1107                                    long layoutId = GetterUtil.getLong(
1108                                            layoutElement.attributeValue("layout-id"));
1109    
1110                                    Layout layout = layouts.get(layoutId);
1111    
1112                                    int layoutPriority = GetterUtil.getInteger(
1113                                            layoutElement.attributeValue("layout-priority"));
1114    
1115                                    layoutPriorities.put(layout.getPlid(), layoutPriority);
1116    
1117                                    if (maxPriority < layoutPriority) {
1118                                            maxPriority = layoutPriority;
1119                                    }
1120                            }
1121                    }
1122    
1123                    List<Layout> layoutSetLayouts = LayoutLocalServiceUtil.getLayouts(
1124                            portletDataContext.getGroupId(), privateLayout);
1125    
1126                    for (Layout layout : layoutSetLayouts) {
1127                            if (layoutPriorities.containsKey(layout.getPlid())) {
1128                                    layout.setPriority(layoutPriorities.get(layout.getPlid()));
1129                            }
1130                            else {
1131                                    layout.setPriority(++maxPriority);
1132                            }
1133    
1134                            LayoutLocalServiceUtil.updateLayout(layout);
1135                    }
1136            }
1137    
1138            protected void validateFile(PortletDataContext portletDataContext)
1139                    throws Exception {
1140    
1141                    // Build compatibility
1142    
1143                    readXML(portletDataContext);
1144    
1145                    int buildNumber = ReleaseInfo.getBuildNumber();
1146    
1147                    int importBuildNumber = GetterUtil.getInteger(
1148                            _headerElement.attributeValue("build-number"));
1149    
1150                    if (buildNumber != importBuildNumber) {
1151                            throw new LayoutImportException(
1152                                    "LAR build number " + importBuildNumber + " does not match " +
1153                                            "portal build number " + buildNumber);
1154                    }
1155    
1156                    // Type
1157    
1158                    String larType = _headerElement.attributeValue("type");
1159    
1160                    if (!larType.equals("layout-prototype") &&
1161                            !larType.equals("layout-set") &&
1162                            !larType.equals("layout-set-prototype")) {
1163    
1164                            throw new LARTypeException(larType);
1165                    }
1166    
1167                    Group group = GroupLocalServiceUtil.fetchGroup(
1168                            portletDataContext.getGroupId());
1169    
1170                    String layoutsImportMode = MapUtil.getString(
1171                            portletDataContext.getParameterMap(),
1172                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE);
1173    
1174                    if (larType.equals("layout-prototype") && !group.isLayoutPrototype() &&
1175                            !layoutsImportMode.equals(
1176                                    PortletDataHandlerKeys.
1177                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1178    
1179                            throw new LARTypeException(
1180                                    "A page template can only be imported to a page template");
1181                    }
1182    
1183                    if (larType.equals("layout-set") &&
1184                            (group.isLayoutPrototype() || group.isLayoutSetPrototype())) {
1185    
1186                            throw new LARTypeException("A site can only be imported to a site");
1187                    }
1188    
1189                    if (larType.equals("layout-set-prototype") &&
1190                            !group.isLayoutSetPrototype() &&
1191                            !layoutsImportMode.equals(
1192                                    PortletDataHandlerKeys.
1193                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1194    
1195                            throw new LARTypeException(
1196                                    "A site template can only be imported to a site template");
1197                    }
1198    
1199                    // Available locales
1200    
1201                    Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1202                            StringUtil.split(
1203                                    _headerElement.attributeValue("available-locales")));
1204    
1205                    Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1206                            portletDataContext.getScopeGroupId());
1207    
1208                    for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1209                            if (!ArrayUtil.contains(
1210                                            targetAvailableLocales, sourceAvailableLocale)) {
1211    
1212                                    LocaleException le = new LocaleException(
1213                                            LocaleException.TYPE_EXPORT_IMPORT);
1214    
1215                                    le.setSourceAvailableLocales(sourceAvailableLocales);
1216                                    le.setTargetAvailableLocales(targetAvailableLocales);
1217    
1218                                    throw le;
1219                            }
1220                    }
1221    
1222                    // Layout prototypes validity
1223    
1224                    validateLayoutPrototypes(
1225                            portletDataContext.getCompanyId(), _layoutsElement,
1226                            _layoutElements);
1227            }
1228    
1229            protected void validateLayoutPrototypes(
1230                            long companyId, Element layoutsElement,
1231                            List<Element> layoutElements)
1232                    throws Exception {
1233    
1234                    List<Tuple> missingLayoutPrototypes = new ArrayList<Tuple>();
1235    
1236                    String layoutSetPrototypeUuid = layoutsElement.attributeValue(
1237                            "layout-set-prototype-uuid");
1238    
1239                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
1240                            try {
1241                                    LayoutSetPrototypeLocalServiceUtil.
1242                                            getLayoutSetPrototypeByUuidAndCompanyId(
1243                                                    layoutSetPrototypeUuid, companyId);
1244                            }
1245                            catch (NoSuchLayoutSetPrototypeException nlspe) {
1246                                    String layoutSetPrototypeName = layoutsElement.attributeValue(
1247                                            "layout-set-prototype-name");
1248    
1249                                    missingLayoutPrototypes.add(
1250                                            new Tuple(
1251                                                    LayoutSetPrototype.class.getName(),
1252                                                    layoutSetPrototypeUuid, layoutSetPrototypeName));
1253                            }
1254                    }
1255    
1256                    for (Element layoutElement : layoutElements) {
1257                            String action = layoutElement.attributeValue("action");
1258    
1259                            if (action.equals(Constants.SKIP)) {
1260                                    continue;
1261                            }
1262    
1263                            String layoutPrototypeUuid = GetterUtil.getString(
1264                                    layoutElement.attributeValue("layout-prototype-uuid"));
1265    
1266                            if (Validator.isNotNull(layoutPrototypeUuid)) {
1267                                    try {
1268                                            LayoutPrototypeLocalServiceUtil.
1269                                                    getLayoutPrototypeByUuidAndCompanyId(
1270                                                            layoutPrototypeUuid, companyId);
1271                                    }
1272                                    catch (NoSuchLayoutPrototypeException nslpe) {
1273                                            String layoutPrototypeName = GetterUtil.getString(
1274                                                    layoutElement.attributeValue("layout-prototype-name"));
1275    
1276                                            missingLayoutPrototypes.add(
1277                                                    new Tuple(
1278                                                            LayoutPrototype.class.getName(),
1279                                                            layoutPrototypeUuid, layoutPrototypeName));
1280                                    }
1281                            }
1282                    }
1283    
1284                    if (!missingLayoutPrototypes.isEmpty()) {
1285                            throw new LayoutPrototypeException(missingLayoutPrototypes);
1286                    }
1287            }
1288    
1289            private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1290    
1291            private DeletionSystemEventImporter _deletionSystemEventImporter =
1292                    new DeletionSystemEventImporter();
1293            private Element _headerElement;
1294            private List<Element> _layoutElements;
1295            private Element _layoutsElement;
1296            private PermissionImporter _permissionImporter = new PermissionImporter();
1297            private PortletImporter _portletImporter = new PortletImporter();
1298            private Element _rootElement;
1299            private ThemeImporter _themeImporter = new ThemeImporter();
1300    
1301    }