Introduce body html in theming.
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / ui / util / BundleCmsTheme.java
index 1076b6ca2b72f9351d2aa065b9526420fdcf5855..6b997e6a35c4f0e691b412b1d9129a2759b4ede7 100644 (file)
@@ -7,6 +7,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
@@ -15,8 +16,7 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
-import org.argeo.cms.ui.CmsTheme;
-import org.eclipse.swt.graphics.Image;
+import org.apache.commons.io.IOUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 
@@ -35,17 +35,29 @@ public class BundleCmsTheme extends AbstractCmsTheme {
        public final static String CMS_THEME_PROPERTY = "argeo.cms.theme";
        public final static String CMS_THEME_BUNDLE_PROPERTY = "argeo.cms.theme.bundle";
 
+       private final static String HEADER_CSS = "header.css";
+       private final static String FONTS_TXT = "fonts.txt";
+       private final static String BODY_HTML = "body.html";
+
 //     private final static Log log = LogFactory.getLog(BundleCmsTheme.class);
 
        private String themeId;
+       private Set<String> webCssPaths = new TreeSet<>();
        private Set<String> rapCssPaths = new TreeSet<>();
+       private Set<String> swtCssPaths = new TreeSet<>();
        private Set<String> imagesPaths = new TreeSet<>();
+       private Set<String> fontsPaths = new TreeSet<>();
 
        private String headerCss;
        private List<String> fonts = new ArrayList<>();
 
+       private String bodyHtml="<body></body>";
+
        private String basePath;
-       private String rapCssPath;
+       private String styleCssPath;
+//     private String webCssPath;
+//     private String rapCssPath;
+//     private String swtCssPath;
        private Bundle themeBundle;
 
        public BundleCmsTheme() {
@@ -79,33 +91,50 @@ public class BundleCmsTheme extends AbstractCmsTheme {
                        themeBundle = findThemeBundle(bundleContext, symbolicName);
                }
                basePath = "/";
-               rapCssPath = "/rap/";
+               styleCssPath = "/style/";
+//             webCssPath = "/css/";
+//             rapCssPath = "/rap/";
+//             swtCssPath = "/swt/";
 //             this.themeId = RWT.DEFAULT_THEME_ID;
                this.themeId = themeBundle.getSymbolicName();
-               addRapStyleSheets(themeBundle);
-               addResources("*.png");
-               addResources("*.gif");
-               addResources("*.jpg");
-               addResources("*.jpeg");
-               addResources("*.svg");
-               addResources("*.ico");
+               webCssPaths = addCss(themeBundle, "/css/");
+               rapCssPaths = addCss(themeBundle, "/rap/");
+               swtCssPaths = addCss(themeBundle, "/swt/");
+               addImages("*.png");
+               addImages("*.gif");
+               addImages("*.jpg");
+               addImages("*.jpeg");
+               addImages("*.svg");
+               addImages("*.ico");
+
+               addFonts("*.woff");
+               addFonts("*.woff2");
 
                // fonts
-               URL fontsUrl = themeBundle.getEntry(basePath + "fonts.txt");
+               URL fontsUrl = themeBundle.getEntry(basePath + FONTS_TXT);
                if (fontsUrl != null) {
                        loadFontsUrl(fontsUrl);
                }
 
                // common CSS header (plain CSS)
-               URL headerCssUrl = themeBundle.getEntry(basePath + "header.css");
+               URL headerCssUrl = themeBundle.getEntry(basePath + HEADER_CSS);
                if (headerCssUrl != null) {
+                       // added to plain Web CSS
+                       webCssPaths.add(basePath + HEADER_CSS);
+                       // and it will also be used by RAP:
                        try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) {
                                headerCss = buffer.lines().collect(Collectors.joining("\n"));
                        } catch (IOException e) {
                                throw new IllegalArgumentException("Cannot read " + headerCssUrl, e);
                        }
                }
-       }
+
+               // body
+               URL bodyUrl = themeBundle.getEntry(basePath + BODY_HTML);
+               if (bodyUrl != null) {
+                       loadBodyHtml(bodyUrl);
+               }
+}
 
        public String getHtmlHeaders() {
                StringBuilder sb = new StringBuilder();
@@ -124,24 +153,43 @@ public class BundleCmsTheme extends AbstractCmsTheme {
                else
                        return sb.toString();
        }
+       
+       
 
-       void addRapStyleSheets(Bundle themeBundle) {
-               Enumeration<URL> themeResources = themeBundle.findEntries(rapCssPath, "*.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 (rapCss.containsKey(resource))
-//                                     log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
-//                             rapCss.put(resource, ssRL);
-                               rapCssPaths.add(resource);
-                       }
+       @Override
+       public String getBodyHtml() {
+               return bodyHtml;
+       }
 
+       Set<String> addCss(Bundle themeBundle, String path) {
+               Set<String> paths = new TreeSet<>();
+
+               // common CSS
+               Enumeration<URL> commonResources = themeBundle.findEntries(styleCssPath, "*.css", true);
+               if (commonResources != null) {
+                       while (commonResources.hasMoreElements()) {
+                               String resource = commonResources.nextElement().getPath();
+                               // remove first '/' so that RWT registers it
+                               resource = resource.substring(1);
+                               if (!resource.endsWith("/")) {
+                                       paths.add(resource);
+                               }
+                       }
                }
 
+               // specific CSS
+               Enumeration<URL> themeResources = themeBundle.findEntries(path, "*.css", true);
+               if (themeResources != null) {
+                       while (themeResources.hasMoreElements()) {
+                               String resource = themeResources.nextElement().getPath();
+                               // remove first '/' so that RWT registers it
+                               resource = resource.substring(1);
+                               if (!resource.endsWith("/")) {
+                                       paths.add(resource);
+                               }
+                       }
+               }
+               return paths;
        }
 
        void loadFontsUrl(URL url) {
@@ -158,7 +206,15 @@ public class BundleCmsTheme extends AbstractCmsTheme {
                }
        }
 
-       void addResources(String pattern) {
+       void loadBodyHtml(URL url) {
+               try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
+               bodyHtml=       IOUtils.toString(url,StandardCharsets.UTF_8);
+               } catch (IOException e) {
+                       throw new IllegalArgumentException("Cannot load URL " + url, e);
+               }
+       }
+
+       void addImages(String pattern) {
                Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
                if (themeResources == null)
                        return;
@@ -177,6 +233,25 @@ public class BundleCmsTheme extends AbstractCmsTheme {
 
        }
 
+       void addFonts(String pattern) {
+               Enumeration<URL> 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);
+                               fontsPaths.add(resource);
+                       }
+
+               }
+
+       }
+
        @Override
        public InputStream getResourceAsStream(String resourceName) throws IOException {
                URL res = themeBundle.getEntry(resourceName);
@@ -193,7 +268,6 @@ public class BundleCmsTheme extends AbstractCmsTheme {
        public String getThemeId() {
                return themeId;
        }
-       
 
 //     public void setThemeId(String themeId) {
 //             this.themeId = themeId;
@@ -215,16 +289,40 @@ public class BundleCmsTheme extends AbstractCmsTheme {
 //             this.rapCssPath = cssPath;
 //     }
 
+       @Override
+       public Set<String> getWebCssPaths() {
+               return webCssPaths;
+       }
+
        @Override
        public Set<String> getRapCssPaths() {
                return rapCssPaths;
        }
 
+       @Override
+       public Set<String> getSwtCssPaths() {
+               return swtCssPaths;
+       }
+
        @Override
        public Set<String> getImagesPaths() {
                return imagesPaths;
        }
 
+       @Override
+       public Set<String> getFontsPaths() {
+               return fontsPaths;
+       }
+
+       @Override
+       public InputStream loadPath(String path) throws IOException {
+               URL url = themeBundle.getResource(path);
+               if (url == null)
+                       throw new IllegalArgumentException(
+                                       "Path " + path + " not found in bundle " + themeBundle.getSymbolicName());
+               return url.openStream();
+       }
+
        private static Bundle findThemeBundle(BundleContext bundleContext, String themeId) {
                if (themeId == null)
                        return null;
@@ -241,4 +339,14 @@ public class BundleCmsTheme extends AbstractCmsTheme {
                return themeBundle;
        }
 
+       @Override
+       public int hashCode() {
+               return themeId.hashCode();
+       }
+
+       @Override
+       public String toString() {
+               return "Bundle CMS Theme " + themeId;
+       }
+
 }