From 890b1739c54daf0b2f5a40b808f3cff78917d80c Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sun, 22 Sep 2019 11:29:51 +0200 Subject: [PATCH] Introduce CMS Theme. --- .../src/org/argeo/cms/script/Theme.java | 187 +---------------- .../src/org/argeo/cms/util/CmsTheme.java | 198 ++++++++++++++++++ 2 files changed, 205 insertions(+), 180 deletions(-) create mode 100644 org.argeo.cms.ui/src/org/argeo/cms/util/CmsTheme.java diff --git a/org.argeo.cms.ui/src/org/argeo/cms/script/Theme.java b/org.argeo.cms.ui/src/org/argeo/cms/script/Theme.java index a3dce2f57..584f521e0 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/script/Theme.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/script/Theme.java @@ -1,191 +1,18 @@ package org.argeo.cms.script; -import static java.nio.charset.StandardCharsets.UTF_8; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.argeo.cms.util.BundleResourceLoader; -import org.argeo.cms.util.ThemeUtils; -import org.eclipse.rap.rwt.RWT; -import org.eclipse.rap.rwt.application.Application; -import org.eclipse.rap.rwt.service.ResourceLoader; -import org.osgi.framework.Bundle; +import org.argeo.cms.util.CmsTheme; import org.osgi.framework.BundleContext; -public class Theme { - private final static Log log = LogFactory.getLog(Theme.class); - - private String themeId; - private Map css = new HashMap<>(); - private Map resources = new HashMap<>(); - - private String headerCss; - private List fonts = new ArrayList<>(); - - private String basePath; - private String cssPath; - - public Theme(BundleContext bundleContext) { - this(bundleContext, null); - } +/** @deprecated Use CmsTheme instead. */ +@Deprecated +public class Theme extends CmsTheme { public Theme(BundleContext bundleContext, String symbolicName) { - Bundle themeBundle; - if (symbolicName == null) { - themeBundle = bundleContext.getBundle(); -// basePath = "/theme/"; -// cssPath = basePath; - } else { - themeBundle = ThemeUtils.findThemeBundle(bundleContext, symbolicName); - } - basePath = "/"; - cssPath = "/rap/"; - this.themeId = RWT.DEFAULT_THEME_ID; - addStyleSheets(themeBundle, new BundleResourceLoader(themeBundle)); - BundleResourceLoader themeBRL = new BundleResourceLoader(themeBundle); - addResources(themeBRL, "*.png"); - addResources(themeBRL, "*.gif"); - addResources(themeBRL, "*.jpg"); - addResources(themeBRL, "*.jpeg"); - addResources(themeBRL, "*.svg"); - addResources(themeBRL, "*.ico"); - - // fonts - URL fontsUrl = themeBundle.getEntry(basePath + "fonts.txt"); - if (fontsUrl != null) { - loadFontsUrl(fontsUrl); - } - - // common CSS header (plain CSS) - URL headerCssUrl = themeBundle.getEntry(basePath + "header.css"); - if (headerCssUrl != null) { - try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) { - headerCss = buffer.lines().collect(Collectors.joining("\n")); - } catch (IOException e) { - throw new CmsException("Cannot read " + headerCssUrl, e); - } - } - - } - - public void apply(Application application) { - resources: for (String name : resources.keySet()) { - if (name.startsWith("target/")) - continue resources; // skip maven output - application.addResource(name, resources.get(name)); - if (log.isDebugEnabled()) - log.debug("Added resource " + name); - } - for (String name : css.keySet()) { - application.addStyleSheet(themeId, name, css.get(name)); - if (log.isDebugEnabled()) - log.debug("Added RAP CSS " + name); - } - } - - public String getAdditionalHeaders() { - StringBuilder sb = new StringBuilder(); - if (headerCss != null) { - sb.append("\n"); - } - for (String link : fonts) { - sb.append("\n"); - } - if (sb.length() == 0) - return null; - else - return sb.toString(); - } - - void addStyleSheets(Bundle themeBundle, ResourceLoader ssRL) { - Enumeration themeResources = themeBundle.findEntries(cssPath, "*.css", true); - if (themeResources == null) - return; - while (themeResources.hasMoreElements()) { - String resource = themeResources.nextElement().getPath(); - // remove first '/' so that RWT registers it - resource = resource.substring(1); - if (!resource.endsWith("/")) { - if (css.containsKey(resource)) - log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName()); - css.put(resource, ssRL); - } - - } - - } - - void loadFontsUrl(URL url) { - try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { - String line = null; - while ((line = in.readLine()) != null) { - line = line.trim(); - if (!line.equals("") && !line.startsWith("#")) { - fonts.add(line); - } - } - } catch (IOException e) { - throw new CmsException("Cannot load URL " + url, e); - } - } - - void addResources(BundleResourceLoader themeBRL, String pattern) { - Bundle themeBundle = themeBRL.getBundle(); - Enumeration themeResources = themeBundle.findEntries(basePath, pattern, true); - if (themeResources == null) - return; - while (themeResources.hasMoreElements()) { - String resource = themeResources.nextElement().getPath(); - // remove first '/' so that RWT registers it - resource = resource.substring(1); - if (!resource.endsWith("/")) { - if (resources.containsKey(resource)) - log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName()); - resources.put(resource, themeBRL); - } - - } - - } - - public String getThemeId() { - return themeId; + super(bundleContext, symbolicName); } - public void setThemeId(String themeId) { - this.themeId = themeId; - } - - public String getBasePath() { - return basePath; - } - - public void setBasePath(String basePath) { - this.basePath = basePath; - } - - public String getCssPath() { - return cssPath; - } - - public void setCssPath(String cssPath) { - this.cssPath = cssPath; + public Theme(BundleContext bundleContext) { + super(bundleContext); } } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/util/CmsTheme.java b/org.argeo.cms.ui/src/org/argeo/cms/util/CmsTheme.java new file mode 100644 index 000000000..76b1854a4 --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/util/CmsTheme.java @@ -0,0 +1,198 @@ +package org.argeo.cms.util; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.application.Application; +import org.eclipse.rap.rwt.service.ResourceLoader; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Simplifies the theming of an app (only RAP is supported at this stage).
+ * + * Additional fonts listed in /fonts.txt.
+ * Additional (standard CSS) header in /header.css.
+ * RAP specific CSS files in /rap/*.css.
+ * All images added as additional resources based on extensions + * / ** /*.{png,gif,jpeg,...}.
+ */ +public class CmsTheme { + private final static Log log = LogFactory.getLog(CmsTheme.class); + + private String themeId; + private Map css = new HashMap<>(); + private Map resources = new HashMap<>(); + + private String headerCss; + private List fonts = new ArrayList<>(); + + private String basePath; + private String cssPath; + + public CmsTheme(BundleContext bundleContext) { + this(bundleContext, null); + } + + public CmsTheme(BundleContext bundleContext, String symbolicName) { + Bundle themeBundle; + if (symbolicName == null) { + themeBundle = bundleContext.getBundle(); +// basePath = "/theme/"; +// cssPath = basePath; + } else { + themeBundle = ThemeUtils.findThemeBundle(bundleContext, symbolicName); + } + basePath = "/"; + cssPath = "/rap/"; + this.themeId = RWT.DEFAULT_THEME_ID; + addStyleSheets(themeBundle, new BundleResourceLoader(themeBundle)); + BundleResourceLoader themeBRL = new BundleResourceLoader(themeBundle); + addResources(themeBRL, "*.png"); + addResources(themeBRL, "*.gif"); + addResources(themeBRL, "*.jpg"); + addResources(themeBRL, "*.jpeg"); + addResources(themeBRL, "*.svg"); + addResources(themeBRL, "*.ico"); + + // fonts + URL fontsUrl = themeBundle.getEntry(basePath + "fonts.txt"); + if (fontsUrl != null) { + loadFontsUrl(fontsUrl); + } + + // common CSS header (plain CSS) + URL headerCssUrl = themeBundle.getEntry(basePath + "header.css"); + if (headerCssUrl != null) { + try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) { + headerCss = buffer.lines().collect(Collectors.joining("\n")); + } catch (IOException e) { + throw new CmsException("Cannot read " + headerCssUrl, e); + } + } + + } + + public void apply(Application application) { + resources: for (String name : resources.keySet()) { + if (name.startsWith("target/")) + continue resources; // skip maven output + application.addResource(name, resources.get(name)); + if (log.isDebugEnabled()) + log.debug("Added resource " + name); + } + for (String name : css.keySet()) { + application.addStyleSheet(themeId, name, css.get(name)); + if (log.isDebugEnabled()) + log.debug("Added RAP CSS " + name); + } + } + + public String getAdditionalHeaders() { + StringBuilder sb = new StringBuilder(); + if (headerCss != null) { + sb.append("\n"); + } + for (String link : fonts) { + sb.append("\n"); + } + if (sb.length() == 0) + return null; + else + return sb.toString(); + } + + void addStyleSheets(Bundle themeBundle, ResourceLoader ssRL) { + Enumeration themeResources = themeBundle.findEntries(cssPath, "*.css", true); + if (themeResources == null) + return; + while (themeResources.hasMoreElements()) { + String resource = themeResources.nextElement().getPath(); + // remove first '/' so that RWT registers it + resource = resource.substring(1); + if (!resource.endsWith("/")) { + if (css.containsKey(resource)) + log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName()); + css.put(resource, ssRL); + } + + } + + } + + void loadFontsUrl(URL url) { + try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { + String line = null; + while ((line = in.readLine()) != null) { + line = line.trim(); + if (!line.equals("") && !line.startsWith("#")) { + fonts.add(line); + } + } + } catch (IOException e) { + throw new CmsException("Cannot load URL " + url, e); + } + } + + void addResources(BundleResourceLoader themeBRL, String pattern) { + Bundle themeBundle = themeBRL.getBundle(); + Enumeration themeResources = themeBundle.findEntries(basePath, pattern, true); + if (themeResources == null) + return; + while (themeResources.hasMoreElements()) { + String resource = themeResources.nextElement().getPath(); + // remove first '/' so that RWT registers it + resource = resource.substring(1); + if (!resource.endsWith("/")) { + if (resources.containsKey(resource)) + log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName()); + resources.put(resource, themeBRL); + } + + } + + } + + public String getThemeId() { + return themeId; + } + + public void setThemeId(String themeId) { + this.themeId = themeId; + } + + public String getBasePath() { + return basePath; + } + + public void setBasePath(String basePath) { + this.basePath = basePath; + } + + public String getCssPath() { + return cssPath; + } + + public void setCssPath(String cssPath) { + this.cssPath = cssPath; + } + +} -- 2.30.2