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