Java tutorial
/** * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.lar; import com.liferay.portal.NoSuchLayoutException; import com.liferay.portal.kernel.lar.ImportExportThreadLocal; import com.liferay.portal.kernel.lar.PortletDataContext; import com.liferay.portal.kernel.lar.PortletDataHandler; import com.liferay.portal.kernel.lar.PortletDataHandlerKeys; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.ServletContextPool; import com.liferay.portal.kernel.staging.LayoutStagingUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.ReleaseInfo; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Time; import com.liferay.portal.kernel.util.UnicodeProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.workflow.WorkflowConstants; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.kernel.zip.ZipWriter; import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil; import com.liferay.portal.model.Group; import com.liferay.portal.model.Image; import com.liferay.portal.model.Layout; import com.liferay.portal.model.LayoutConstants; import com.liferay.portal.model.LayoutRevision; import com.liferay.portal.model.LayoutSet; import com.liferay.portal.model.LayoutSetPrototype; import com.liferay.portal.model.LayoutStagingHandler; import com.liferay.portal.model.LayoutTypePortlet; import com.liferay.portal.model.Portlet; import com.liferay.portal.model.PortletConstants; import com.liferay.portal.model.Theme; import com.liferay.portal.service.GroupLocalServiceUtil; import com.liferay.portal.service.ImageLocalServiceUtil; import com.liferay.portal.service.LayoutLocalServiceUtil; import com.liferay.portal.service.LayoutSetLocalServiceUtil; import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil; import com.liferay.portal.service.PortletLocalServiceUtil; import com.liferay.portal.service.ServiceContext; import com.liferay.portal.service.ServiceContextThreadLocal; import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.service.permission.PortletPermissionUtil; import com.liferay.portal.service.persistence.LayoutRevisionUtil; import com.liferay.portal.theme.ThemeLoader; import com.liferay.portal.theme.ThemeLoaderFactory; import com.liferay.portal.util.PortletKeys; import com.liferay.portal.util.PropsValues; import com.liferay.portlet.PortletPreferencesFactoryUtil; import com.liferay.portlet.asset.model.AssetCategory; import com.liferay.portlet.asset.model.AssetVocabulary; import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil; import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil; import com.liferay.portlet.journal.NoSuchArticleException; import com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl; import com.liferay.portlet.journal.model.JournalArticle; import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil; import com.liferay.portlet.sites.util.SitesUtil; import com.liferay.util.ContentUtil; import de.schlichtherle.io.FileInputStream; import java.io.File; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import org.apache.commons.lang.time.StopWatch; /** * @author Brian Wing Shun Chan * @author Joel Kozikowski * @author Charles May * @author Raymond Aug * @author Jorge Ferrer * @author Bruno Farache * @author Karthik Sudarshan * @author Zsigmond Rab * @author Douglas Wong */ public class LayoutExporter { public static final String SAME_GROUP_FRIENDLY_URL = "/[$SAME_GROUP_FRIENDLY_URL$]"; public static List<Portlet> getAlwaysExportablePortlets(long companyId) throws Exception { List<Portlet> portlets = PortletLocalServiceUtil.getPortlets(companyId); Iterator<Portlet> itr = portlets.iterator(); while (itr.hasNext()) { Portlet portlet = itr.next(); if (!portlet.isActive()) { itr.remove(); continue; } PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance(); if ((portletDataHandler == null) || (!portletDataHandler.isAlwaysExportable())) { itr.remove(); } } return portlets; } public static void updateLastPublishDate(LayoutSet layoutSet, long lastPublishDate) throws Exception { UnicodeProperties settingsProperties = layoutSet.getSettingsProperties(); if (lastPublishDate <= 0) { settingsProperties.remove("last-publish-date"); } else { settingsProperties.setProperty("last-publish-date", String.valueOf(lastPublishDate)); } LayoutSetLocalServiceUtil.updateSettings(layoutSet.getGroupId(), layoutSet.isPrivateLayout(), settingsProperties.toString()); } public byte[] exportLayouts(long groupId, boolean privateLayout, long[] layoutIds, Map<String, String[]> parameterMap, Date startDate, Date endDate) throws Exception { File file = exportLayoutsAsFile(groupId, privateLayout, layoutIds, parameterMap, startDate, endDate); try { return FileUtil.getBytes(file); } finally { file.delete(); } } public File exportLayoutsAsFile(long groupId, boolean privateLayout, long[] layoutIds, Map<String, String[]> parameterMap, Date startDate, Date endDate) throws Exception { try { ImportExportThreadLocal.setLayoutExportInProcess(true); return doExportLayoutsAsFile(groupId, privateLayout, layoutIds, parameterMap, startDate, endDate); } finally { ImportExportThreadLocal.setLayoutExportInProcess(false); } } protected File doExportLayoutsAsFile(long groupId, boolean privateLayout, long[] layoutIds, Map<String, String[]> parameterMap, Date startDate, Date endDate) throws Exception { boolean exportCategories = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.CATEGORIES); boolean exportIgnoreLastPublishDate = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE); boolean exportPermissions = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PERMISSIONS); boolean exportUserPermissions = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.USER_PERMISSIONS); boolean exportPortletArchivedSetups = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS); boolean exportPortletUserPreferences = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES); boolean exportTheme = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.THEME); boolean exportThemeSettings = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.THEME_REFERENCE); boolean publishToRemote = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PUBLISH_TO_REMOTE); boolean updateLastPublishDate = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE); if (_log.isDebugEnabled()) { _log.debug("Export categories " + exportCategories); _log.debug("Export permissions " + exportPermissions); _log.debug("Export user permissions " + exportUserPermissions); _log.debug("Export portlet archived setups " + exportPortletArchivedSetups); _log.debug("Export portlet user preferences " + exportPortletUserPreferences); _log.debug("Export theme " + exportTheme); } LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(groupId, privateLayout); long companyId = layoutSet.getCompanyId(); long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId); ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext(); if (serviceContext == null) { serviceContext = new ServiceContext(); serviceContext.setCompanyId(companyId); serviceContext.setSignedIn(false); serviceContext.setUserId(defaultUserId); ServiceContextThreadLocal.pushServiceContext(serviceContext); } serviceContext.setAttribute("exporting", Boolean.TRUE); long layoutSetBranchId = MapUtil.getLong(parameterMap, "layoutSetBranchId"); serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId); long lastPublishDate = System.currentTimeMillis(); if (endDate != null) { lastPublishDate = endDate.getTime(); } if (exportIgnoreLastPublishDate) { endDate = null; startDate = null; } StopWatch stopWatch = null; if (_log.isInfoEnabled()) { stopWatch = new StopWatch(); stopWatch.start(); } LayoutCache layoutCache = new LayoutCache(); ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter(); PortletDataContext portletDataContext = new PortletDataContextImpl(companyId, groupId, parameterMap, new HashSet<String>(), startDate, endDate, zipWriter); portletDataContext.setPortetDataContextListener(new PortletDataContextListenerImpl(portletDataContext)); Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("root"); Element headerElement = rootElement.addElement("header"); headerElement.addAttribute("build-number", String.valueOf(ReleaseInfo.getBuildNumber())); headerElement.addAttribute("export-date", Time.getRFC822()); if (portletDataContext.hasDateRange()) { headerElement.addAttribute("start-date", String.valueOf(portletDataContext.getStartDate())); headerElement.addAttribute("end-date", String.valueOf(portletDataContext.getEndDate())); } headerElement.addAttribute("type", "layout-set"); headerElement.addAttribute("group-id", String.valueOf(groupId)); headerElement.addAttribute("private-layout", String.valueOf(privateLayout)); Group group = layoutSet.getGroup(); if (group.isLayoutSetPrototype()) { LayoutSetPrototype layoutSetPrototype = LayoutSetPrototypeLocalServiceUtil .getLayoutSetPrototype(group.getClassPK()); String layoutSetPrototypeUuid = layoutSetPrototype.getUuid(); headerElement.addAttribute("layout-set-prototype-uuid", layoutSetPrototypeUuid); if (publishToRemote) { String path = getLayoutSetPrototype(portletDataContext, layoutSetPrototypeUuid); File layoutSetPrototypeFile = SitesUtil.exportLayoutSetPrototype(layoutSetPrototype, serviceContext); try { portletDataContext.addZipEntry(path.concat(".lar"), new FileInputStream(layoutSetPrototypeFile)); portletDataContext.addZipEntry(path.concat(".xml"), layoutSetPrototype); } finally { layoutSetPrototypeFile.delete(); } } } if (exportTheme || exportThemeSettings) { headerElement.addAttribute("theme-id", layoutSet.getThemeId()); headerElement.addAttribute("color-scheme-id", layoutSet.getColorSchemeId()); } Element cssElement = headerElement.addElement("css"); cssElement.addCDATA(layoutSet.getCss()); Portlet layoutConfigurationPortlet = PortletLocalServiceUtil .getPortletById(portletDataContext.getCompanyId(), PortletKeys.LAYOUT_CONFIGURATION); Map<String, Object[]> portletIds = new LinkedHashMap<String, Object[]>(); List<Layout> layouts = null; if ((layoutIds == null) || (layoutIds.length == 0)) { layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout); } else { layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout, layoutIds); } List<Portlet> portlets = getAlwaysExportablePortlets(companyId); if (!layouts.isEmpty()) { Layout firstLayout = layouts.get(0); if (group.isStagingGroup()) { group = group.getLiveGroup(); } for (Portlet portlet : portlets) { String portletId = portlet.getRootPortletId(); if (!group.isStagedPortlet(portletId)) { continue; } String key = PortletPermissionUtil.getPrimaryKey(0, portletId); if (portletIds.get(key) == null) { portletIds.put(key, new Object[] { portletId, firstLayout.getPlid(), groupId, StringPool.BLANK, StringPool.BLANK }); } } } Element layoutsElement = rootElement.addElement("layouts"); for (Layout layout : layouts) { exportLayout(portletDataContext, layoutConfigurationPortlet, layoutCache, portlets, portletIds, exportPermissions, exportUserPermissions, layout, layoutsElement); } if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) { Element rolesElement = rootElement.addElement("roles"); if (exportPermissions) { _permissionExporter.exportLayoutRoles(layoutCache, companyId, groupId, rolesElement); } } long previousScopeGroupId = portletDataContext.getScopeGroupId(); Element portletsElement = rootElement.addElement("portlets"); for (Map.Entry<String, Object[]> portletIdsEntry : portletIds.entrySet()) { Object[] portletObjects = portletIdsEntry.getValue(); String portletId = null; long plid = 0; long scopeGroupId = 0; String scopeType = StringPool.BLANK; String scopeLayoutUuid = null; if (portletObjects.length == 4) { portletId = (String) portletIdsEntry.getValue()[0]; plid = (Long) portletIdsEntry.getValue()[1]; scopeGroupId = (Long) portletIdsEntry.getValue()[2]; scopeLayoutUuid = (String) portletIdsEntry.getValue()[3]; } else { portletId = (String) portletIdsEntry.getValue()[0]; plid = (Long) portletIdsEntry.getValue()[1]; scopeGroupId = (Long) portletIdsEntry.getValue()[2]; scopeType = (String) portletIdsEntry.getValue()[3]; scopeLayoutUuid = (String) portletIdsEntry.getValue()[4]; } Layout layout = LayoutLocalServiceUtil.getLayout(plid); portletDataContext.setPlid(layout.getPlid()); portletDataContext.setOldPlid(layout.getPlid()); portletDataContext.setScopeGroupId(scopeGroupId); portletDataContext.setScopeType(scopeType); portletDataContext.setScopeLayoutUuid(scopeLayoutUuid); boolean[] exportPortletControls = getExportPortletControls(companyId, portletId, portletDataContext, parameterMap); _portletExporter.exportPortlet(portletDataContext, layoutCache, portletId, layout, portletsElement, defaultUserId, exportPermissions, exportPortletArchivedSetups, exportPortletControls[0], exportPortletControls[1], exportPortletUserPreferences, exportUserPermissions); } portletDataContext.setScopeGroupId(previousScopeGroupId); if (exportCategories) { exportAssetCategories(portletDataContext); } _portletExporter.exportAssetLinks(portletDataContext); _portletExporter.exportAssetTags(portletDataContext); _portletExporter.exportComments(portletDataContext); _portletExporter.exportExpandoTables(portletDataContext); _portletExporter.exportLocks(portletDataContext); if (exportPermissions) { _permissionExporter.exportPortletDataPermissions(portletDataContext); } _portletExporter.exportRatingsEntries(portletDataContext, rootElement); if (exportTheme && !portletDataContext.isPerformDirectBinaryImport()) { exportTheme(layoutSet, zipWriter); } if (_log.isInfoEnabled()) { if (stopWatch != null) { _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms"); } else { _log.info("Exporting layouts is finished"); } } portletDataContext.addZipEntry("/manifest.xml", document.formattedString()); try { return zipWriter.getFile(); } finally { if (updateLastPublishDate) { updateLastPublishDate(layoutSet, lastPublishDate); } } } protected void exportAssetCategories(PortletDataContext portletDataContext) throws Exception { Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("categories-hierarchy"); Element assetVocabulariesElement = rootElement.addElement("vocabularies"); List<AssetVocabulary> assetVocabularies = AssetVocabularyLocalServiceUtil .getGroupVocabularies(portletDataContext.getGroupId()); for (AssetVocabulary assetVocabulary : assetVocabularies) { _portletExporter.exportAssetVocabulary(portletDataContext, assetVocabulariesElement, assetVocabulary); } Element categoriesElement = rootElement.addElement("categories"); List<AssetCategory> assetCategories = AssetCategoryUtil.findByGroupId(portletDataContext.getGroupId()); for (AssetCategory assetCategory : assetCategories) { _portletExporter.exportAssetCategory(portletDataContext, assetVocabulariesElement, categoriesElement, assetCategory); } _portletExporter.exportAssetCategories(portletDataContext, rootElement); portletDataContext.addZipEntry(portletDataContext.getRootPath() + "/categories-hierarchy.xml", document.formattedString()); } protected void exportJournalArticle(PortletDataContext portletDataContext, Layout layout, Element layoutElement) throws Exception { UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties(); String articleId = typeSettingsProperties.getProperty("article-id", StringPool.BLANK); long articleGroupId = layout.getGroupId(); if (Validator.isNull(articleId)) { if (_log.isWarnEnabled()) { _log.warn("No article id found in typeSettings of layout " + layout.getPlid()); } } JournalArticle article = null; try { article = JournalArticleLocalServiceUtil.getLatestArticle(articleGroupId, articleId, WorkflowConstants.STATUS_APPROVED); } catch (NoSuchArticleException nsae) { if (_log.isWarnEnabled()) { _log.warn("No approved article found with group id " + articleGroupId + " and article id " + articleId); } } if (article == null) { return; } String path = JournalPortletDataHandlerImpl.getArticlePath(portletDataContext, article); Element articleElement = layoutElement.addElement("article"); articleElement.addAttribute("path", path); Element dlFileEntryTypesElement = layoutElement.addElement("dl-file-entry-types"); Element dlFoldersElement = layoutElement.addElement("dl-folders"); Element dlFilesElement = layoutElement.addElement("dl-file-entries"); Element dlFileRanksElement = layoutElement.addElement("dl-file-ranks"); JournalPortletDataHandlerImpl.exportArticle(portletDataContext, layoutElement, layoutElement, layoutElement, dlFileEntryTypesElement, dlFoldersElement, dlFilesElement, dlFileRanksElement, article, false); } protected void exportLayout(PortletDataContext portletDataContext, Portlet layoutConfigurationPortlet, LayoutCache layoutCache, List<Portlet> portlets, Map<String, Object[]> portletIds, boolean exportPermissions, boolean exportUserPermissions, Layout layout, Element layoutsElement) throws Exception { String path = portletDataContext.getLayoutPath(layout.getLayoutId()) + "/layout.xml"; if (!portletDataContext.isPathNotProcessed(path)) { return; } LayoutRevision layoutRevision = null; if (LayoutStagingUtil.isBranchingLayout(layout)) { ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext(); long layoutSetBranchId = ParamUtil.getLong(serviceContext, "layoutSetBranchId"); if (layoutSetBranchId <= 0) { return; } layoutRevision = LayoutRevisionUtil.fetchByL_H_P(layoutSetBranchId, true, layout.getPlid()); if (layoutRevision == null) { return; } LayoutStagingHandler layoutStagingHandler = LayoutStagingUtil.getLayoutStagingHandler(layout); layoutStagingHandler.setLayoutRevision(layoutRevision); } Element layoutElement = layoutsElement.addElement("layout"); if (layoutRevision != null) { layoutElement.addAttribute("layout-revision-id", String.valueOf(layoutRevision.getLayoutRevisionId())); layoutElement.addAttribute("layout-branch-id", String.valueOf(layoutRevision.getLayoutBranchId())); layoutElement.addAttribute("layout-branch-name", String.valueOf(layoutRevision.getLayoutBranch().getName())); } layoutElement.addAttribute("layout-uuid", layout.getUuid()); layoutElement.addAttribute("layout-id", String.valueOf(layout.getLayoutId())); long parentLayoutId = layout.getParentLayoutId(); if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) { Layout parentLayout = LayoutLocalServiceUtil.getLayout(layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId); if (parentLayout != null) { layoutElement.addAttribute("parent-layout-uuid", parentLayout.getUuid()); } } boolean deleteLayout = MapUtil.getBoolean(portletDataContext.getParameterMap(), "delete_" + layout.getPlid()); if (deleteLayout) { layoutElement.addAttribute("delete", String.valueOf(true)); return; } portletDataContext.setPlid(layout.getPlid()); if (layout.isIconImage()) { Image image = ImageLocalServiceUtil.getImage(layout.getIconImageId()); if (image != null) { String iconPath = getLayoutIconPath(portletDataContext, layout, image); layoutElement.addElement("icon-image-path").addText(iconPath); portletDataContext.addZipEntry(iconPath, image.getTextObj()); } } _portletExporter.exportPortletData(portletDataContext, layoutConfigurationPortlet, layout, null, layoutElement); // Layout permissions if (exportPermissions) { _permissionExporter.exportLayoutPermissions(portletDataContext, layoutCache, portletDataContext.getCompanyId(), portletDataContext.getScopeGroupId(), layout, layoutElement, exportUserPermissions); } if (layout.isTypeArticle()) { exportJournalArticle(portletDataContext, layout, layoutElement); } else if (layout.isTypeLinkToLayout()) { UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties(); long linkToLayoutId = GetterUtil .getLong(typeSettingsProperties.getProperty("linkToLayoutId", StringPool.BLANK)); if (linkToLayoutId > 0) { try { Layout linkedToLayout = LayoutLocalServiceUtil.getLayout(portletDataContext.getScopeGroupId(), layout.isPrivateLayout(), linkToLayoutId); exportLayout(portletDataContext, layoutConfigurationPortlet, layoutCache, portlets, portletIds, exportPermissions, exportUserPermissions, linkedToLayout, layoutsElement); } catch (NoSuchLayoutException nsle) { } } } else if (layout.isTypePortlet()) { for (Portlet portlet : portlets) { if (portlet.isScopeable() && layout.hasScopeGroup()) { String key = PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portlet.getPortletId()); portletIds.put(key, new Object[] { portlet.getPortletId(), layout.getPlid(), layout.getScopeGroup().getGroupId(), StringPool.BLANK, layout.getUuid() }); } } LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType(); for (String portletId : layoutTypePortlet.getPortletIds()) { javax.portlet.PortletPreferences jxPreferences = PortletPreferencesFactoryUtil .getLayoutPortletSetup(layout, portletId); String scopeType = GetterUtil.getString(jxPreferences.getValue("lfrScopeType", null)); String scopeLayoutUuid = GetterUtil.getString(jxPreferences.getValue("lfrScopeLayoutUuid", null)); long scopeGroupId = portletDataContext.getScopeGroupId(); if (Validator.isNotNull(scopeType)) { Group scopeGroup = null; if (scopeType.equals("company")) { scopeGroup = GroupLocalServiceUtil.getCompanyGroup(layout.getCompanyId()); } else if (scopeType.equals("layout")) { Layout scopeLayout = null; scopeLayout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(scopeLayoutUuid, portletDataContext.getGroupId()); if (scopeLayout == null) { continue; } scopeGroup = scopeLayout.getScopeGroup(); } else { throw new IllegalArgumentException("Scope type " + scopeType + " is invalid"); } if (scopeGroup != null) { scopeGroupId = scopeGroup.getGroupId(); } } String key = PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portletId); portletIds.put(key, new Object[] { portletId, layout.getPlid(), scopeGroupId, scopeType, scopeLayoutUuid }); } } fixTypeSettings(layout); layoutElement.addAttribute("path", path); portletDataContext.addExpando(layoutElement, path, layout); portletDataContext.addZipEntry(path, layout); } protected void exportTheme(LayoutSet layoutSet, ZipWriter zipWriter) throws Exception { Theme theme = layoutSet.getTheme(); String lookAndFeelXML = ContentUtil.get("com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl"); lookAndFeelXML = StringUtil.replace(lookAndFeelXML, new String[] { "[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]" }, new String[] { theme.getTemplateExtension(), theme.getVirtualPath() }); String servletContextName = theme.getServletContextName(); ServletContext servletContext = ServletContextPool.get(servletContextName); if (servletContext == null) { if (_log.isWarnEnabled()) { _log.warn("Servlet context not found for theme " + theme.getThemeId()); } return; } File themeZip = new File(zipWriter.getPath() + "/theme.zip"); ZipWriter themeZipWriter = ZipWriterFactoryUtil.getZipWriter(themeZip); themeZipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML); File cssPath = null; File imagesPath = null; File javaScriptPath = null; File templatesPath = null; if (!theme.isLoadFromServletContext()) { ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(servletContextName); if (themeLoader == null) { _log.error(servletContextName + " does not map to a theme loader"); } else { String realPath = themeLoader.getFileStorage().getPath() + StringPool.SLASH + theme.getName(); cssPath = new File(realPath + "/css"); imagesPath = new File(realPath + "/images"); javaScriptPath = new File(realPath + "/javascript"); templatesPath = new File(realPath + "/templates"); } } else { cssPath = new File(servletContext.getRealPath(theme.getCssPath())); imagesPath = new File(servletContext.getRealPath(theme.getImagesPath())); javaScriptPath = new File(servletContext.getRealPath(theme.getJavaScriptPath())); templatesPath = new File(servletContext.getRealPath(theme.getTemplatesPath())); } exportThemeFiles("css", cssPath, themeZipWriter); exportThemeFiles("images", imagesPath, themeZipWriter); exportThemeFiles("javascript", javaScriptPath, themeZipWriter); exportThemeFiles("templates", templatesPath, themeZipWriter); } protected void exportThemeFiles(String path, File dir, ZipWriter zipWriter) throws Exception { if ((dir == null) || (!dir.exists())) { return; } File[] files = dir.listFiles(); for (File file : files) { if (file.isDirectory()) { exportThemeFiles(path + StringPool.SLASH + file.getName(), file, zipWriter); } else { zipWriter.addEntry(path + StringPool.SLASH + file.getName(), FileUtil.getBytes(file)); } } } protected void fixTypeSettings(Layout layout) throws Exception { if (!layout.isTypeURL()) { return; } UnicodeProperties typeSettings = layout.getTypeSettingsProperties(); String url = GetterUtil.getString(typeSettings.getProperty("url")); String friendlyURLPrivateGroupPath = PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING; String friendlyURLPrivateUserPath = PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING; String friendlyURLPublicPath = PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING; if (!url.startsWith(friendlyURLPrivateGroupPath) && !url.startsWith(friendlyURLPrivateUserPath) && !url.startsWith(friendlyURLPublicPath)) { return; } int x = url.indexOf(CharPool.SLASH, 1); if (x == -1) { return; } int y = url.indexOf(CharPool.SLASH, x + 1); if (y == -1) { return; } String friendlyURL = url.substring(x, y); String groupFriendlyURL = layout.getGroup().getFriendlyURL(); if (!friendlyURL.equals(groupFriendlyURL)) { return; } typeSettings.setProperty("url", url.substring(0, x) + SAME_GROUP_FRIENDLY_URL + url.substring(y)); } protected boolean[] getExportPortletControls(long companyId, String portletId, PortletDataContext portletDataContext, Map<String, String[]> parameterMap) throws Exception { boolean exportPortletData = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_DATA); boolean exportPortletDataAll = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL); boolean exportPortletSetup = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_SETUP); boolean exportPortletSetupAll = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_SETUP_ALL); if (_log.isDebugEnabled()) { _log.debug("Export portlet data " + exportPortletData); _log.debug("Export all portlet data " + exportPortletDataAll); _log.debug("Export portlet setup " + exportPortletSetup); } boolean exportCurPortletData = exportPortletData; boolean exportCurPortletSetup = exportPortletSetup; // If PORTLET_DATA_ALL is true, this means that staging has just been // activated and all data and setup must be exported. There is no // portlet export control to check in this case. if (exportPortletDataAll) { exportCurPortletData = true; exportCurPortletSetup = true; } else { Portlet portlet = PortletLocalServiceUtil.getPortletById(companyId, portletId); if (portlet != null) { String portletDataHandlerClass = portlet.getPortletDataHandlerClass(); // Checking if the portlet has a data handler, if it doesn't, // the default values are the ones set in PORTLET_DATA and // PORTLET_SETUP. If it has a data handler, iterate over each // portlet export control. if (portletDataHandlerClass != null) { String rootPortletId = PortletConstants.getRootPortletId(portletId); // PORTLET_DATA and the PORTLET_DATA for this specific // data handler must be true exportCurPortletData = exportPortletData && MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_DATA + StringPool.UNDERLINE + rootPortletId); // PORTLET_SETUP and the PORTLET_SETUP for this specific // data handler must be true exportCurPortletSetup = exportPortletSetup && MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PORTLET_SETUP + StringPool.UNDERLINE + rootPortletId); } } } if (exportPortletSetupAll) { exportCurPortletSetup = true; } return new boolean[] { exportCurPortletData, exportCurPortletSetup }; } protected String getLayoutIconPath(PortletDataContext portletDataContext, Layout layout, Image image) { StringBundler sb = new StringBundler(5); sb.append(portletDataContext.getLayoutPath(layout.getLayoutId())); sb.append("/icons/"); sb.append(image.getImageId()); sb.append(StringPool.PERIOD); sb.append(image.getType()); return sb.toString(); } protected String getLayoutSetPrototype(PortletDataContext portletDataContext, String layoutSetPrototypeUuid) { StringBundler sb = new StringBundler(3); sb.append(portletDataContext.getRootPath()); sb.append("/layout-set-prototype/"); sb.append(layoutSetPrototypeUuid); return sb.toString(); } private static Log _log = LogFactoryUtil.getLog(LayoutExporter.class); private PermissionExporter _permissionExporter = new PermissionExporter(); private PortletExporter _portletExporter = new PortletExporter(); }