001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.counter.service.CounterLocalServiceUtil;
018 import com.liferay.portal.LARFileException;
019 import com.liferay.portal.LARTypeException;
020 import com.liferay.portal.LayoutImportException;
021 import com.liferay.portal.LayoutPrototypeException;
022 import com.liferay.portal.LocaleException;
023 import com.liferay.portal.NoSuchLayoutException;
024 import com.liferay.portal.NoSuchLayoutPrototypeException;
025 import com.liferay.portal.NoSuchLayoutSetPrototypeException;
026 import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
027 import com.liferay.portal.kernel.cluster.ClusterRequest;
028 import com.liferay.portal.kernel.exception.PortalException;
029 import com.liferay.portal.kernel.exception.SystemException;
030 import com.liferay.portal.kernel.language.LanguageUtil;
031 import com.liferay.portal.kernel.lar.ImportExportThreadLocal;
032 import com.liferay.portal.kernel.lar.PortletDataContext;
033 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
034 import com.liferay.portal.kernel.lar.UserIdStrategy;
035 import com.liferay.portal.kernel.log.Log;
036 import com.liferay.portal.kernel.log.LogFactoryUtil;
037 import com.liferay.portal.kernel.search.Indexer;
038 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
039 import com.liferay.portal.kernel.staging.StagingUtil;
040 import com.liferay.portal.kernel.util.ArrayUtil;
041 import com.liferay.portal.kernel.util.CharPool;
042 import com.liferay.portal.kernel.util.FileUtil;
043 import com.liferay.portal.kernel.util.GetterUtil;
044 import com.liferay.portal.kernel.util.LocaleUtil;
045 import com.liferay.portal.kernel.util.MapUtil;
046 import com.liferay.portal.kernel.util.MethodHandler;
047 import com.liferay.portal.kernel.util.MethodKey;
048 import com.liferay.portal.kernel.util.ReleaseInfo;
049 import com.liferay.portal.kernel.util.StringBundler;
050 import com.liferay.portal.kernel.util.StringPool;
051 import com.liferay.portal.kernel.util.StringUtil;
052 import com.liferay.portal.kernel.util.Time;
053 import com.liferay.portal.kernel.util.Tuple;
054 import com.liferay.portal.kernel.util.UnicodeProperties;
055 import com.liferay.portal.kernel.util.Validator;
056 import com.liferay.portal.kernel.xml.Attribute;
057 import com.liferay.portal.kernel.xml.Document;
058 import com.liferay.portal.kernel.xml.Element;
059 import com.liferay.portal.kernel.xml.Node;
060 import com.liferay.portal.kernel.xml.SAXReaderUtil;
061 import com.liferay.portal.kernel.zip.ZipReader;
062 import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
063 import com.liferay.portal.model.Group;
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.LayoutTemplate;
070 import com.liferay.portal.model.LayoutTypePortlet;
071 import com.liferay.portal.model.LayoutTypePortletConstants;
072 import com.liferay.portal.model.Portlet;
073 import com.liferay.portal.model.PortletConstants;
074 import com.liferay.portal.model.ResourceConstants;
075 import com.liferay.portal.model.Role;
076 import com.liferay.portal.model.RoleConstants;
077 import com.liferay.portal.model.User;
078 import com.liferay.portal.model.impl.ColorSchemeImpl;
079 import com.liferay.portal.security.permission.ActionKeys;
080 import com.liferay.portal.security.permission.PermissionCacheUtil;
081 import com.liferay.portal.service.GroupLocalServiceUtil;
082 import com.liferay.portal.service.ImageLocalServiceUtil;
083 import com.liferay.portal.service.LayoutLocalServiceUtil;
084 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
085 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
086 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
087 import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
088 import com.liferay.portal.service.PortletLocalServiceUtil;
089 import com.liferay.portal.service.ResourceLocalServiceUtil;
090 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
091 import com.liferay.portal.service.RoleLocalServiceUtil;
092 import com.liferay.portal.service.ServiceContext;
093 import com.liferay.portal.service.ServiceContextThreadLocal;
094 import com.liferay.portal.service.persistence.LayoutUtil;
095 import com.liferay.portal.service.persistence.UserUtil;
096 import com.liferay.portal.servlet.filters.cache.CacheUtil;
097 import com.liferay.portal.theme.ThemeLoader;
098 import com.liferay.portal.theme.ThemeLoaderFactory;
099 import com.liferay.portal.util.PortalUtil;
100 import com.liferay.portal.util.PortletKeys;
101 import com.liferay.portal.util.PropsValues;
102 import com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl;
103 import com.liferay.portlet.journal.model.JournalArticle;
104 import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
105 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
106 import com.liferay.portlet.sites.util.SitesUtil;
107
108 import java.io.File;
109 import java.io.IOException;
110 import java.io.InputStream;
111
112 import java.util.ArrayList;
113 import java.util.Date;
114 import java.util.HashSet;
115 import java.util.List;
116 import java.util.Locale;
117 import java.util.Map;
118 import java.util.Set;
119
120 import org.apache.commons.lang.time.StopWatch;
121
122
135 public class LayoutImporter {
136
137 public void importLayouts(
138 long userId, long groupId, boolean privateLayout,
139 Map<String, String[]> parameterMap, File file)
140 throws Exception {
141
142 try {
143 ImportExportThreadLocal.setLayoutImportInProcess(true);
144
145 doImportLayouts(userId, groupId, privateLayout, parameterMap, file);
146 }
147 finally {
148 ImportExportThreadLocal.setLayoutImportInProcess(false);
149
150 CacheUtil.clearCache();
151 JournalContentUtil.clearCache();
152 PermissionCacheUtil.clearCache();
153 }
154 }
155
156 protected String[] appendPortletIds(
157 String[] portletIds, String[] newPortletIds, String portletsMergeMode) {
158
159 for (String portletId : newPortletIds) {
160 if (ArrayUtil.contains(portletIds, portletId)) {
161 continue;
162 }
163
164 if (portletsMergeMode.equals(
165 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM)) {
166
167 portletIds = ArrayUtil.append(portletIds, portletId);
168 }
169 else {
170 portletIds = ArrayUtil.append(
171 new String[] {portletId}, portletIds);
172 }
173 }
174
175 return portletIds;
176 }
177
178 protected void deleteMissingLayouts(
179 long groupId, boolean privateLayout, List<Layout> newLayouts,
180 List<Layout> previousLayouts, ServiceContext serviceContext)
181 throws Exception {
182
183
184
185 Set<Long> existingLayoutIds = new HashSet<Long>();
186
187 Group group = GroupLocalServiceUtil.getGroup(groupId);
188
189 if (group.hasStagingGroup()) {
190 Group stagingGroup = group.getStagingGroup();
191
192 if (stagingGroup.hasPrivateLayouts() ||
193 stagingGroup.hasPublicLayouts()) {
194
195 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
196 stagingGroup.getGroupId(), privateLayout);
197
198 for (Layout layout : layouts) {
199 existingLayoutIds.add(layout.getLayoutId());
200 }
201 }
202 }
203 else {
204 for (Layout layout : newLayouts) {
205 existingLayoutIds.add(layout.getLayoutId());
206 }
207 }
208
209 if (_log.isDebugEnabled() && !existingLayoutIds.isEmpty()) {
210 _log.debug("Delete missing layouts");
211 }
212
213 for (Layout layout : previousLayouts) {
214 if (!existingLayoutIds.contains(layout.getLayoutId())) {
215 try {
216 LayoutLocalServiceUtil.deleteLayout(
217 layout, privateLayout, serviceContext);
218 }
219 catch (NoSuchLayoutException nsle) {
220 }
221 }
222 }
223 }
224
225 protected void doImportLayouts(
226 long userId, long groupId, boolean privateLayout,
227 Map<String, String[]> parameterMap, File file)
228 throws Exception {
229
230 boolean deleteMissingLayouts = MapUtil.getBoolean(
231 parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
232 Boolean.TRUE.booleanValue());
233 boolean deletePortletData = MapUtil.getBoolean(
234 parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
235 boolean importCategories = MapUtil.getBoolean(
236 parameterMap, PortletDataHandlerKeys.CATEGORIES);
237 boolean importPermissions = MapUtil.getBoolean(
238 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
239 boolean importPublicLayoutPermissions = MapUtil.getBoolean(
240 parameterMap, PortletDataHandlerKeys.PUBLIC_LAYOUT_PERMISSIONS);
241 boolean importPortletData = MapUtil.getBoolean(
242 parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
243 boolean importPortletSetup = MapUtil.getBoolean(
244 parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
245 boolean importPortletArchivedSetups = MapUtil.getBoolean(
246 parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
247 boolean importPortletUserPreferences = MapUtil.getBoolean(
248 parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
249 boolean importTheme = MapUtil.getBoolean(
250 parameterMap, PortletDataHandlerKeys.THEME);
251 boolean importThemeSettings = MapUtil.getBoolean(
252 parameterMap, PortletDataHandlerKeys.THEME_REFERENCE);
253 boolean importLogo = MapUtil.getBoolean(
254 parameterMap, PortletDataHandlerKeys.LOGO);
255 boolean importLayoutSetSettings = MapUtil.getBoolean(
256 parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
257
258 boolean layoutSetPrototypeLinkEnabled = MapUtil.getBoolean(
259 parameterMap,
260 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED, true);
261
262 Group group = GroupLocalServiceUtil.getGroup(groupId);
263
264 if (group.isLayoutSetPrototype()) {
265 layoutSetPrototypeLinkEnabled = false;
266 }
267
268
269
270 String layoutsImportMode = MapUtil.getString(
271 parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
272 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
273 String portletsMergeMode = MapUtil.getString(
274 parameterMap, PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
275 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE);
276 String userIdStrategy = MapUtil.getString(
277 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
278
279 if (_log.isDebugEnabled()) {
280 _log.debug("Delete portlet data " + deletePortletData);
281 _log.debug("Import categories " + importCategories);
282 _log.debug("Import permissions " + importPermissions);
283 _log.debug("Import portlet data " + importPortletData);
284 _log.debug("Import portlet setup " + importPortletSetup);
285 _log.debug(
286 "Import portlet archived setups " +
287 importPortletArchivedSetups);
288 _log.debug(
289 "Import portlet user preferences " +
290 importPortletUserPreferences);
291 _log.debug("Import theme " + importTheme);
292 }
293
294 StopWatch stopWatch = null;
295
296 if (_log.isInfoEnabled()) {
297 stopWatch = new StopWatch();
298
299 stopWatch.start();
300 }
301
302 LayoutCache layoutCache = new LayoutCache();
303
304 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
305 groupId, privateLayout);
306
307 long companyId = layoutSet.getCompanyId();
308
309 User user = UserUtil.findByPrimaryKey(userId);
310
311 UserIdStrategy strategy = _portletImporter.getUserIdStrategy(
312 user, userIdStrategy);
313
314 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
315
316 PortletDataContext portletDataContext = new PortletDataContextImpl(
317 companyId, groupId, parameterMap, new HashSet<String>(), strategy,
318 zipReader);
319
320 portletDataContext.setPortetDataContextListener(
321 new PortletDataContextListenerImpl(portletDataContext));
322
323 portletDataContext.setPrivateLayout(privateLayout);
324
325
326
327 Element rootElement = null;
328 InputStream themeZip = null;
329
330
331
332 String xml = portletDataContext.getZipEntryAsString("/manifest.xml");
333
334 if (xml == null) {
335 throw new LARFileException("manifest.xml not found in the LAR");
336 }
337
338 try {
339 Document document = SAXReaderUtil.read(xml);
340
341 rootElement = document.getRootElement();
342 }
343 catch (Exception e) {
344 throw new LARFileException(e);
345 }
346
347
348
349 Element headerElement = rootElement.element("header");
350
351 int buildNumber = ReleaseInfo.getBuildNumber();
352
353 int importBuildNumber = GetterUtil.getInteger(
354 headerElement.attributeValue("build-number"));
355
356 if (buildNumber != importBuildNumber) {
357 throw new LayoutImportException(
358 "LAR build number " + importBuildNumber + " does not match " +
359 "portal build number " + buildNumber);
360 }
361
362
363
364 String larType = headerElement.attributeValue("type");
365
366 if (!larType.equals("layout-prototype") &&
367 !larType.equals("layout-set") &&
368 !larType.equals("layout-set-prototype")) {
369
370 throw new LARTypeException(
371 "Invalid type of LAR file (" + larType + ")");
372 }
373
374
375
376 Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
377 StringUtil.split(
378 headerElement.attributeValue("available-locales")));
379
380 Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales();
381
382 for (Locale sourceAvailableLocale : sourceAvailableLocales) {
383 if (!ArrayUtil.contains(
384 targetAvailableLocales, sourceAvailableLocale)) {
385
386 LocaleException le = new LocaleException();
387
388 le.setSourceAvailableLocales(sourceAvailableLocales);
389 le.setTargetAvailableLocales(targetAvailableLocales);
390
391 throw le;
392 }
393 }
394
395
396
397 Element layoutsElement = rootElement.element("layouts");
398
399 List<Element> layoutElements = layoutsElement.elements("layout");
400
401 validateLayoutPrototypes(companyId, layoutsElement, layoutElements);
402
403
404
405 long sourceGroupId = GetterUtil.getLong(
406 headerElement.attributeValue("group-id"));
407
408 portletDataContext.setSourceGroupId(sourceGroupId);
409
410
411
412 String layoutSetPrototypeUuid = layoutsElement.attributeValue(
413 "layout-set-prototype-uuid");
414
415 if (group.isLayoutPrototype() && larType.equals("layout-prototype")) {
416 deleteMissingLayouts = false;
417
418 LayoutPrototype layoutPrototype =
419 LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
420 group.getClassPK());
421
422 String layoutPrototypeUuid = GetterUtil.getString(
423 headerElement.attributeValue("type-uuid"));
424
425 LayoutPrototype existingLayoutPrototype = null;
426
427 if (Validator.isNotNull(layoutPrototypeUuid)) {
428 try {
429 existingLayoutPrototype =
430 LayoutPrototypeLocalServiceUtil.
431 getLayoutPrototypeByUuidAndCompanyId(
432 layoutPrototypeUuid, companyId);
433 }
434 catch (NoSuchLayoutPrototypeException nslpe) {
435 }
436 }
437
438 if (existingLayoutPrototype == null) {
439 layoutPrototype.setUuid(layoutPrototypeUuid);
440
441 LayoutPrototypeLocalServiceUtil.updateLayoutPrototype(
442 layoutPrototype);
443 }
444 }
445 else if (group.isLayoutSetPrototype() &&
446 larType.equals("layout-set-prototype")) {
447
448 LayoutSetPrototype layoutSetPrototype =
449 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
450 group.getClassPK());
451
452 String importedLayoutSetPrototypeUuid = GetterUtil.getString(
453 headerElement.attributeValue("type-uuid"));
454
455 LayoutSetPrototype existingLayoutSetPrototype = null;
456
457 if (Validator.isNotNull(importedLayoutSetPrototypeUuid)) {
458 try {
459 existingLayoutSetPrototype =
460 LayoutSetPrototypeLocalServiceUtil.
461 getLayoutSetPrototypeByUuidAndCompanyId(
462 importedLayoutSetPrototypeUuid, companyId);
463 }
464 catch (NoSuchLayoutSetPrototypeException nslspe) {
465 }
466 }
467
468 if (existingLayoutSetPrototype == null) {
469 layoutSetPrototype.setUuid(importedLayoutSetPrototypeUuid);
470
471 LayoutSetPrototypeLocalServiceUtil.updateLayoutSetPrototype(
472 layoutSetPrototype);
473 }
474 }
475 else if (larType.equals("layout-set-prototype")) {
476 layoutSetPrototypeUuid = GetterUtil.getString(
477 headerElement.attributeValue("type-uuid"));
478 }
479
480 ServiceContext serviceContext =
481 ServiceContextThreadLocal.getServiceContext();
482
483 if (Validator.isNotNull(layoutSetPrototypeUuid)) {
484 layoutSet.setLayoutSetPrototypeUuid(layoutSetPrototypeUuid);
485 layoutSet.setLayoutSetPrototypeLinkEnabled(
486 layoutSetPrototypeLinkEnabled);
487
488 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
489 }
490
491
492
493 if (importTheme) {
494 themeZip = portletDataContext.getZipEntryAsInputStream("theme.zip");
495 }
496
497
498
499 String themeId = layoutSet.getThemeId();
500 String colorSchemeId = layoutSet.getColorSchemeId();
501
502 if (importThemeSettings) {
503 Attribute themeIdAttribute = headerElement.attribute("theme-id");
504
505 if (themeIdAttribute != null) {
506 themeId = themeIdAttribute.getValue();
507 }
508
509 Attribute colorSchemeIdAttribute = headerElement.attribute(
510 "color-scheme-id");
511
512 if (colorSchemeIdAttribute != null) {
513 colorSchemeId = colorSchemeIdAttribute.getValue();
514 }
515 }
516
517 if (importLogo) {
518 String logoPath = headerElement.attributeValue("logo-path");
519
520 byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
521 logoPath);
522
523 if ((iconBytes != null) && (iconBytes.length > 0)) {
524 File logo = FileUtil.createTempFile(iconBytes);
525
526 LayoutSetLocalServiceUtil.updateLogo(
527 groupId, privateLayout, true, logo);
528 }
529 else {
530 LayoutSetLocalServiceUtil.updateLogo(
531 groupId, privateLayout, false, (File) null);
532 }
533 }
534
535 if (importLayoutSetSettings) {
536 String settings = GetterUtil.getString(
537 headerElement.elementText("settings"));
538
539 LayoutSetLocalServiceUtil.updateSettings(
540 groupId, privateLayout, settings);
541 }
542
543 String css = GetterUtil.getString(headerElement.elementText("css"));
544
545 if (themeZip != null) {
546 String importThemeId = importTheme(layoutSet, themeZip);
547
548 if (importThemeId != null) {
549 themeId = importThemeId;
550 colorSchemeId =
551 ColorSchemeImpl.getDefaultRegularColorSchemeId();
552 }
553
554 if (_log.isDebugEnabled()) {
555 _log.debug(
556 "Importing theme takes " + stopWatch.getTime() + " ms");
557 }
558 }
559
560 boolean wapTheme = false;
561
562 LayoutSetLocalServiceUtil.updateLookAndFeel(
563 groupId, privateLayout, themeId, colorSchemeId, css, wapTheme);
564
565
566
567
568
569 if (importPermissions) {
570 _permissionImporter.readPortletDataPermissions(portletDataContext);
571 }
572
573 if (importCategories || group.isCompany()) {
574 _portletImporter.readAssetCategories(portletDataContext);
575 }
576
577 _portletImporter.readAssetTags(portletDataContext);
578 _portletImporter.readComments(portletDataContext);
579 _portletImporter.readExpandoTables(portletDataContext);
580 _portletImporter.readLocks(portletDataContext);
581 _portletImporter.readRatingsEntries(portletDataContext);
582
583
584
585 List<Layout> previousLayouts = LayoutUtil.findByG_P(
586 groupId, privateLayout);
587
588
589
590 if (Validator.isNotNull(layoutSetPrototypeUuid) &&
591 layoutSetPrototypeLinkEnabled) {
592
593 LayoutSetPrototype layoutSetPrototype =
594 LayoutSetPrototypeLocalServiceUtil.
595 getLayoutSetPrototypeByUuidAndCompanyId(
596 layoutSetPrototypeUuid, companyId);
597
598 Group layoutSetPrototypeGroup = layoutSetPrototype.getGroup();
599
600 for (Layout layout : previousLayouts) {
601 String sourcePrototypeLayoutUuid =
602 layout.getSourcePrototypeLayoutUuid();
603
604 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
605 continue;
606 }
607
608 Layout sourcePrototypeLayout = LayoutUtil.fetchByUUID_G(
609 sourcePrototypeLayoutUuid,
610 layoutSetPrototypeGroup.getGroupId());
611
612 if (sourcePrototypeLayout == null) {
613 LayoutLocalServiceUtil.deleteLayout(
614 layout, false, serviceContext);
615 }
616 }
617 }
618
619 List<Layout> newLayouts = new ArrayList<Layout>();
620
621 Map<Long, Layout> newLayoutsMap =
622 (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
623 Layout.class);
624
625 if (_log.isDebugEnabled()) {
626 if (layoutElements.size() > 0) {
627 _log.debug("Importing layouts");
628 }
629 }
630
631 for (Element layoutElement : layoutElements) {
632 importLayout(
633 portletDataContext, user, layoutCache, previousLayouts,
634 newLayouts, newLayoutsMap, portletsMergeMode, themeId,
635 colorSchemeId, layoutsImportMode, privateLayout,
636 importPermissions, importPublicLayoutPermissions,
637 importThemeSettings, rootElement, layoutElement);
638 }
639
640 Element portletsElement = rootElement.element("portlets");
641
642 List<Element> portletElements = portletsElement.elements("portlet");
643
644
645
646 if (deletePortletData) {
647 if (_log.isDebugEnabled()) {
648 if (portletElements.size() > 0) {
649 _log.debug("Deleting portlet data");
650 }
651 }
652
653 for (Element portletElement : portletElements) {
654 String portletId = portletElement.attributeValue("portlet-id");
655 long layoutId = GetterUtil.getLong(
656 portletElement.attributeValue("layout-id"));
657 long plid = newLayoutsMap.get(layoutId).getPlid();
658
659 portletDataContext.setPlid(plid);
660
661 _portletImporter.deletePortletData(
662 portletDataContext, portletId, plid);
663 }
664 }
665
666
667
668 if (_log.isDebugEnabled()) {
669 if (portletElements.size() > 0) {
670 _log.debug("Importing portlets");
671 }
672 }
673
674 for (Element portletElement : portletElements) {
675 String portletPath = portletElement.attributeValue("path");
676 String portletId = portletElement.attributeValue("portlet-id");
677 long layoutId = GetterUtil.getLong(
678 portletElement.attributeValue("layout-id"));
679 long oldPlid = GetterUtil.getLong(
680 portletElement.attributeValue("old-plid"));
681
682 Portlet portlet = PortletLocalServiceUtil.getPortletById(
683 portletDataContext.getCompanyId(), portletId);
684
685 if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
686 continue;
687 }
688
689 Layout layout = newLayoutsMap.get(layoutId);
690
691 long plid = LayoutConstants.DEFAULT_PLID;
692
693 if (layout != null) {
694 plid = layout.getPlid();
695 }
696
697 layout = LayoutUtil.fetchByPrimaryKey(plid);
698
699 if ((layout == null) && !group.isCompany()) {
700 continue;
701 }
702
703 portletDataContext.setPlid(plid);
704 portletDataContext.setOldPlid(oldPlid);
705
706 Document portletDocument = SAXReaderUtil.read(
707 portletDataContext.getZipEntryAsString(portletPath));
708
709 portletElement = portletDocument.getRootElement();
710
711
712
713
714
715
716 _portletImporter.setPortletScope(
717 portletDataContext, portletElement);
718
719 long portletPreferencesGroupId = groupId;
720
721 Element portletDataElement = portletElement.element("portlet-data");
722
723 boolean importData =
724 importPortletData && (portletDataElement != null);
725
726 try {
727 if ((layout != null) && !group.isCompany()) {
728 portletPreferencesGroupId = layout.getGroupId();
729 }
730
731
732
733 _portletImporter.importPortletPreferences(
734 portletDataContext, layoutSet.getCompanyId(),
735 portletPreferencesGroupId, layout, null, portletElement,
736 importPortletSetup, importPortletArchivedSetups,
737 importPortletUserPreferences, false, importData);
738
739
740
741 if (importData) {
742 _portletImporter.importPortletData(
743 portletDataContext, portletId, plid,
744 portletDataElement);
745 }
746 }
747 finally {
748 _portletImporter.resetPortletScope(
749 portletDataContext, portletPreferencesGroupId);
750 }
751
752
753
754 if (importPermissions) {
755 _permissionImporter.importPortletPermissions(
756 layoutCache, companyId, groupId, userId, layout,
757 portletElement, portletId);
758 }
759
760
761
762 _portletImporter.importPortletPreferences(
763 portletDataContext, layoutSet.getCompanyId(), groupId, null,
764 null, portletElement, importPortletSetup,
765 importPortletArchivedSetups, importPortletUserPreferences,
766 false, importData);
767 }
768
769 if (importPermissions) {
770 if (userId > 0) {
771 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
772 User.class);
773
774 indexer.reindex(userId);
775 }
776 }
777
778
779
780 _portletImporter.readAssetLinks(portletDataContext);
781
782
783
784 if (deleteMissingLayouts) {
785 deleteMissingLayouts(
786 groupId, privateLayout, newLayouts, previousLayouts,
787 serviceContext);
788 }
789
790
791
792 LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
793
794 if (_log.isInfoEnabled()) {
795 _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
796 }
797
798
799
800 GroupLocalServiceUtil.updateSite(groupId, true);
801
802
803
804 for (Layout layout : newLayouts) {
805 UnicodeProperties typeSettingsProperties =
806 layout.getTypeSettingsProperties();
807
808 String articleId = typeSettingsProperties.getProperty("article-id");
809
810 if (Validator.isNotNull(articleId)) {
811 Map<String, String> articleIds =
812 (Map<String, String>)portletDataContext.
813 getNewPrimaryKeysMap(
814 JournalArticle.class + ".articleId");
815
816 typeSettingsProperties.setProperty(
817 "article-id",
818 MapUtil.getString(articleIds, articleId, articleId));
819
820 LayoutUtil.update(layout);
821 }
822 }
823
824 zipReader.close();
825 }
826
827 protected void fixTypeSettings(Layout layout) throws Exception {
828 if (!layout.isTypeURL()) {
829 return;
830 }
831
832 UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
833
834 String url = GetterUtil.getString(typeSettings.getProperty("url"));
835
836 String friendlyURLPrivateGroupPath =
837 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
838 String friendlyURLPrivateUserPath =
839 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
840 String friendlyURLPublicPath =
841 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
842
843 if (!url.startsWith(friendlyURLPrivateGroupPath) &&
844 !url.startsWith(friendlyURLPrivateUserPath) &&
845 !url.startsWith(friendlyURLPublicPath)) {
846
847 return;
848 }
849
850 int x = url.indexOf(CharPool.SLASH, 1);
851
852 if (x == -1) {
853 return;
854 }
855
856 int y = url.indexOf(CharPool.SLASH, x + 1);
857
858 if (y == -1) {
859 return;
860 }
861
862 String friendlyURL = url.substring(x, y);
863
864 if (!friendlyURL.equals(LayoutExporter.SAME_GROUP_FRIENDLY_URL)) {
865 return;
866 }
867
868 Group group = layout.getGroup();
869
870 typeSettings.setProperty(
871 "url",
872 url.substring(0, x) + group.getFriendlyURL() + url.substring(y));
873 }
874
875 protected String getLayoutSetPrototype(
876 PortletDataContext portletDataContext, String layoutSetPrototypeUuid) {
877
878 StringBundler sb = new StringBundler(3);
879
880 sb.append(portletDataContext.getSourceRootPath());
881 sb.append("/layout-set-prototype/");
882 sb.append(layoutSetPrototypeUuid);
883
884 return sb.toString();
885 }
886
887 protected void importJournalArticle(
888 PortletDataContext portletDataContext, Layout layout,
889 Element layoutElement)
890 throws Exception {
891
892 UnicodeProperties typeSettingsProperties =
893 layout.getTypeSettingsProperties();
894
895 String articleId = typeSettingsProperties.getProperty(
896 "article-id", StringPool.BLANK);
897
898 if (Validator.isNull(articleId)) {
899 return;
900 }
901
902 JournalPortletDataHandlerImpl.importReferencedData(
903 portletDataContext, layoutElement);
904
905 Element structureElement = layoutElement.element("structure");
906
907 if (structureElement != null) {
908 JournalPortletDataHandlerImpl.importStructure(
909 portletDataContext, structureElement);
910 }
911
912 Element templateElement = layoutElement.element("template");
913
914 if (templateElement != null) {
915 JournalPortletDataHandlerImpl.importTemplate(
916 portletDataContext, templateElement);
917 }
918
919 Element articleElement = layoutElement.element("article");
920
921 if (articleElement != null) {
922 JournalPortletDataHandlerImpl.importArticle(
923 portletDataContext, articleElement);
924 }
925
926 Map<String, String> articleIds =
927 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
928 JournalArticle.class + ".articleId");
929
930 articleId = MapUtil.getString(articleIds, articleId, articleId);
931
932 typeSettingsProperties.setProperty("article-id", articleId);
933
934 JournalContentSearchLocalServiceUtil.updateContentSearch(
935 portletDataContext.getScopeGroupId(), layout.isPrivateLayout(),
936 layout.getLayoutId(), StringPool.BLANK, articleId, true);
937 }
938
939 protected void importLayout(
940 PortletDataContext portletDataContext, User user,
941 LayoutCache layoutCache, List<Layout> previousLayouts,
942 List<Layout> newLayouts, Map<Long, Layout> newLayoutsMap,
943 String portletsMergeMode, String themeId, String colorSchemeId,
944 String layoutsImportMode, boolean privateLayout,
945 boolean importPermissions, boolean importPublicLayoutPermissions,
946 boolean importThemeSettings, Element rootElement,
947 Element layoutElement)
948 throws Exception {
949
950 long groupId = portletDataContext.getGroupId();
951
952 String layoutUuid = GetterUtil.getString(
953 layoutElement.attributeValue("layout-uuid"));
954
955 long layoutId = GetterUtil.getInteger(
956 layoutElement.attributeValue("layout-id"));
957
958 long oldLayoutId = layoutId;
959
960 boolean deleteLayout = GetterUtil.getBoolean(
961 layoutElement.attributeValue("delete"));
962
963 if (deleteLayout) {
964 Layout layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
965 layoutUuid, groupId);
966
967 if (layout != null) {
968 newLayoutsMap.put(oldLayoutId, layout);
969
970 ServiceContext serviceContext =
971 ServiceContextThreadLocal.getServiceContext();
972
973 LayoutLocalServiceUtil.deleteLayout(
974 layout, false, serviceContext);
975 }
976
977 return;
978 }
979
980 String path = layoutElement.attributeValue("path");
981
982 if (!portletDataContext.isPathNotProcessed(path)) {
983 return;
984 }
985
986 Layout layout = (Layout)portletDataContext.getZipEntryAsObject(path);
987
988 Layout existingLayout = null;
989 Layout importedLayout = null;
990
991 String friendlyURL = layout.getFriendlyURL();
992
993 if (layoutsImportMode.equals(
994 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_ADD_AS_NEW)) {
995
996 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
997 groupId, privateLayout);
998 friendlyURL = StringPool.SLASH + layoutId;
999 }
1000 else if (layoutsImportMode.equals(
1001 PortletDataHandlerKeys.
1002 LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME)) {
1003
1004 Locale locale = LocaleUtil.getDefault();
1005
1006 String localizedName = layout.getName(locale);
1007
1008 for (Layout curLayout : previousLayouts) {
1009 if (localizedName.equals(curLayout.getName(locale)) ||
1010 friendlyURL.equals(curLayout.getFriendlyURL())) {
1011
1012 existingLayout = curLayout;
1013
1014 break;
1015 }
1016 }
1017
1018 if (existingLayout == null) {
1019 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
1020 groupId, privateLayout);
1021 }
1022 }
1023 else if (layoutsImportMode.equals(
1024 PortletDataHandlerKeys.
1025 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1026
1027 existingLayout = LayoutUtil.fetchByG_P_SPLU(
1028 groupId, privateLayout, layout.getUuid());
1029
1030 if (SitesUtil.isLayoutModifiedSinceLastMerge(existingLayout)) {
1031 newLayoutsMap.put(oldLayoutId, existingLayout);
1032
1033 return;
1034 }
1035 }
1036 else {
1037
1038
1039
1040
1041 existingLayout = LayoutUtil.fetchByUUID_G(
1042 layout.getUuid(), groupId);
1043
1044 if (existingLayout == null) {
1045 existingLayout = LayoutUtil.fetchByG_P_F(
1046 groupId, privateLayout, friendlyURL);
1047 }
1048
1049 if (existingLayout == null) {
1050 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
1051 groupId, privateLayout);
1052 }
1053 }
1054
1055 if (_log.isDebugEnabled()) {
1056 if (existingLayout == null) {
1057 _log.debug(
1058 "Layout with {groupId=" + groupId + ",privateLayout=" +
1059 privateLayout + ",layoutId=" + layoutId +
1060 "} does not exist");
1061 }
1062 else {
1063 _log.debug(
1064 "Layout with {groupId=" + groupId + ",privateLayout=" +
1065 privateLayout + ",layoutId=" + layoutId + "} exists");
1066 }
1067 }
1068
1069 if (existingLayout == null) {
1070 long plid = CounterLocalServiceUtil.increment();
1071
1072 importedLayout = LayoutUtil.create(plid);
1073
1074 if (layoutsImportMode.equals(
1075 PortletDataHandlerKeys.
1076 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1077
1078 importedLayout.setSourcePrototypeLayoutUuid(layout.getUuid());
1079
1080 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
1081 groupId, privateLayout);
1082 }
1083 else {
1084 importedLayout.setCreateDate(layout.getCreateDate());
1085 importedLayout.setModifiedDate(layout.getModifiedDate());
1086 importedLayout.setLayoutPrototypeUuid(
1087 layout.getLayoutPrototypeUuid());
1088 importedLayout.setLayoutPrototypeLinkEnabled(
1089 layout.isLayoutPrototypeLinkEnabled());
1090 importedLayout.setSourcePrototypeLayoutUuid(
1091 layout.getSourcePrototypeLayoutUuid());
1092 }
1093
1094 importedLayout.setUuid(layout.getUuid());
1095 importedLayout.setGroupId(groupId);
1096 importedLayout.setPrivateLayout(privateLayout);
1097 importedLayout.setLayoutId(layoutId);
1098
1099
1100
1101 boolean addGroupPermissions = true;
1102
1103 Group group = importedLayout.getGroup();
1104
1105 if (privateLayout && group.isUser()) {
1106 addGroupPermissions = false;
1107 }
1108
1109 boolean addGuestPermissions = false;
1110
1111 if (!privateLayout || layout.isTypeControlPanel()) {
1112 addGuestPermissions = true;
1113 }
1114
1115 ResourceLocalServiceUtil.addResources(
1116 user.getCompanyId(), groupId, user.getUserId(),
1117 Layout.class.getName(), importedLayout.getPlid(), false,
1118 addGroupPermissions, addGuestPermissions);
1119
1120 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1121 groupId, privateLayout);
1122
1123 importedLayout.setLayoutSet(layoutSet);
1124 }
1125 else {
1126 importedLayout = existingLayout;
1127 }
1128
1129 newLayoutsMap.put(oldLayoutId, importedLayout);
1130
1131 long parentLayoutId = layout.getParentLayoutId();
1132
1133 Node parentLayoutNode = rootElement.selectSingleNode(
1134 "./layouts/layout[@layout-id='" + parentLayoutId + "']");
1135
1136 String parentLayoutUuid = GetterUtil.getString(
1137 layoutElement.attributeValue("parent-layout-uuid"));
1138
1139 if ((parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) &&
1140 (parentLayoutNode != null)) {
1141
1142 importLayout(
1143 portletDataContext, user, layoutCache, previousLayouts,
1144 newLayouts, newLayoutsMap, portletsMergeMode, themeId,
1145 colorSchemeId, layoutsImportMode, privateLayout,
1146 importPermissions, importPublicLayoutPermissions,
1147 importThemeSettings, rootElement, (Element)parentLayoutNode);
1148
1149 Layout parentLayout = newLayoutsMap.get(parentLayoutId);
1150
1151 parentLayoutId = parentLayout.getLayoutId();
1152 }
1153 else if (Validator.isNotNull(parentLayoutUuid)) {
1154 Layout parentLayout =
1155 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1156 parentLayoutUuid, groupId);
1157
1158 parentLayoutId = parentLayout.getLayoutId();
1159 }
1160
1161 if (_log.isDebugEnabled()) {
1162 _log.debug(
1163 "Importing layout with layout id " + layoutId +
1164 " and parent layout id " + parentLayoutId);
1165 }
1166
1167 importedLayout.setCompanyId(user.getCompanyId());
1168 importedLayout.setParentLayoutId(parentLayoutId);
1169 importedLayout.setName(layout.getName());
1170 importedLayout.setTitle(layout.getTitle());
1171 importedLayout.setDescription(layout.getDescription());
1172 importedLayout.setKeywords(layout.getKeywords());
1173 importedLayout.setRobots(layout.getRobots());
1174 importedLayout.setType(layout.getType());
1175
1176 if (layout.isTypeArticle()) {
1177 importJournalArticle(portletDataContext, layout, layoutElement);
1178
1179 importedLayout.setTypeSettings(layout.getTypeSettings());
1180 }
1181 else if (layout.isTypePortlet() &&
1182 Validator.isNotNull(layout.getTypeSettings()) &&
1183 !portletsMergeMode.equals(
1184 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE)) {
1185
1186 mergePortlets(
1187 importedLayout, layout.getTypeSettings(), portletsMergeMode);
1188 }
1189 else if (layout.isTypeLinkToLayout()) {
1190 UnicodeProperties typeSettingsProperties =
1191 layout.getTypeSettingsProperties();
1192
1193 long linkToLayoutId = GetterUtil.getLong(
1194 typeSettingsProperties.getProperty(
1195 "linkToLayoutId", StringPool.BLANK));
1196
1197 if (linkToLayoutId > 0) {
1198 Node linkedLayoutNode = rootElement.selectSingleNode(
1199 "./layouts/layout[@layout-id='" + linkToLayoutId + "']");
1200
1201 if (linkedLayoutNode != null) {
1202 importLayout(
1203 portletDataContext, user, layoutCache, previousLayouts,
1204 newLayouts, newLayoutsMap, portletsMergeMode, themeId,
1205 colorSchemeId, layoutsImportMode, privateLayout,
1206 importPermissions, importPublicLayoutPermissions,
1207 importThemeSettings, rootElement,
1208 (Element)linkedLayoutNode);
1209
1210 Layout linkedLayout = newLayoutsMap.get(linkToLayoutId);
1211
1212 typeSettingsProperties.setProperty(
1213 "privateLayout",
1214 String.valueOf(linkedLayout.getPrivateLayout()));
1215 typeSettingsProperties.setProperty(
1216 "linkToLayoutId",
1217 String.valueOf(linkedLayout.getLayoutId()));
1218 }
1219 else {
1220 if (_log.isWarnEnabled()) {
1221 StringBundler sb = new StringBundler();
1222
1223 sb.append("Unable to link layout with friendly URL ");
1224 sb.append(layout.getFriendlyURL());
1225 sb.append(" and layout id ");
1226 sb.append(layout.getLayoutId());
1227 sb.append(" to layout with layout id ");
1228 sb.append(linkToLayoutId);
1229
1230 _log.warn(sb.toString());
1231 }
1232 }
1233 }
1234
1235 importedLayout.setTypeSettings(layout.getTypeSettings());
1236 }
1237 else {
1238 importedLayout.setTypeSettings(layout.getTypeSettings());
1239 }
1240
1241 importedLayout.setHidden(layout.isHidden());
1242 importedLayout.setFriendlyURL(friendlyURL);
1243
1244 if (importThemeSettings) {
1245 importedLayout.setThemeId(layout.getThemeId());
1246 importedLayout.setColorSchemeId(layout.getColorSchemeId());
1247 }
1248 else {
1249 importedLayout.setThemeId(StringPool.BLANK);
1250 importedLayout.setColorSchemeId(StringPool.BLANK);
1251 }
1252
1253 importedLayout.setWapThemeId(layout.getWapThemeId());
1254 importedLayout.setWapColorSchemeId(layout.getWapColorSchemeId());
1255 importedLayout.setCss(layout.getCss());
1256 importedLayout.setPriority(layout.getPriority());
1257 importedLayout.setLayoutPrototypeUuid(layout.getLayoutPrototypeUuid());
1258 importedLayout.setLayoutPrototypeLinkEnabled(
1259 layout.isLayoutPrototypeLinkEnabled());
1260
1261 StagingUtil.updateLastImportSettings(
1262 layoutElement, importedLayout, portletDataContext);
1263
1264 fixTypeSettings(importedLayout);
1265
1266 importedLayout.setIconImage(false);
1267
1268 if (layout.isIconImage()) {
1269 String iconImagePath = layoutElement.elementText("icon-image-path");
1270
1271 byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
1272 iconImagePath);
1273
1274 if ((iconBytes != null) && (iconBytes.length > 0)) {
1275 importedLayout.setIconImage(true);
1276
1277 if (importedLayout.getIconImageId() == 0) {
1278 long iconImageId = CounterLocalServiceUtil.increment();
1279
1280 importedLayout.setIconImageId(iconImageId);
1281 }
1282
1283 ImageLocalServiceUtil.updateImage(
1284 importedLayout.getIconImageId(), iconBytes);
1285 }
1286 }
1287 else {
1288 ImageLocalServiceUtil.deleteImage(importedLayout.getIconImageId());
1289 }
1290
1291 ServiceContext serviceContext = portletDataContext.createServiceContext(
1292 layoutElement, importedLayout, null);
1293
1294 importedLayout.setExpandoBridgeAttributes(serviceContext);
1295
1296 LayoutUtil.update(importedLayout);
1297
1298 portletDataContext.setPlid(importedLayout.getPlid());
1299 portletDataContext.setOldPlid(layout.getPlid());
1300
1301 newLayouts.add(importedLayout);
1302
1303
1304
1305 if (importPermissions) {
1306 _permissionImporter.importLayoutPermissions(
1307 layoutCache, portletDataContext.getCompanyId(), groupId,
1308 user.getUserId(), importedLayout, layoutElement, rootElement);
1309 }
1310
1311 if (importPublicLayoutPermissions) {
1312 String resourceName = Layout.class.getName();
1313 String resourcePrimKey = String.valueOf(importedLayout.getPlid());
1314
1315 Role guestRole = RoleLocalServiceUtil.getRole(
1316 importedLayout.getCompanyId(), RoleConstants.GUEST);
1317
1318 ResourcePermissionLocalServiceUtil.setResourcePermissions(
1319 importedLayout.getCompanyId(), resourceName,
1320 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
1321 guestRole.getRoleId(), new String[] {ActionKeys.VIEW});
1322 }
1323
1324 _portletImporter.importPortletData(
1325 portletDataContext, PortletKeys.LAYOUT_CONFIGURATION, null,
1326 layoutElement);
1327 }
1328
1329 protected void importLayoutSetPrototype(
1330 PortletDataContext portletDataContext, User user,
1331 String layoutSetPrototypeUuid, ServiceContext serviceContext)
1332 throws PortalException, SystemException {
1333
1334 String path = getLayoutSetPrototype(
1335 portletDataContext, layoutSetPrototypeUuid);
1336
1337 LayoutSetPrototype layoutSetPrototype = null;
1338
1339 try {
1340 layoutSetPrototype =
1341 LayoutSetPrototypeLocalServiceUtil.
1342 getLayoutSetPrototypeByUuidAndCompanyId(
1343 layoutSetPrototypeUuid, serviceContext.getCompanyId());
1344 }
1345 catch (NoSuchLayoutSetPrototypeException nslspe) {
1346 }
1347
1348 if (layoutSetPrototype == null) {
1349 layoutSetPrototype =
1350 (LayoutSetPrototype)portletDataContext.getZipEntryAsObject(
1351 path.concat(".xml"));
1352
1353 serviceContext.setUuid(layoutSetPrototypeUuid);
1354
1355 layoutSetPrototype =
1356 LayoutSetPrototypeLocalServiceUtil.addLayoutSetPrototype(
1357 user.getUserId(), user.getCompanyId(),
1358 layoutSetPrototype.getNameMap(),
1359 layoutSetPrototype.getDescription(),
1360 layoutSetPrototype.getActive(), true, serviceContext);
1361 }
1362
1363 InputStream inputStream = portletDataContext.getZipEntryAsInputStream(
1364 path.concat(".lar"));
1365
1366 SitesUtil.importLayoutSetPrototype(
1367 layoutSetPrototype, inputStream, serviceContext);
1368 }
1369
1370 protected String importTheme(LayoutSet layoutSet, InputStream themeZip)
1371 throws Exception {
1372
1373 ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
1374
1375 if (themeLoader == null) {
1376 _log.error("No theme loaders are deployed");
1377
1378 return null;
1379 }
1380
1381 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(themeZip);
1382
1383 String lookAndFeelXML = zipReader.getEntryAsString(
1384 "liferay-look-and-feel.xml");
1385
1386 String themeId = String.valueOf(layoutSet.getGroupId());
1387
1388 if (layoutSet.isPrivateLayout()) {
1389 themeId += "-private";
1390 }
1391 else {
1392 themeId += "-public";
1393 }
1394
1395 if (PropsValues.THEME_LOADER_NEW_THEME_ID_ON_IMPORT) {
1396 Date now = new Date();
1397
1398 themeId += "-" + Time.getShortTimestamp(now);
1399 }
1400
1401 String themeName = themeId;
1402
1403 lookAndFeelXML = StringUtil.replace(
1404 lookAndFeelXML,
1405 new String[] {
1406 "[$GROUP_ID$]", "[$THEME_ID$]", "[$THEME_NAME$]"
1407 },
1408 new String[] {
1409 String.valueOf(layoutSet.getGroupId()), themeId, themeName
1410 }
1411 );
1412
1413 FileUtil.deltree(
1414 themeLoader.getFileStorage() + StringPool.SLASH + themeId);
1415
1416 List<String> zipEntries = zipReader.getEntries();
1417
1418 for (String zipEntry : zipEntries) {
1419 String key = zipEntry;
1420
1421 if (key.equals("liferay-look-and-feel.xml")) {
1422 FileUtil.write(
1423 themeLoader.getFileStorage() + StringPool.SLASH + themeId +
1424 StringPool.SLASH + key,
1425 lookAndFeelXML.getBytes());
1426 }
1427 else {
1428 InputStream is = zipReader.getEntryAsInputStream(zipEntry);
1429
1430 FileUtil.write(
1431 themeLoader.getFileStorage() + StringPool.SLASH + themeId +
1432 StringPool.SLASH + key,
1433 is);
1434 }
1435 }
1436
1437 themeLoader.loadThemes();
1438
1439 ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
1440 _loadThemesMethodHandler, true);
1441
1442 clusterRequest.setFireAndForget(true);
1443
1444 ClusterExecutorUtil.execute(clusterRequest);
1445
1446 themeId +=
1447 PortletConstants.WAR_SEPARATOR +
1448 themeLoader.getServletContextName();
1449
1450 return PortalUtil.getJsSafePortletId(themeId);
1451 }
1452
1453 protected void mergePortlets(
1454 Layout layout, String newTypeSettings, String portletsMergeMode) {
1455
1456 try {
1457 UnicodeProperties previousTypeSettingsProperties =
1458 layout.getTypeSettingsProperties();
1459
1460 LayoutTypePortlet previousLayoutType =
1461 (LayoutTypePortlet)layout.getLayoutType();
1462
1463 LayoutTemplate previousLayoutTemplate =
1464 previousLayoutType.getLayoutTemplate();
1465
1466 List<String> previousColumns = previousLayoutTemplate.getColumns();
1467
1468 UnicodeProperties newTypeSettingsProperties = new UnicodeProperties(
1469 true);
1470
1471 newTypeSettingsProperties.load(newTypeSettings);
1472
1473 String layoutTemplateId = newTypeSettingsProperties.getProperty(
1474 LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
1475
1476 previousTypeSettingsProperties.setProperty(
1477 LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID,
1478 layoutTemplateId);
1479
1480 String nestedColumnIds = newTypeSettingsProperties.getProperty(
1481 LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1482
1483 if (Validator.isNotNull(nestedColumnIds)) {
1484 previousTypeSettingsProperties.setProperty(
1485 LayoutTypePortletConstants.NESTED_COLUMN_IDS,
1486 nestedColumnIds);
1487
1488 String[] nestedColumnIdsArray = StringUtil.split(
1489 nestedColumnIds);
1490
1491 for (String nestedColumnId : nestedColumnIdsArray) {
1492 String nestedColumnValue =
1493 newTypeSettingsProperties.getProperty(nestedColumnId);
1494
1495 previousTypeSettingsProperties.setProperty(
1496 nestedColumnId, nestedColumnValue);
1497 }
1498 }
1499
1500 LayoutTemplate newLayoutTemplate =
1501 LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1502 layoutTemplateId, false, null);
1503
1504 String[] newPortletIds = new String[0];
1505
1506 for (String columnId : newLayoutTemplate.getColumns()) {
1507 String columnValue = newTypeSettingsProperties.getProperty(
1508 columnId);
1509
1510 String[] portletIds = StringUtil.split(columnValue);
1511
1512 if (!previousColumns.contains(columnId)) {
1513 newPortletIds = ArrayUtil.append(newPortletIds, portletIds);
1514 }
1515 else {
1516 String[] previousPortletIds = StringUtil.split(
1517 previousTypeSettingsProperties.getProperty(columnId));
1518
1519 portletIds = appendPortletIds(
1520 previousPortletIds, portletIds, portletsMergeMode);
1521
1522 previousTypeSettingsProperties.setProperty(
1523 columnId, StringUtil.merge(portletIds));
1524 }
1525 }
1526
1527
1528
1529 String columnId = previousColumns.get(0);
1530
1531 String[] portletIds = StringUtil.split(
1532 previousTypeSettingsProperties.getProperty(columnId));
1533
1534 appendPortletIds(portletIds, newPortletIds, portletsMergeMode);
1535
1536 previousTypeSettingsProperties.setProperty(
1537 columnId, StringUtil.merge(portletIds));
1538
1539 layout.setTypeSettings(previousTypeSettingsProperties.toString());
1540 }
1541 catch (IOException ioe) {
1542 layout.setTypeSettings(newTypeSettings);
1543 }
1544 }
1545
1546 protected void validateLayoutPrototypes(
1547 long companyId, Element layoutsElement,
1548 List<Element> layoutElements)
1549 throws Exception {
1550
1551 List<Tuple> missingLayoutPrototypes = new ArrayList<Tuple>();
1552
1553 String layoutSetPrototypeUuid = layoutsElement.attributeValue(
1554 "layout-set-prototype-uuid");
1555
1556 if (Validator.isNotNull(layoutSetPrototypeUuid)) {
1557 try {
1558 LayoutSetPrototypeLocalServiceUtil.
1559 getLayoutSetPrototypeByUuidAndCompanyId(
1560 layoutSetPrototypeUuid, companyId);
1561 }
1562 catch (NoSuchLayoutSetPrototypeException nlspe) {
1563 String layoutSetPrototypeName = layoutsElement.attributeValue(
1564 "layout-set-prototype-name");
1565
1566 missingLayoutPrototypes.add(
1567 new Tuple(
1568 LayoutSetPrototype.class.getName(),
1569 layoutSetPrototypeUuid, layoutSetPrototypeName));
1570 }
1571 }
1572
1573 for (Element layoutElement : layoutElements) {
1574 String layoutPrototypeUuid = GetterUtil.getString(
1575 layoutElement.attributeValue("layout-prototype-uuid"));
1576
1577 if (Validator.isNotNull(layoutPrototypeUuid)) {
1578 try {
1579 LayoutPrototypeLocalServiceUtil.
1580 getLayoutPrototypeByUuidAndCompanyId(
1581 layoutPrototypeUuid, companyId);
1582 }
1583 catch (NoSuchLayoutPrototypeException nslpe) {
1584 String layoutPrototypeName = GetterUtil.getString(
1585 layoutElement.attributeValue("layout-prototype-name"));
1586
1587 missingLayoutPrototypes.add(
1588 new Tuple(
1589 LayoutPrototype.class.getName(),
1590 layoutPrototypeUuid, layoutPrototypeName));
1591 }
1592 }
1593 }
1594
1595 if (!missingLayoutPrototypes.isEmpty()) {
1596 throw new LayoutPrototypeException(missingLayoutPrototypes);
1597 }
1598 }
1599
1600 private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1601
1602 private static MethodHandler _loadThemesMethodHandler = new MethodHandler(
1603 new MethodKey(ThemeLoaderFactory.class.getName(), "loadThemes"));
1604
1605 private PermissionImporter _permissionImporter = new PermissionImporter();
1606 private PortletImporter _portletImporter = new PortletImporter();
1607
1608 }