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