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