001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.kernel.lar.PortletDataContext;
018    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.servlet.ServletContextPool;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.MapUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.zip.ZipWriter;
029    import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
030    import com.liferay.portal.model.Layout;
031    import com.liferay.portal.model.LayoutSet;
032    import com.liferay.portal.model.LayoutSetBranch;
033    import com.liferay.portal.model.Theme;
034    import com.liferay.portal.theme.ThemeLoader;
035    import com.liferay.portal.theme.ThemeLoaderFactory;
036    import com.liferay.util.ContentUtil;
037    
038    import java.io.File;
039    
040    import javax.servlet.ServletContext;
041    
042    /**
043     * @author Mate Thurzo
044     */
045    public class ThemeExporter {
046    
047            public void exportTheme(
048                            PortletDataContext portletDataContext, Layout layout)
049                    throws Exception {
050    
051                    boolean exportTheme = MapUtil.getBoolean(
052                            portletDataContext.getParameterMap(), PortletDataHandlerKeys.THEME);
053    
054                    if (_log.isDebugEnabled()) {
055                            _log.debug("Export theme " + exportTheme);
056                    }
057    
058                    if (exportTheme && !portletDataContext.isPerformDirectBinaryImport() &&
059                            !layout.isInheritLookAndFeel()) {
060    
061                            Theme theme = layout.getTheme();
062    
063                            StringBundler sb = new StringBundler(6);
064    
065                            ZipWriter zipWriter = portletDataContext.getZipWriter();
066    
067                            sb.append(zipWriter.getPath());
068                            sb.append(StringPool.SLASH);
069                            sb.append("theme");
070                            sb.append(StringPool.DASH);
071                            sb.append(String.valueOf(layout.getLayoutId()));
072                            sb.append(".zip");
073    
074                            File themeZipFile = new File(sb.toString());
075    
076                            exportTheme(theme, themeZipFile);
077                    }
078            }
079    
080            public void exportTheme(
081                            PortletDataContext portletDataContext, LayoutSet layoutSet)
082                    throws Exception {
083    
084                    exportTheme(
085                            portletDataContext, layoutSet.getTheme(),
086                            layoutSet.getColorSchemeId(), layoutSet.getCss());
087            }
088    
089            public void exportTheme(
090                            PortletDataContext portletDataContext,
091                            LayoutSetBranch layoutSetBranch)
092                    throws Exception {
093    
094                    exportTheme(
095                            portletDataContext, layoutSetBranch.getTheme(),
096                            layoutSetBranch.getColorSchemeId(), layoutSetBranch.getCss());
097            }
098    
099            protected void exportTheme(
100                            PortletDataContext portletDataContext, Theme theme,
101                            String colorSchemeId, String css)
102                    throws Exception {
103    
104                    boolean exportTheme = MapUtil.getBoolean(
105                            portletDataContext.getParameterMap(), PortletDataHandlerKeys.THEME);
106                    boolean exportThemeSettings = MapUtil.getBoolean(
107                            portletDataContext.getParameterMap(),
108                            PortletDataHandlerKeys.THEME_REFERENCE);
109    
110                    if (_log.isDebugEnabled()) {
111                            _log.debug("Export theme " + exportTheme);
112                            _log.debug("Export theme settings " + exportThemeSettings);
113                    }
114    
115                    Element exportDataRootElement =
116                            portletDataContext.getExportDataRootElement();
117                    Element headerElement = exportDataRootElement.element("header");
118    
119                    if (exportTheme || exportThemeSettings) {
120                            headerElement.addAttribute("theme-id", theme.getThemeId());
121                            headerElement.addAttribute("color-scheme-id", colorSchemeId);
122                    }
123    
124                    if (exportTheme && !portletDataContext.isPerformDirectBinaryImport()) {
125                            ZipWriter zipWriter = portletDataContext.getZipWriter();
126    
127                            File themeZipFile = new File(zipWriter.getPath() + "/theme.zip");
128    
129                            exportTheme(theme, themeZipFile);
130                    }
131    
132                    Element cssElement = headerElement.addElement("css");
133    
134                    cssElement.addCDATA(css);
135            }
136    
137            protected void exportTheme(Theme theme, File themeZipFile)
138                    throws Exception {
139    
140                    String lookAndFeelXML = ContentUtil.get(
141                            "com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl");
142    
143                    lookAndFeelXML = StringUtil.replace(
144                            lookAndFeelXML,
145                            new String[] {
146                                    "[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]"
147                            },
148                            new String[] {
149                                    theme.getTemplateExtension(), theme.getVirtualPath()
150                            }
151                    );
152    
153                    String servletContextName = theme.getServletContextName();
154    
155                    ServletContext servletContext = ServletContextPool.get(
156                            servletContextName);
157    
158                    if (servletContext == null) {
159                            if (_log.isWarnEnabled()) {
160                                    _log.warn(
161                                            "Servlet context not found for theme " +
162                                                    theme.getThemeId());
163                            }
164    
165                            return;
166                    }
167    
168                    ZipWriter themeZipWriter = ZipWriterFactoryUtil.getZipWriter(
169                            themeZipFile);
170    
171                    themeZipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML);
172    
173                    File cssPath = null;
174                    File imagesPath = null;
175                    File javaScriptPath = null;
176                    File templatesPath = null;
177    
178                    if (!theme.isLoadFromServletContext()) {
179                            ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(
180                                    servletContextName);
181    
182                            if (themeLoader == null) {
183                                    _log.error(
184                                            servletContextName + " does not map to a theme loader");
185                            }
186                            else {
187                                    File file = themeLoader.getFileStorage();
188    
189                                    String realPath =
190                                            file.getPath() + StringPool.SLASH + theme.getName();
191    
192                                    cssPath = new File(realPath + "/css");
193                                    imagesPath = new File(realPath + "/images");
194                                    javaScriptPath = new File(realPath + "/javascript");
195                                    templatesPath = new File(realPath + "/templates");
196                            }
197                    }
198                    else {
199                            cssPath = new File(servletContext.getRealPath(theme.getCssPath()));
200                            imagesPath = new File(
201                                    servletContext.getRealPath(theme.getImagesPath()));
202                            javaScriptPath = new File(
203                                    servletContext.getRealPath(theme.getJavaScriptPath()));
204                            templatesPath = new File(
205                                    servletContext.getRealPath(theme.getTemplatesPath()));
206                    }
207    
208                    exportThemeFiles("css", cssPath, themeZipWriter);
209                    exportThemeFiles("images", imagesPath, themeZipWriter);
210                    exportThemeFiles("javascript", javaScriptPath, themeZipWriter);
211                    exportThemeFiles("templates", templatesPath, themeZipWriter);
212            }
213    
214            protected void exportThemeFiles(String path, File dir, ZipWriter zipWriter)
215                    throws Exception {
216    
217                    if ((dir == null) || !dir.exists()) {
218                            return;
219                    }
220    
221                    File[] files = dir.listFiles();
222    
223                    for (File file : files) {
224                            if (file.isDirectory()) {
225                                    exportThemeFiles(
226                                            path + StringPool.SLASH + file.getName(), file, zipWriter);
227                            }
228                            else {
229                                    zipWriter.addEntry(
230                                            path + StringPool.SLASH + file.getName(),
231                                            FileUtil.getBytes(file));
232                            }
233                    }
234            }
235    
236            private static Log _log = LogFactoryUtil.getLog(ThemeExporter.class);
237    
238    }