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