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