]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui/src/org/argeo/cms/script/Theme.java
Add JGit to client.
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / script / Theme.java
1 package org.argeo.cms.script;
2
3 import static java.nio.charset.StandardCharsets.UTF_8;
4
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.net.URL;
9 import java.util.ArrayList;
10 import java.util.Enumeration;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.stream.Collectors;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.argeo.cms.CmsException;
19 import org.argeo.cms.util.BundleResourceLoader;
20 import org.argeo.cms.util.ThemeUtils;
21 import org.eclipse.rap.rwt.RWT;
22 import org.eclipse.rap.rwt.application.Application;
23 import org.eclipse.rap.rwt.service.ResourceLoader;
24 import org.osgi.framework.Bundle;
25 import org.osgi.framework.BundleContext;
26
27 public class Theme {
28 private final static Log log = LogFactory.getLog(Theme.class);
29
30 private String themeId;
31 private Map<String, ResourceLoader> css = new HashMap<>();
32 private Map<String, ResourceLoader> resources = new HashMap<>();
33
34 private String headerCss;
35 private List<String> fonts = new ArrayList<>();
36
37 private String basePath;
38 private String cssPath;
39
40 public Theme(BundleContext bundleContext) {
41 this(bundleContext, null);
42 }
43
44 public Theme(BundleContext bundleContext, String symbolicName) {
45 Bundle themeBundle;
46 if (symbolicName == null) {
47 themeBundle = bundleContext.getBundle();
48 // basePath = "/theme/";
49 // cssPath = basePath;
50 } else {
51 themeBundle = ThemeUtils.findThemeBundle(bundleContext, symbolicName);
52 }
53 basePath = "/";
54 cssPath = "/rap/";
55 this.themeId = RWT.DEFAULT_THEME_ID;
56 addStyleSheets(themeBundle, new BundleResourceLoader(themeBundle));
57 BundleResourceLoader themeBRL = new BundleResourceLoader(themeBundle);
58 addResources(themeBRL, "*.png");
59 addResources(themeBRL, "*.gif");
60 addResources(themeBRL, "*.jpg");
61 addResources(themeBRL, "*.jpeg");
62 addResources(themeBRL, "*.svg");
63 addResources(themeBRL, "*.ico");
64
65 // fonts
66 URL fontsUrl = themeBundle.getEntry(basePath + "fonts.txt");
67 if (fontsUrl != null) {
68 loadFontsUrl(fontsUrl);
69 }
70
71 // common CSS header (plain CSS)
72 URL headerCssUrl = themeBundle.getEntry(basePath + "header.css");
73 if (headerCssUrl != null) {
74 try (BufferedReader buffer = new BufferedReader(new InputStreamReader(headerCssUrl.openStream(), UTF_8))) {
75 headerCss = buffer.lines().collect(Collectors.joining("\n"));
76 } catch (IOException e) {
77 throw new CmsException("Cannot read " + headerCssUrl, e);
78 }
79 }
80
81 }
82
83 public void apply(Application application) {
84 resources: for (String name : resources.keySet()) {
85 if (name.startsWith("target/"))
86 continue resources; // skip maven output
87 application.addResource(name, resources.get(name));
88 if (log.isDebugEnabled())
89 log.debug("Added resource " + name);
90 }
91 for (String name : css.keySet()) {
92 application.addStyleSheet(themeId, name, css.get(name));
93 if (log.isDebugEnabled())
94 log.debug("Added RAP CSS " + name);
95 }
96 }
97
98 public String getAdditionalHeaders() {
99 StringBuilder sb = new StringBuilder();
100 if (headerCss != null) {
101 sb.append("<style type='text/css'>\n");
102 sb.append(headerCss);
103 sb.append("\n</style>\n");
104 }
105 for (String link : fonts) {
106 sb.append("<link rel='stylesheet' href='");
107 sb.append(link);
108 sb.append("'/>\n");
109 }
110 if (sb.length() == 0)
111 return null;
112 else
113 return sb.toString();
114 }
115
116 void addStyleSheets(Bundle themeBundle, ResourceLoader ssRL) {
117 Enumeration<URL> themeResources = themeBundle.findEntries(cssPath, "*.css", true);
118 if (themeResources == null)
119 return;
120 while (themeResources.hasMoreElements()) {
121 String resource = themeResources.nextElement().getPath();
122 // remove first '/' so that RWT registers it
123 resource = resource.substring(1);
124 if (!resource.endsWith("/")) {
125 if (css.containsKey(resource))
126 log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
127 css.put(resource, ssRL);
128 }
129
130 }
131
132 }
133
134 void loadFontsUrl(URL url) {
135 try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) {
136 String line = null;
137 while ((line = in.readLine()) != null) {
138 line = line.trim();
139 if (!line.equals("") && !line.startsWith("#")) {
140 fonts.add(line);
141 }
142 }
143 } catch (IOException e) {
144 throw new CmsException("Cannot load URL " + url, e);
145 }
146 }
147
148 void addResources(BundleResourceLoader themeBRL, String pattern) {
149 Bundle themeBundle = themeBRL.getBundle();
150 Enumeration<URL> themeResources = themeBundle.findEntries(basePath, pattern, true);
151 if (themeResources == null)
152 return;
153 while (themeResources.hasMoreElements()) {
154 String resource = themeResources.nextElement().getPath();
155 // remove first '/' so that RWT registers it
156 resource = resource.substring(1);
157 if (!resource.endsWith("/")) {
158 if (resources.containsKey(resource))
159 log.warn("Overriding " + resource + " from " + themeBundle.getSymbolicName());
160 resources.put(resource, themeBRL);
161 }
162
163 }
164
165 }
166
167 public String getThemeId() {
168 return themeId;
169 }
170
171 public void setThemeId(String themeId) {
172 this.themeId = themeId;
173 }
174
175 public String getBasePath() {
176 return basePath;
177 }
178
179 public void setBasePath(String basePath) {
180 this.basePath = basePath;
181 }
182
183 public String getCssPath() {
184 return cssPath;
185 }
186
187 public void setCssPath(String cssPath) {
188 this.cssPath = cssPath;
189 }
190
191 }