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