001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.LARFileException;
018    import com.liferay.portal.LARTypeException;
019    import com.liferay.portal.LayoutImportException;
020    import com.liferay.portal.LayoutPrototypeException;
021    import com.liferay.portal.LocaleException;
022    import com.liferay.portal.MissingReferenceException;
023    import com.liferay.portal.NoSuchLayoutException;
024    import com.liferay.portal.NoSuchLayoutPrototypeException;
025    import com.liferay.portal.NoSuchLayoutSetPrototypeException;
026    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.exception.SystemException;
029    import com.liferay.portal.kernel.language.LanguageUtil;
030    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
031    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
032    import com.liferay.portal.kernel.lar.ManifestSummary;
033    import com.liferay.portal.kernel.lar.MissingReference;
034    import com.liferay.portal.kernel.lar.MissingReferences;
035    import com.liferay.portal.kernel.lar.PortletDataContext;
036    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
037    import com.liferay.portal.kernel.lar.PortletDataHandler;
038    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
039    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
040    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
041    import com.liferay.portal.kernel.lar.UserIdStrategy;
042    import com.liferay.portal.kernel.log.Log;
043    import com.liferay.portal.kernel.log.LogFactoryUtil;
044    import com.liferay.portal.kernel.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    
623                    if (!layoutsImportMode.equals(
624                                    PortletDataHandlerKeys.
625                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
626    
627                            _portletImporter.readExpandoTables(portletDataContext);
628                    }
629    
630                    _portletImporter.readLocks(portletDataContext);
631                    _portletImporter.readRatingsEntries(portletDataContext);
632    
633                    // Layouts
634    
635                    List<Layout> previousLayouts = LayoutUtil.findByG_P(
636                            groupId, privateLayout);
637    
638                    // Remove layouts that were deleted from the layout set prototype
639    
640                    if (Validator.isNotNull(layoutSetPrototypeUuid) &&
641                            layoutSetPrototypeLinkEnabled) {
642    
643                            LayoutSetPrototype layoutSetPrototype =
644                                    LayoutSetPrototypeLocalServiceUtil.
645                                            getLayoutSetPrototypeByUuidAndCompanyId(
646                                                    layoutSetPrototypeUuid, companyId);
647    
648                            for (Layout layout : previousLayouts) {
649                                    String sourcePrototypeLayoutUuid =
650                                            layout.getSourcePrototypeLayoutUuid();
651    
652                                    if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
653                                            continue;
654                                    }
655    
656                                    Layout sourcePrototypeLayout = LayoutUtil.fetchByUUID_G_P(
657                                            sourcePrototypeLayoutUuid, layoutSetPrototype.getGroupId(),
658                                            true);
659    
660                                    if (sourcePrototypeLayout == null) {
661                                            LayoutLocalServiceUtil.deleteLayout(
662                                                    layout, false, serviceContext);
663                                    }
664                            }
665                    }
666    
667                    List<String> sourceLayoutsUuids = new ArrayList<String>();
668                    List<Layout> newLayouts = new ArrayList<Layout>();
669    
670                    if (_log.isDebugEnabled()) {
671                            if (_layoutElements.size() > 0) {
672                                    _log.debug("Importing layouts");
673                            }
674                    }
675    
676                    for (Element layoutElement : _layoutElements) {
677                            importLayout(
678                                    portletDataContext, sourceLayoutsUuids, newLayouts,
679                                    layoutElement);
680                    }
681    
682                    // Delete portlet data
683    
684                    Map<Long, Layout> newLayoutsMap =
685                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
686                                    Layout.class + ".layout");
687    
688                    if (deletePortletData) {
689                            if (_log.isDebugEnabled()) {
690                                    if (portletElements.size() > 0) {
691                                            _log.debug("Deleting portlet data");
692                                    }
693                            }
694    
695                            for (Element portletElement : portletElements) {
696                                    String portletId = portletElement.attributeValue("portlet-id");
697                                    long layoutId = GetterUtil.getLong(
698                                            portletElement.attributeValue("layout-id"));
699    
700                                    long plid = LayoutConstants.DEFAULT_PLID;
701    
702                                    Layout layout = newLayoutsMap.get(layoutId);
703    
704                                    if (layout != null) {
705                                            plid = layout.getPlid();
706                                    }
707    
708                                    portletDataContext.setPlid(plid);
709    
710                                    _portletImporter.deletePortletData(
711                                            portletDataContext, portletId, plid);
712                            }
713                    }
714    
715                    // Import portlets
716    
717                    if (_log.isDebugEnabled()) {
718                            if (portletElements.size() > 0) {
719                                    _log.debug("Importing portlets");
720                            }
721                    }
722    
723                    for (Element portletElement : portletElements) {
724                            String portletPath = portletElement.attributeValue("path");
725                            String portletId = portletElement.attributeValue("portlet-id");
726                            long layoutId = GetterUtil.getLong(
727                                    portletElement.attributeValue("layout-id"));
728                            long oldPlid = GetterUtil.getLong(
729                                    portletElement.attributeValue("old-plid"));
730    
731                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
732                                    portletDataContext.getCompanyId(), portletId);
733    
734                            if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
735                                    continue;
736                            }
737    
738                            Layout layout = newLayoutsMap.get(layoutId);
739    
740                            long plid = LayoutConstants.DEFAULT_PLID;
741    
742                            if (layout != null) {
743                                    plid = layout.getPlid();
744                            }
745    
746                            portletDataContext.setPlid(plid);
747                            portletDataContext.setOldPlid(oldPlid);
748    
749                            if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
750                                    PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
751                                            "portlet", portletId, manifestSummary);
752                            }
753    
754                            Document portletDocument = SAXReaderUtil.read(
755                                    portletDataContext.getZipEntryAsString(portletPath));
756    
757                            portletElement = portletDocument.getRootElement();
758    
759                            // The order of the import is important. You must always import the
760                            // portlet preferences first, then the portlet data, then the
761                            // portlet permissions. The import of the portlet data assumes that
762                            // portlet preferences already exist.
763    
764                            setPortletScope(portletDataContext, portletElement);
765    
766                            long portletPreferencesGroupId = groupId;
767    
768                            Element portletDataElement = portletElement.element("portlet-data");
769    
770                            Map<String, Boolean> importPortletControlsMap =
771                                    getImportPortletControlsMap(
772                                            companyId, portletId, parameterMap, portletDataElement,
773                                            manifestSummary);
774    
775                            try {
776                                    portletDataContext.setRootPortletId(
777                                            PortletConstants.getRootPortletId(portletId));
778    
779                                    if (layout != null) {
780                                            portletPreferencesGroupId = layout.getGroupId();
781                                    }
782    
783                                    // Portlet preferences
784    
785                                    _portletImporter.importPortletPreferences(
786                                            portletDataContext, layoutSet.getCompanyId(),
787                                            portletPreferencesGroupId, layout, null, portletElement,
788                                            false,
789                                            importPortletControlsMap.get(
790                                                    PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
791                                            importPortletControlsMap.get(
792                                                    PortletDataHandlerKeys.PORTLET_DATA),
793                                            importPortletControlsMap.get(
794                                                    PortletDataHandlerKeys.PORTLET_SETUP),
795                                            importPortletControlsMap.get(
796                                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
797    
798                                    // Portlet data
799    
800                                    if (importPortletControlsMap.get(
801                                                    PortletDataHandlerKeys.PORTLET_DATA)) {
802    
803                                            _portletImporter.importPortletData(
804                                                    portletDataContext, portletId, plid,
805                                                    portletDataElement);
806                                    }
807                            }
808                            finally {
809                                    portletDataContext.setRootPortletId(StringPool.BLANK);
810    
811                                    _portletImporter.resetPortletScope(
812                                            portletDataContext, portletPreferencesGroupId);
813                            }
814    
815                            // Portlet permissions
816    
817                            if (importPermissions) {
818                                    _permissionImporter.importPortletPermissions(
819                                            layoutCache, companyId, groupId, userId, layout,
820                                            portletElement, portletId);
821                            }
822    
823                            // Archived setups
824    
825                            _portletImporter.importPortletPreferences(
826                                    portletDataContext, layoutSet.getCompanyId(), groupId, null,
827                                    null, portletElement, false,
828                                    importPortletControlsMap.get(
829                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
830                                    importPortletControlsMap.get(
831                                            PortletDataHandlerKeys.PORTLET_DATA),
832                                    importPortletControlsMap.get(
833                                            PortletDataHandlerKeys.PORTLET_SETUP),
834                                    importPortletControlsMap.get(
835                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
836                    }
837    
838                    // Asset links
839    
840                    _portletImporter.readAssetLinks(portletDataContext);
841    
842                    // Delete missing layouts
843    
844                    if (deleteMissingLayouts) {
845                            deleteMissingLayouts(
846                                    sourceLayoutsUuids, previousLayouts, serviceContext);
847                    }
848    
849                    // Page count
850    
851                    layoutSet = LayoutSetLocalServiceUtil.updatePageCount(
852                            groupId, privateLayout);
853    
854                    // Site
855    
856                    GroupLocalServiceUtil.updateSite(groupId, true);
857    
858                    // Last merge time must be the same for merged layouts and the layout
859                    // set
860    
861                    long lastMergeTime = System.currentTimeMillis();
862    
863                    for (Layout layout : newLayouts) {
864                            boolean modifiedTypeSettingsProperties = false;
865    
866                            UnicodeProperties typeSettingsProperties =
867                                    layout.getTypeSettingsProperties();
868    
869                            // Journal article layout type
870    
871                            String articleId = typeSettingsProperties.getProperty("article-id");
872    
873                            if (Validator.isNotNull(articleId)) {
874                                    Map<String, String> articleIds =
875                                            (Map<String, String>)portletDataContext.
876                                                    getNewPrimaryKeysMap(
877                                                            JournalArticle.class + ".articleId");
878    
879                                    typeSettingsProperties.setProperty(
880                                            "article-id",
881                                            MapUtil.getString(articleIds, articleId, articleId));
882    
883                                    modifiedTypeSettingsProperties = true;
884                            }
885    
886                            // Last merge time for layout
887    
888                            if (layoutsImportMode.equals(
889                                            PortletDataHandlerKeys.
890                                                    LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
891    
892                                    typeSettingsProperties.setProperty(
893                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
894    
895                                    modifiedTypeSettingsProperties = true;
896                            }
897    
898                            if (modifiedTypeSettingsProperties) {
899                                    LayoutUtil.update(layout);
900                            }
901                    }
902    
903                    // Last merge time for layout set
904    
905                    if (layoutsImportMode.equals(
906                                    PortletDataHandlerKeys.
907                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
908    
909                            UnicodeProperties settingsProperties =
910                                    layoutSet.getSettingsProperties();
911    
912                            String mergeFailFriendlyURLLayouts =
913                                    settingsProperties.getProperty(
914                                            Sites.MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
915    
916                            if (Validator.isNull(mergeFailFriendlyURLLayouts)) {
917                                    settingsProperties.setProperty(
918                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
919    
920                                    LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
921                            }
922                    }
923    
924                    // Page priorities
925    
926                    updateLayoutPriorities(
927                            portletDataContext, _layoutElements, privateLayout);
928    
929                    if (_log.isInfoEnabled()) {
930                            _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
931                    }
932    
933                    zipReader.close();
934    
935                    ExportImportHelperUtil.reindex(portletDataContext, userId);
936            }
937    
938            protected void importLayout(
939                            PortletDataContext portletDataContext,
940                            List<String> sourceLayoutsUuids, List<Layout> newLayouts,
941                            Element layoutElement)
942                    throws Exception {
943    
944                    String action = layoutElement.attributeValue("action");
945    
946                    if (!action.equals(Constants.SKIP)) {
947                            StagedModelDataHandlerUtil.importStagedModel(
948                                    portletDataContext, layoutElement);
949    
950                            List<Layout> portletDataContextNewLayouts =
951                                    portletDataContext.getNewLayouts();
952    
953                            newLayouts.addAll(portletDataContextNewLayouts);
954    
955                            portletDataContextNewLayouts.clear();
956                    }
957    
958                    if (!action.equals(Constants.DELETE)) {
959                            sourceLayoutsUuids.add(layoutElement.attributeValue("uuid"));
960                    }
961            }
962    
963            protected void readXML(PortletDataContext portletDataContext)
964                    throws Exception {
965    
966                    if ((_rootElement != null) && (_headerElement != null) &&
967                            (_layoutsElement != null) && (_layoutElements != null)) {
968    
969                            return;
970                    }
971    
972                    String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
973    
974                    if (xml == null) {
975                            throw new LARFileException("manifest.xml not found in the LAR");
976                    }
977    
978                    try {
979                            Document document = SAXReaderUtil.read(xml);
980    
981                            _rootElement = document.getRootElement();
982    
983                            portletDataContext.setImportDataRootElement(_rootElement);
984                    }
985                    catch (Exception e) {
986                            throw new LARFileException(e);
987                    }
988    
989                    _headerElement = _rootElement.element("header");
990    
991                    _layoutsElement = portletDataContext.getImportDataGroupElement(
992                            Layout.class);
993    
994                    _layoutElements = _layoutsElement.elements();
995            }
996    
997            protected void setPortletScope(
998                    PortletDataContext portletDataContext, Element portletElement) {
999    
1000                    // Portlet data scope
1001    
1002                    String scopeLayoutUuid = GetterUtil.getString(
1003                            portletElement.attributeValue("scope-layout-uuid"));
1004                    String scopeLayoutType = GetterUtil.getString(
1005                            portletElement.attributeValue("scope-layout-type"));
1006    
1007                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
1008                    portletDataContext.setScopeType(scopeLayoutType);
1009    
1010                    // Layout scope
1011    
1012                    try {
1013                            Group scopeGroup = null;
1014    
1015                            if (scopeLayoutType.equals("company")) {
1016                                    scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
1017                                            portletDataContext.getCompanyId());
1018                            }
1019                            else if (Validator.isNotNull(scopeLayoutUuid)) {
1020                                    Layout scopeLayout =
1021                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1022                                                    scopeLayoutUuid, portletDataContext.getGroupId(),
1023                                                    portletDataContext.isPrivateLayout());
1024    
1025                                    if (scopeLayout.hasScopeGroup()) {
1026                                            scopeGroup = scopeLayout.getScopeGroup();
1027                                    }
1028                                    else {
1029                                            String name = String.valueOf(scopeLayout.getPlid());
1030    
1031                                            scopeGroup = GroupLocalServiceUtil.addGroup(
1032                                                    portletDataContext.getUserId(null),
1033                                                    GroupConstants.DEFAULT_PARENT_GROUP_ID,
1034                                                    Layout.class.getName(), scopeLayout.getPlid(),
1035                                                    GroupConstants.DEFAULT_LIVE_GROUP_ID, name, null, 0,
1036                                                    true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
1037                                                    null, false, true, null);
1038                                    }
1039    
1040                                    Group group = scopeLayout.getGroup();
1041    
1042                                    if (group.isStaged() && !group.isStagedRemotely()) {
1043                                            try {
1044                                                    boolean privateLayout = GetterUtil.getBoolean(
1045                                                            portletElement.attributeValue("private-layout"));
1046    
1047                                                    Layout oldLayout =
1048                                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1049                                                                    scopeLayoutUuid,
1050                                                                    portletDataContext.getSourceGroupId(),
1051                                                                    privateLayout);
1052    
1053                                                    Group oldScopeGroup = oldLayout.getScopeGroup();
1054    
1055                                                    if (group.isStagingGroup()) {
1056                                                            scopeGroup.setLiveGroupId(
1057                                                                    oldScopeGroup.getGroupId());
1058    
1059                                                            GroupLocalServiceUtil.updateGroup(scopeGroup);
1060                                                    }
1061                                                    else {
1062                                                            oldScopeGroup.setLiveGroupId(
1063                                                                    scopeGroup.getGroupId());
1064    
1065                                                            GroupLocalServiceUtil.updateGroup(oldScopeGroup);
1066                                                    }
1067                                            }
1068                                            catch (NoSuchLayoutException nsle) {
1069                                                    if (_log.isWarnEnabled()) {
1070                                                            _log.warn(nsle);
1071                                                    }
1072                                            }
1073                                    }
1074                            }
1075    
1076                            if (scopeGroup != null) {
1077                                    portletDataContext.setScopeGroupId(scopeGroup.getGroupId());
1078                            }
1079                    }
1080                    catch (PortalException pe) {
1081                    }
1082                    catch (Exception e) {
1083                            _log.error(e, e);
1084                    }
1085            }
1086    
1087            protected void updateLayoutPriorities(
1088                            PortletDataContext portletDataContext, List<Element> layoutElements,
1089                            boolean privateLayout)
1090                    throws SystemException {
1091    
1092                    Map<Long, Layout> layouts =
1093                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
1094                                    Layout.class + ".layout");
1095    
1096                    Map<Long, Integer> layoutPriorities = new HashMap<Long, Integer>();
1097    
1098                    int maxPriority = Integer.MIN_VALUE;
1099    
1100                    for (Element layoutElement : layoutElements) {
1101                            String action = layoutElement.attributeValue(Constants.ACTION);
1102    
1103                            if (action.equals(Constants.SKIP)) {
1104    
1105                                    // We only want to update priorites if there are no elements
1106                                    // with the SKIP action
1107    
1108                                    return;
1109                            }
1110    
1111                            if (action.equals(Constants.ADD)) {
1112                                    long layoutId = GetterUtil.getLong(
1113                                            layoutElement.attributeValue("layout-id"));
1114    
1115                                    Layout layout = layouts.get(layoutId);
1116    
1117                                    // Layout might have not been imported due to a controlled
1118                                    // error. See SitesImpl#addMergeFailFriendlyURLLayout.
1119    
1120                                    if (layout == null) {
1121                                            continue;
1122                                    }
1123    
1124                                    int layoutPriority = GetterUtil.getInteger(
1125                                            layoutElement.attributeValue("layout-priority"));
1126    
1127                                    layoutPriorities.put(layout.getPlid(), layoutPriority);
1128    
1129                                    if (maxPriority < layoutPriority) {
1130                                            maxPriority = layoutPriority;
1131                                    }
1132                            }
1133                    }
1134    
1135                    List<Layout> layoutSetLayouts = LayoutLocalServiceUtil.getLayouts(
1136                            portletDataContext.getGroupId(), privateLayout);
1137    
1138                    for (Layout layout : layoutSetLayouts) {
1139                            if (layoutPriorities.containsKey(layout.getPlid())) {
1140                                    layout.setPriority(layoutPriorities.get(layout.getPlid()));
1141                            }
1142                            else {
1143                                    layout.setPriority(++maxPriority);
1144                            }
1145    
1146                            LayoutLocalServiceUtil.updateLayout(layout);
1147                    }
1148            }
1149    
1150            protected void validateFile(PortletDataContext portletDataContext)
1151                    throws Exception {
1152    
1153                    // Build compatibility
1154    
1155                    readXML(portletDataContext);
1156    
1157                    int buildNumber = ReleaseInfo.getBuildNumber();
1158    
1159                    int importBuildNumber = GetterUtil.getInteger(
1160                            _headerElement.attributeValue("build-number"));
1161    
1162                    if (buildNumber != importBuildNumber) {
1163                            throw new LayoutImportException(
1164                                    "LAR build number " + importBuildNumber + " does not match " +
1165                                            "portal build number " + buildNumber);
1166                    }
1167    
1168                    // Type
1169    
1170                    String larType = _headerElement.attributeValue("type");
1171    
1172                    if (!larType.equals("layout-prototype") &&
1173                            !larType.equals("layout-set") &&
1174                            !larType.equals("layout-set-prototype")) {
1175    
1176                            throw new LARTypeException(larType);
1177                    }
1178    
1179                    Group group = GroupLocalServiceUtil.fetchGroup(
1180                            portletDataContext.getGroupId());
1181    
1182                    String layoutsImportMode = MapUtil.getString(
1183                            portletDataContext.getParameterMap(),
1184                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE);
1185    
1186                    if (larType.equals("layout-prototype") && !group.isLayoutPrototype() &&
1187                            !layoutsImportMode.equals(
1188                                    PortletDataHandlerKeys.
1189                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1190    
1191                            throw new LARTypeException(
1192                                    "A page template can only be imported to a page template");
1193                    }
1194    
1195                    if (larType.equals("layout-set") &&
1196                            (group.isLayoutPrototype() || group.isLayoutSetPrototype())) {
1197    
1198                            throw new LARTypeException("A site can only be imported to a site");
1199                    }
1200    
1201                    if (larType.equals("layout-set-prototype") &&
1202                            !group.isLayoutSetPrototype() &&
1203                            !layoutsImportMode.equals(
1204                                    PortletDataHandlerKeys.
1205                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1206    
1207                            throw new LARTypeException(
1208                                    "A site template can only be imported to a site template");
1209                    }
1210    
1211                    // Available locales
1212    
1213                    Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1214                            StringUtil.split(
1215                                    _headerElement.attributeValue("available-locales")));
1216    
1217                    Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1218                            portletDataContext.getScopeGroupId());
1219    
1220                    for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1221                            if (!ArrayUtil.contains(
1222                                            targetAvailableLocales, sourceAvailableLocale)) {
1223    
1224                                    LocaleException le = new LocaleException(
1225                                            LocaleException.TYPE_EXPORT_IMPORT);
1226    
1227                                    le.setSourceAvailableLocales(sourceAvailableLocales);
1228                                    le.setTargetAvailableLocales(targetAvailableLocales);
1229    
1230                                    throw le;
1231                            }
1232                    }
1233    
1234                    // Layout prototypes validity
1235    
1236                    validateLayoutPrototypes(
1237                            portletDataContext.getCompanyId(), _layoutsElement,
1238                            _layoutElements);
1239            }
1240    
1241            protected void validateLayoutPrototypes(
1242                            long companyId, Element layoutsElement,
1243                            List<Element> layoutElements)
1244                    throws Exception {
1245    
1246                    List<Tuple> missingLayoutPrototypes = new ArrayList<Tuple>();
1247    
1248                    String layoutSetPrototypeUuid = layoutsElement.attributeValue(
1249                            "layout-set-prototype-uuid");
1250    
1251                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
1252                            try {
1253                                    LayoutSetPrototypeLocalServiceUtil.
1254                                            getLayoutSetPrototypeByUuidAndCompanyId(
1255                                                    layoutSetPrototypeUuid, companyId);
1256                            }
1257                            catch (NoSuchLayoutSetPrototypeException nlspe) {
1258                                    String layoutSetPrototypeName = layoutsElement.attributeValue(
1259                                            "layout-set-prototype-name");
1260    
1261                                    missingLayoutPrototypes.add(
1262                                            new Tuple(
1263                                                    LayoutSetPrototype.class.getName(),
1264                                                    layoutSetPrototypeUuid, layoutSetPrototypeName));
1265                            }
1266                    }
1267    
1268                    for (Element layoutElement : layoutElements) {
1269                            String action = layoutElement.attributeValue("action");
1270    
1271                            if (action.equals(Constants.SKIP)) {
1272                                    continue;
1273                            }
1274    
1275                            String layoutPrototypeUuid = GetterUtil.getString(
1276                                    layoutElement.attributeValue("layout-prototype-uuid"));
1277    
1278                            if (Validator.isNotNull(layoutPrototypeUuid)) {
1279                                    try {
1280                                            LayoutPrototypeLocalServiceUtil.
1281                                                    getLayoutPrototypeByUuidAndCompanyId(
1282                                                            layoutPrototypeUuid, companyId);
1283                                    }
1284                                    catch (NoSuchLayoutPrototypeException nslpe) {
1285                                            String layoutPrototypeName = GetterUtil.getString(
1286                                                    layoutElement.attributeValue("layout-prototype-name"));
1287    
1288                                            missingLayoutPrototypes.add(
1289                                                    new Tuple(
1290                                                            LayoutPrototype.class.getName(),
1291                                                            layoutPrototypeUuid, layoutPrototypeName));
1292                                    }
1293                            }
1294                    }
1295    
1296                    if (!missingLayoutPrototypes.isEmpty()) {
1297                            throw new LayoutPrototypeException(missingLayoutPrototypes);
1298                    }
1299            }
1300    
1301            private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1302    
1303            private DeletionSystemEventImporter _deletionSystemEventImporter =
1304                    new DeletionSystemEventImporter();
1305            private Element _headerElement;
1306            private List<Element> _layoutElements;
1307            private Element _layoutsElement;
1308            private PermissionImporter _permissionImporter = new PermissionImporter();
1309            private PortletImporter _portletImporter = new PortletImporter();
1310            private Element _rootElement;
1311            private ThemeImporter _themeImporter = new ThemeImporter();
1312    
1313    }