001
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.language.LanguageUtil;
028 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
029 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
030 import com.liferay.portal.kernel.lar.ManifestSummary;
031 import com.liferay.portal.kernel.lar.MissingReference;
032 import com.liferay.portal.kernel.lar.MissingReferences;
033 import com.liferay.portal.kernel.lar.PortletDataContext;
034 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
035 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
036 import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
037 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
038 import com.liferay.portal.kernel.lar.UserIdStrategy;
039 import com.liferay.portal.kernel.log.Log;
040 import com.liferay.portal.kernel.log.LogFactoryUtil;
041 import com.liferay.portal.kernel.search.Indexer;
042 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
043 import com.liferay.portal.kernel.util.ArrayUtil;
044 import com.liferay.portal.kernel.util.Constants;
045 import com.liferay.portal.kernel.util.FileUtil;
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.Layout;
062 import com.liferay.portal.model.LayoutConstants;
063 import com.liferay.portal.model.LayoutPrototype;
064 import com.liferay.portal.model.LayoutSet;
065 import com.liferay.portal.model.LayoutSetPrototype;
066 import com.liferay.portal.model.Portlet;
067 import com.liferay.portal.model.User;
068 import com.liferay.portal.security.permission.PermissionCacheUtil;
069 import com.liferay.portal.service.GroupLocalServiceUtil;
070 import com.liferay.portal.service.LayoutLocalServiceUtil;
071 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
072 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
073 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
074 import com.liferay.portal.service.PortletLocalServiceUtil;
075 import com.liferay.portal.service.ServiceContext;
076 import com.liferay.portal.service.ServiceContextThreadLocal;
077 import com.liferay.portal.service.persistence.LayoutUtil;
078 import com.liferay.portal.service.persistence.UserUtil;
079 import com.liferay.portal.servlet.filters.cache.CacheUtil;
080 import com.liferay.portlet.journal.model.JournalArticle;
081 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
082 import com.liferay.portlet.sites.util.Sites;
083
084 import java.io.File;
085
086 import java.util.ArrayList;
087 import java.util.List;
088 import java.util.Locale;
089 import java.util.Map;
090
091 import org.apache.commons.lang.time.StopWatch;
092
093
106 public class LayoutImporter {
107
108 public void importLayouts(
109 long userId, long groupId, boolean privateLayout,
110 Map<String, String[]> parameterMap, File file)
111 throws Exception {
112
113 try {
114 ExportImportThreadLocal.setLayoutImportInProcess(true);
115
116 doImportLayouts(userId, groupId, privateLayout, parameterMap, file);
117 }
118 finally {
119 ExportImportThreadLocal.setLayoutImportInProcess(false);
120
121 CacheUtil.clearCache();
122 JournalContentUtil.clearCache();
123 PermissionCacheUtil.clearCache();
124 }
125 }
126
127 public MissingReferences validateFile(
128 long userId, long groupId, boolean privateLayout,
129 Map<String, String[]> parameterMap, File file)
130 throws Exception {
131
132 try {
133 ExportImportThreadLocal.setLayoutValidationInProcess(true);
134
135 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
136 groupId, privateLayout);
137
138 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
139
140 PortletDataContext portletDataContext =
141 PortletDataContextFactoryUtil.createImportPortletDataContext(
142 layoutSet.getCompanyId(), groupId, parameterMap, null,
143 zipReader);
144
145 validateFile(portletDataContext);
146
147 MissingReferences missingReferences =
148 ExportImportHelperUtil.validateMissingReferences(
149 userId, groupId, parameterMap, file);
150
151 Map<String, MissingReference> dependencyMissingReferences =
152 missingReferences.getDependencyMissingReferences();
153
154 if (!dependencyMissingReferences.isEmpty()) {
155 throw new MissingReferenceException(missingReferences);
156 }
157
158 return missingReferences;
159 }
160 finally {
161 ExportImportThreadLocal.setLayoutValidationInProcess(false);
162 }
163 }
164
165 protected void deleteMissingLayouts(
166 List<String> sourceLayoutUuids, List<Layout> previousLayouts,
167 ServiceContext serviceContext)
168 throws Exception {
169
170 if (_log.isDebugEnabled() && !sourceLayoutUuids.isEmpty()) {
171 _log.debug("Delete missing layouts");
172 }
173
174 for (Layout layout : previousLayouts) {
175 if (!sourceLayoutUuids.contains(layout.getUuid())) {
176 try {
177 LayoutLocalServiceUtil.deleteLayout(
178 layout, false, serviceContext);
179 }
180 catch (NoSuchLayoutException nsle) {
181 }
182 }
183 }
184 }
185
186 protected void doImportLayouts(
187 long userId, long groupId, boolean privateLayout,
188 Map<String, String[]> parameterMap, File file)
189 throws Exception {
190
191 boolean deleteMissingLayouts = MapUtil.getBoolean(
192 parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
193 Boolean.TRUE.booleanValue());
194 boolean deletePortletData = MapUtil.getBoolean(
195 parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
196 boolean importCategories = MapUtil.getBoolean(
197 parameterMap, PortletDataHandlerKeys.CATEGORIES);
198 boolean importPermissions = MapUtil.getBoolean(
199 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
200 boolean importLogo = MapUtil.getBoolean(
201 parameterMap, PortletDataHandlerKeys.LOGO);
202 boolean importLayoutSetSettings = MapUtil.getBoolean(
203 parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
204
205 boolean layoutSetPrototypeLinkEnabled = MapUtil.getBoolean(
206 parameterMap,
207 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED, true);
208
209 Group group = GroupLocalServiceUtil.getGroup(groupId);
210
211 if (group.isLayoutSetPrototype()) {
212 layoutSetPrototypeLinkEnabled = false;
213 }
214
215 String layoutsImportMode = MapUtil.getString(
216 parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
217 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
218 String userIdStrategy = MapUtil.getString(
219 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
220
221 if (_log.isDebugEnabled()) {
222 _log.debug("Delete portlet data " + deletePortletData);
223 _log.debug("Import categories " + importCategories);
224 _log.debug("Import permissions " + importPermissions);
225 }
226
227 StopWatch stopWatch = null;
228
229 if (_log.isInfoEnabled()) {
230 stopWatch = new StopWatch();
231
232 stopWatch.start();
233 }
234
235 LayoutCache layoutCache = new LayoutCache();
236
237 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
238 groupId, privateLayout);
239
240 long companyId = layoutSet.getCompanyId();
241
242 User user = UserUtil.findByPrimaryKey(userId);
243
244 ServiceContext serviceContext =
245 ServiceContextThreadLocal.getServiceContext();
246
247 if (serviceContext == null) {
248 serviceContext = new ServiceContext();
249
250 serviceContext.setCompanyId(companyId);
251 serviceContext.setSignedIn(false);
252 serviceContext.setUserId(userId);
253
254 ServiceContextThreadLocal.pushServiceContext(serviceContext);
255 }
256
257 UserIdStrategy strategy = _portletImporter.getUserIdStrategy(
258 user, userIdStrategy);
259
260 if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
261 ManifestSummary manifestSummary =
262 ExportImportHelperUtil.getManifestSummary(
263 userId, groupId, parameterMap, file);
264
265 PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
266 "layout", manifestSummary);
267 }
268
269 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
270
271 PortletDataContext portletDataContext =
272 PortletDataContextFactoryUtil.createImportPortletDataContext(
273 companyId, groupId, parameterMap, strategy, zipReader);
274
275 portletDataContext.setPortetDataContextListener(
276 new PortletDataContextListenerImpl(portletDataContext));
277
278 portletDataContext.setPrivateLayout(privateLayout);
279
280
281
282 validateFile(portletDataContext);
283
284
285
286 long sourceCompanyId = GetterUtil.getLong(
287 _headerElement.attributeValue("company-id"));
288
289 portletDataContext.setSourceCompanyId(sourceCompanyId);
290
291
292
293 long sourceCompanyGroupId = GetterUtil.getLong(
294 _headerElement.attributeValue("company-group-id"));
295
296 portletDataContext.setSourceCompanyGroupId(sourceCompanyGroupId);
297
298
299
300 long sourceGroupId = GetterUtil.getLong(
301 _headerElement.attributeValue("group-id"));
302
303 portletDataContext.setSourceGroupId(sourceGroupId);
304
305
306
307 long sourceUserPersonalSiteGroupId = GetterUtil.getLong(
308 _headerElement.attributeValue("user-personal-site-group-id"));
309
310 portletDataContext.setSourceUserPersonalSiteGroupId(
311 sourceUserPersonalSiteGroupId);
312
313
314
315 String layoutSetPrototypeUuid = _layoutsElement.attributeValue(
316 "layout-set-prototype-uuid");
317
318 String larType = _headerElement.attributeValue("type");
319
320 if (group.isLayoutPrototype() && larType.equals("layout-prototype")) {
321 deleteMissingLayouts = false;
322
323 LayoutPrototype layoutPrototype =
324 LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
325 group.getClassPK());
326
327 String layoutPrototypeUuid = GetterUtil.getString(
328 _headerElement.attributeValue("type-uuid"));
329
330 LayoutPrototype existingLayoutPrototype = null;
331
332 if (Validator.isNotNull(layoutPrototypeUuid)) {
333 try {
334 existingLayoutPrototype =
335 LayoutPrototypeLocalServiceUtil.
336 getLayoutPrototypeByUuidAndCompanyId(
337 layoutPrototypeUuid, companyId);
338 }
339 catch (NoSuchLayoutPrototypeException nslpe) {
340 }
341 }
342
343 if (existingLayoutPrototype == null) {
344 List<Layout> layouts =
345 LayoutLocalServiceUtil.getLayoutsByLayoutPrototypeUuid(
346 layoutPrototype.getUuid());
347
348 layoutPrototype.setUuid(layoutPrototypeUuid);
349
350 LayoutPrototypeLocalServiceUtil.updateLayoutPrototype(
351 layoutPrototype);
352
353 for (Layout layout : layouts) {
354 layout.setLayoutPrototypeUuid(layoutPrototypeUuid);
355
356 LayoutLocalServiceUtil.updateLayout(layout);
357 }
358 }
359 }
360 else if (group.isLayoutSetPrototype() &&
361 larType.equals("layout-set-prototype")) {
362
363 LayoutSetPrototype layoutSetPrototype =
364 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
365 group.getClassPK());
366
367 String importedLayoutSetPrototypeUuid = GetterUtil.getString(
368 _headerElement.attributeValue("type-uuid"));
369
370 LayoutSetPrototype existingLayoutSetPrototype = null;
371
372 if (Validator.isNotNull(importedLayoutSetPrototypeUuid)) {
373 try {
374 existingLayoutSetPrototype =
375 LayoutSetPrototypeLocalServiceUtil.
376 getLayoutSetPrototypeByUuidAndCompanyId(
377 importedLayoutSetPrototypeUuid, companyId);
378 }
379 catch (NoSuchLayoutSetPrototypeException nslspe) {
380 }
381 }
382
383 if (existingLayoutSetPrototype == null) {
384 layoutSetPrototype.setUuid(importedLayoutSetPrototypeUuid);
385
386 LayoutSetPrototypeLocalServiceUtil.updateLayoutSetPrototype(
387 layoutSetPrototype);
388 }
389 }
390 else if (larType.equals("layout-set-prototype")) {
391 layoutSetPrototypeUuid = GetterUtil.getString(
392 _headerElement.attributeValue("type-uuid"));
393 }
394
395 if (Validator.isNotNull(layoutSetPrototypeUuid)) {
396 layoutSet.setLayoutSetPrototypeUuid(layoutSetPrototypeUuid);
397 layoutSet.setLayoutSetPrototypeLinkEnabled(
398 layoutSetPrototypeLinkEnabled);
399
400 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
401 }
402
403
404
405 if (importLogo) {
406 String logoPath = _headerElement.attributeValue("logo-path");
407
408 byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
409 logoPath);
410
411 if (ArrayUtil.isNotEmpty(iconBytes)) {
412 File logo = null;
413
414 try {
415 logo = FileUtil.createTempFile(iconBytes);
416
417 LayoutSetLocalServiceUtil.updateLogo(
418 groupId, privateLayout, true, logo);
419 }
420 finally {
421 FileUtil.delete(logo);
422 }
423 }
424 else {
425 LayoutSetLocalServiceUtil.updateLogo(
426 groupId, privateLayout, false, (File)null);
427 }
428 }
429
430 _themeImporter.importTheme(portletDataContext, layoutSet);
431
432 if (importLayoutSetSettings) {
433 String settings = GetterUtil.getString(
434 _headerElement.elementText("settings"));
435
436 LayoutSetLocalServiceUtil.updateSettings(
437 groupId, privateLayout, settings);
438 }
439
440
441
442
443
444 if (importPermissions) {
445 _permissionImporter.readPortletDataPermissions(portletDataContext);
446 }
447
448 _portletImporter.readAssetCategories(portletDataContext);
449 _portletImporter.readAssetTags(portletDataContext);
450 _portletImporter.readComments(portletDataContext);
451 _portletImporter.readExpandoTables(portletDataContext);
452 _portletImporter.readLocks(portletDataContext);
453 _portletImporter.readRatingsEntries(portletDataContext);
454
455
456
457 List<Layout> previousLayouts = LayoutUtil.findByG_P(
458 groupId, privateLayout);
459
460
461
462 if (Validator.isNotNull(layoutSetPrototypeUuid) &&
463 layoutSetPrototypeLinkEnabled) {
464
465 LayoutSetPrototype layoutSetPrototype =
466 LayoutSetPrototypeLocalServiceUtil.
467 getLayoutSetPrototypeByUuidAndCompanyId(
468 layoutSetPrototypeUuid, companyId);
469
470 for (Layout layout : previousLayouts) {
471 String sourcePrototypeLayoutUuid =
472 layout.getSourcePrototypeLayoutUuid();
473
474 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
475 continue;
476 }
477
478 Layout sourcePrototypeLayout = LayoutUtil.fetchByUUID_G_P(
479 sourcePrototypeLayoutUuid, layoutSetPrototype.getGroupId(),
480 true);
481
482 if (sourcePrototypeLayout == null) {
483 LayoutLocalServiceUtil.deleteLayout(
484 layout, false, serviceContext);
485 }
486 }
487 }
488
489 List<String> sourceLayoutsUuids = new ArrayList<String>();
490 List<Layout> newLayouts = new ArrayList<Layout>();
491
492 if (_log.isDebugEnabled()) {
493 if (_layoutElements.size() > 0) {
494 _log.debug("Importing layouts");
495 }
496 }
497
498 for (Element layoutElement : _layoutElements) {
499 importLayout(
500 portletDataContext, sourceLayoutsUuids, newLayouts,
501 layoutElement);
502 }
503
504 Element portletsElement = _rootElement.element("portlets");
505
506 List<Element> portletElements = portletsElement.elements("portlet");
507
508
509
510 Map<Long, Layout> newLayoutsMap =
511 (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
512 Layout.class + ".layout");
513
514 if (deletePortletData) {
515 if (_log.isDebugEnabled()) {
516 if (portletElements.size() > 0) {
517 _log.debug("Deleting portlet data");
518 }
519 }
520
521 for (Element portletElement : portletElements) {
522 String portletId = portletElement.attributeValue("portlet-id");
523 long layoutId = GetterUtil.getLong(
524 portletElement.attributeValue("layout-id"));
525
526 Layout layout = newLayoutsMap.get(layoutId);
527
528 long plid = layout.getPlid();
529
530 portletDataContext.setPlid(plid);
531
532 _portletImporter.deletePortletData(
533 portletDataContext, portletId, plid);
534 }
535 }
536
537
538
539 if (_log.isDebugEnabled()) {
540 if (portletElements.size() > 0) {
541 _log.debug("Importing portlets");
542 }
543 }
544
545 for (Element portletElement : portletElements) {
546 String portletPath = portletElement.attributeValue("path");
547 String portletId = portletElement.attributeValue("portlet-id");
548 long layoutId = GetterUtil.getLong(
549 portletElement.attributeValue("layout-id"));
550 long oldPlid = GetterUtil.getLong(
551 portletElement.attributeValue("old-plid"));
552
553 Portlet portlet = PortletLocalServiceUtil.getPortletById(
554 portletDataContext.getCompanyId(), portletId);
555
556 if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
557 continue;
558 }
559
560 Layout layout = newLayoutsMap.get(layoutId);
561
562 long plid = LayoutConstants.DEFAULT_PLID;
563
564 if (layout != null) {
565 plid = layout.getPlid();
566 }
567
568 portletDataContext.setPlid(plid);
569 portletDataContext.setOldPlid(oldPlid);
570
571 Document portletDocument = SAXReaderUtil.read(
572 portletDataContext.getZipEntryAsString(portletPath));
573
574 portletElement = portletDocument.getRootElement();
575
576
577
578
579
580
581 _portletImporter.setPortletScope(
582 portletDataContext, portletElement);
583
584 long portletPreferencesGroupId = groupId;
585
586 Element portletDataElement = portletElement.element("portlet-data");
587
588 boolean[] importPortletControls = getImportPortletControls(
589 companyId, portletId, parameterMap, portletDataElement);
590
591 try {
592 if (layout != null) {
593 portletPreferencesGroupId = layout.getGroupId();
594 }
595
596
597
598 _portletImporter.importPortletPreferences(
599 portletDataContext, layoutSet.getCompanyId(),
600 portletPreferencesGroupId, layout, null, portletElement,
601 importPortletControls[2], importPortletControls[0],
602 importPortletControls[3], false, importPortletControls[1]);
603
604
605
606 if (importPortletControls[1]) {
607 _portletImporter.importPortletData(
608 portletDataContext, portletId, plid,
609 portletDataElement);
610 }
611 }
612 finally {
613 _portletImporter.resetPortletScope(
614 portletDataContext, portletPreferencesGroupId);
615 }
616
617
618
619 if (importPermissions) {
620 _permissionImporter.importPortletPermissions(
621 layoutCache, companyId, groupId, userId, layout,
622 portletElement, portletId);
623 }
624
625
626
627 _portletImporter.importPortletPreferences(
628 portletDataContext, layoutSet.getCompanyId(), groupId, null,
629 null, portletElement, importPortletControls[2],
630 importPortletControls[0], importPortletControls[3], false,
631 importPortletControls[1]);
632 }
633
634 if (importPermissions) {
635 if (userId > 0) {
636 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
637 User.class);
638
639 indexer.reindex(userId);
640 }
641 }
642
643
644
645 _portletImporter.readAssetLinks(portletDataContext);
646
647
648
649 if (deleteMissingLayouts) {
650 deleteMissingLayouts(
651 sourceLayoutsUuids, previousLayouts, serviceContext);
652 }
653
654
655
656 layoutSet = LayoutSetLocalServiceUtil.updatePageCount(
657 groupId, privateLayout);
658
659
660
661 GroupLocalServiceUtil.updateSite(groupId, true);
662
663
664
665
666 long lastMergeTime = System.currentTimeMillis();
667
668 for (Layout layout : newLayouts) {
669 boolean modifiedTypeSettingsProperties = false;
670
671 UnicodeProperties typeSettingsProperties =
672 layout.getTypeSettingsProperties();
673
674
675
676 String articleId = typeSettingsProperties.getProperty("article-id");
677
678 if (Validator.isNotNull(articleId)) {
679 Map<String, String> articleIds =
680 (Map<String, String>)portletDataContext.
681 getNewPrimaryKeysMap(
682 JournalArticle.class + ".articleId");
683
684 typeSettingsProperties.setProperty(
685 "article-id",
686 MapUtil.getString(articleIds, articleId, articleId));
687
688 modifiedTypeSettingsProperties = true;
689 }
690
691
692
693 if (layoutsImportMode.equals(
694 PortletDataHandlerKeys.
695 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
696
697 typeSettingsProperties.setProperty(
698 Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
699
700 modifiedTypeSettingsProperties = true;
701 }
702
703 if (modifiedTypeSettingsProperties) {
704 LayoutUtil.update(layout);
705 }
706 }
707
708
709
710 if (layoutsImportMode.equals(
711 PortletDataHandlerKeys.
712 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
713
714 UnicodeProperties settingsProperties =
715 layoutSet.getSettingsProperties();
716
717 String mergeFailFriendlyURLLayouts =
718 settingsProperties.getProperty(
719 Sites.MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
720
721 if (Validator.isNull(mergeFailFriendlyURLLayouts)) {
722 settingsProperties.setProperty(
723 Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
724
725 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
726 }
727 }
728
729
730
731 _deletionSystemEventImporter.importDeletionSystemEvents(
732 portletDataContext);
733
734 if (_log.isInfoEnabled()) {
735 _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
736 }
737
738 zipReader.close();
739 }
740
741 protected boolean[] getImportPortletControls(
742 long companyId, String portletId,
743 Map<String, String[]> parameterMap, Element portletDataElement)
744 throws Exception {
745
746 boolean importPortletConfiguration = MapUtil.getBoolean(
747 parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION);
748 boolean importPortletConfigurationAll = MapUtil.getBoolean(
749 parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL);
750 boolean importPortletData = MapUtil.getBoolean(
751 parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
752 boolean importPortletDataAll = MapUtil.getBoolean(
753 parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
754
755 if (_log.isDebugEnabled()) {
756 _log.debug("Import portlet data " + importPortletData);
757 _log.debug("Import all portlet data " + importPortletDataAll);
758 _log.debug(
759 "Import portlet configuration " + importPortletConfiguration);
760 }
761
762 boolean importCurPortletData = importPortletData;
763
764 String rootPortletId =
765 ExportImportHelperUtil.getExportableRootPortletId(
766 companyId, portletId);
767
768 if (portletDataElement == null) {
769 importCurPortletData = false;
770 }
771 else if (importPortletDataAll) {
772 importCurPortletData = true;
773 }
774 else if (rootPortletId != null) {
775 importCurPortletData =
776 importPortletData &&
777 MapUtil.getBoolean(
778 parameterMap,
779 PortletDataHandlerKeys.PORTLET_DATA +
780 StringPool.UNDERLINE + rootPortletId);
781 }
782
783 boolean importCurPortletArchivedSetups = importPortletConfiguration;
784 boolean importCurPortletSetup = importPortletConfiguration;
785 boolean importCurPortletUserPreferences = importPortletConfiguration;
786
787 if (importPortletConfigurationAll) {
788 importCurPortletArchivedSetups =
789 MapUtil.getBoolean(
790 parameterMap,
791 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS_ALL);
792 importCurPortletSetup =
793 MapUtil.getBoolean(
794 parameterMap, PortletDataHandlerKeys.PORTLET_SETUP_ALL);
795 importCurPortletUserPreferences =
796 MapUtil.getBoolean(
797 parameterMap,
798 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES_ALL);
799 }
800 else if (rootPortletId != null) {
801 boolean importCurPortletConfiguration =
802 importPortletConfiguration &&
803 MapUtil.getBoolean(
804 parameterMap,
805 PortletDataHandlerKeys.PORTLET_CONFIGURATION +
806 StringPool.UNDERLINE + rootPortletId);
807
808 importCurPortletArchivedSetups =
809 importCurPortletConfiguration &&
810 MapUtil.getBoolean(
811 parameterMap,
812 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS +
813 StringPool.UNDERLINE + rootPortletId);
814 importCurPortletSetup =
815 importCurPortletConfiguration &&
816 MapUtil.getBoolean(
817 parameterMap,
818 PortletDataHandlerKeys.PORTLET_SETUP +
819 StringPool.UNDERLINE + rootPortletId);
820 importCurPortletUserPreferences =
821 importCurPortletConfiguration &&
822 MapUtil.getBoolean(
823 parameterMap,
824 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES +
825 StringPool.UNDERLINE + rootPortletId);
826 }
827
828 return new boolean[] {
829 importCurPortletArchivedSetups, importCurPortletData,
830 importCurPortletSetup, importCurPortletUserPreferences};
831 }
832
833 protected void importLayout(
834 PortletDataContext portletDataContext,
835 List<String> sourceLayoutsUuids, List<Layout> newLayouts,
836 Element layoutElement)
837 throws Exception {
838
839 String action = layoutElement.attributeValue("action");
840
841 if (!action.equals(Constants.SKIP)) {
842 StagedModelDataHandlerUtil.importStagedModel(
843 portletDataContext, layoutElement);
844
845 List<Layout> portletDataContextNewLayouts =
846 portletDataContext.getNewLayouts();
847
848 newLayouts.addAll(portletDataContextNewLayouts);
849
850 portletDataContextNewLayouts.clear();
851 }
852
853 if (!action.equals(Constants.DELETE)) {
854 sourceLayoutsUuids.add(layoutElement.attributeValue("uuid"));
855 }
856 }
857
858 protected void readXML(PortletDataContext portletDataContext)
859 throws Exception {
860
861 if ((_rootElement != null) && (_headerElement != null) &&
862 (_layoutsElement != null) && (_layoutElements != null)) {
863
864 return;
865 }
866
867 String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
868
869 if (xml == null) {
870 throw new LARFileException("manifest.xml not found in the LAR");
871 }
872
873 try {
874 Document document = SAXReaderUtil.read(xml);
875
876 _rootElement = document.getRootElement();
877
878 portletDataContext.setImportDataRootElement(_rootElement);
879 }
880 catch (Exception e) {
881 throw new LARFileException(e);
882 }
883
884 _headerElement = _rootElement.element("header");
885
886 _layoutsElement = portletDataContext.getImportDataGroupElement(
887 Layout.class);
888
889 _layoutElements = _layoutsElement.elements();
890 }
891
892 protected void validateFile(PortletDataContext portletDataContext)
893 throws Exception {
894
895
896
897 readXML(portletDataContext);
898
899 int buildNumber = ReleaseInfo.getBuildNumber();
900
901 int importBuildNumber = GetterUtil.getInteger(
902 _headerElement.attributeValue("build-number"));
903
904 if (buildNumber != importBuildNumber) {
905 throw new LayoutImportException(
906 "LAR build number " + importBuildNumber + " does not match " +
907 "portal build number " + buildNumber);
908 }
909
910
911
912 String larType = _headerElement.attributeValue("type");
913
914 if (!larType.equals("layout-prototype") &&
915 !larType.equals("layout-set") &&
916 !larType.equals("layout-set-prototype")) {
917
918 throw new LARTypeException(larType);
919 }
920
921
922
923 Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
924 StringUtil.split(
925 _headerElement.attributeValue("available-locales")));
926
927 Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
928 portletDataContext.getScopeGroupId());
929
930 for (Locale sourceAvailableLocale : sourceAvailableLocales) {
931 if (!ArrayUtil.contains(
932 targetAvailableLocales, sourceAvailableLocale)) {
933
934 LocaleException le = new LocaleException(
935 LocaleException.TYPE_EXPORT_IMPORT);
936
937 le.setSourceAvailableLocales(sourceAvailableLocales);
938 le.setTargetAvailableLocales(targetAvailableLocales);
939
940 throw le;
941 }
942 }
943
944
945
946 validateLayoutPrototypes(
947 portletDataContext.getCompanyId(), _layoutsElement,
948 _layoutElements);
949 }
950
951 protected void validateLayoutPrototypes(
952 long companyId, Element layoutsElement,
953 List<Element> layoutElements)
954 throws Exception {
955
956 List<Tuple> missingLayoutPrototypes = new ArrayList<Tuple>();
957
958 String layoutSetPrototypeUuid = layoutsElement.attributeValue(
959 "layout-set-prototype-uuid");
960
961 if (Validator.isNotNull(layoutSetPrototypeUuid)) {
962 try {
963 LayoutSetPrototypeLocalServiceUtil.
964 getLayoutSetPrototypeByUuidAndCompanyId(
965 layoutSetPrototypeUuid, companyId);
966 }
967 catch (NoSuchLayoutSetPrototypeException nlspe) {
968 String layoutSetPrototypeName = layoutsElement.attributeValue(
969 "layout-set-prototype-name");
970
971 missingLayoutPrototypes.add(
972 new Tuple(
973 LayoutSetPrototype.class.getName(),
974 layoutSetPrototypeUuid, layoutSetPrototypeName));
975 }
976 }
977
978 for (Element layoutElement : layoutElements) {
979 String action = layoutElement.attributeValue("action");
980
981 if (action.equals(Constants.SKIP)) {
982 continue;
983 }
984
985 String layoutPrototypeUuid = GetterUtil.getString(
986 layoutElement.attributeValue("layout-prototype-uuid"));
987
988 if (Validator.isNotNull(layoutPrototypeUuid)) {
989 try {
990 LayoutPrototypeLocalServiceUtil.
991 getLayoutPrototypeByUuidAndCompanyId(
992 layoutPrototypeUuid, companyId);
993 }
994 catch (NoSuchLayoutPrototypeException nslpe) {
995 String layoutPrototypeName = GetterUtil.getString(
996 layoutElement.attributeValue("layout-prototype-name"));
997
998 missingLayoutPrototypes.add(
999 new Tuple(
1000 LayoutPrototype.class.getName(),
1001 layoutPrototypeUuid, layoutPrototypeName));
1002 }
1003 }
1004 }
1005
1006 if (!missingLayoutPrototypes.isEmpty()) {
1007 throw new LayoutPrototypeException(missingLayoutPrototypes);
1008 }
1009 }
1010
1011 private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1012
1013 private DeletionSystemEventImporter _deletionSystemEventImporter =
1014 new DeletionSystemEventImporter();
1015 private Element _headerElement;
1016 private List<Element> _layoutElements;
1017 private Element _layoutsElement;
1018 private PermissionImporter _permissionImporter = new PermissionImporter();
1019 private PortletImporter _portletImporter = new PortletImporter();
1020 private Element _rootElement;
1021 private ThemeImporter _themeImporter = new ThemeImporter();
1022
1023 }