001
014
015 package com.liferay.portal.model.impl;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.servlet.PortalWebResourceConstants;
020 import com.liferay.portal.kernel.servlet.PortalWebResourcesUtil;
021 import com.liferay.portal.kernel.servlet.ServletContextPool;
022 import com.liferay.portal.kernel.template.TemplateConstants;
023 import com.liferay.portal.kernel.util.ListUtil;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.ThemeHelper;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.model.ColorScheme;
029 import com.liferay.portal.model.Plugin;
030 import com.liferay.portal.model.SpriteImage;
031 import com.liferay.portal.model.Theme;
032 import com.liferay.portal.model.ThemeSetting;
033 import com.liferay.portal.theme.ThemeCompanyId;
034 import com.liferay.portal.theme.ThemeCompanyLimit;
035 import com.liferay.portal.theme.ThemeGroupLimit;
036 import com.liferay.portal.util.PortalUtil;
037 import com.liferay.portal.util.PropsValues;
038
039 import java.util.HashMap;
040 import java.util.LinkedHashMap;
041 import java.util.List;
042 import java.util.Map;
043 import java.util.Properties;
044 import java.util.concurrent.ConcurrentHashMap;
045
046 import javax.servlet.ServletContext;
047
048
053 public class ThemeImpl extends PluginBaseImpl implements Theme {
054
055 public ThemeImpl() {
056 this(null);
057 }
058
059 public ThemeImpl(String themeId) {
060 this(themeId, null);
061 }
062
063 public ThemeImpl(String themeId, String name) {
064 _themeId = themeId;
065 _name = name;
066 }
067
068 @Override
069 public void addSetting(
070 String key, String value, boolean configurable, String type,
071 String[] options, String script) {
072
073 ThemeSetting themeSetting = new ThemeSettingImpl(
074 configurable, options, script, type, value);
075
076 _themeSettingsMap.put(key, themeSetting);
077 }
078
079 @Override
080 public int compareTo(Theme theme) {
081 return getName().compareTo(theme.getName());
082 }
083
084 @Override
085 public boolean equals(Object obj) {
086 if (this == obj) {
087 return true;
088 }
089
090 if (!(obj instanceof Theme)) {
091 return false;
092 }
093
094 Theme theme = (Theme)obj;
095
096 String themeId = theme.getThemeId();
097
098 if (getThemeId().equals(themeId)) {
099 return true;
100 }
101 else {
102 return false;
103 }
104 }
105
106 @Override
107 public List<ColorScheme> getColorSchemes() {
108 List<ColorScheme> colorSchemes = ListUtil.fromMapValues(
109 _colorSchemesMap);
110
111 return ListUtil.sort(colorSchemes);
112 }
113
114 @Override
115 public Map<String, ColorScheme> getColorSchemesMap() {
116 return _colorSchemesMap;
117 }
118
119 @Override
120 public Map<String, ThemeSetting> getConfigurableSettings() {
121 Map<String, ThemeSetting> configurableSettings = new LinkedHashMap<>();
122
123 for (Map.Entry<String, ThemeSetting> entry :
124 _themeSettingsMap.entrySet()) {
125
126 ThemeSetting themeSetting = entry.getValue();
127
128 if (themeSetting.isConfigurable()) {
129 configurableSettings.put(entry.getKey(), entry.getValue());
130 }
131 }
132
133 return configurableSettings;
134 }
135
136 @Override
137 public String getContextPath() {
138 if (!isWARFile()) {
139 return PortalUtil.getPathContext();
140 }
141
142 String servletContextName = getServletContextName();
143
144 if (ServletContextPool.containsKey(servletContextName)) {
145 ServletContext servletContext = ServletContextPool.get(
146 servletContextName);
147
148 return servletContext.getContextPath();
149 }
150
151 return StringPool.SLASH.concat(servletContextName);
152 }
153
154 @Override
155 public String getCssPath() {
156 return _cssPath;
157 }
158
159 @Override
160 public String getDevice() {
161 if (isWapTheme()) {
162 return "wap";
163 }
164 else {
165 return "regular";
166 }
167 }
168
169 @Override
170 public String getFreeMarkerTemplateLoader() {
171 if (_loadFromServletContext) {
172 return TemplateConstants.SERVLET_SEPARATOR;
173 }
174 else {
175 return TemplateConstants.THEME_LOADER_SEPARATOR;
176 }
177 }
178
179 @Override
180 public String getImagesPath() {
181 return _imagesPath;
182 }
183
184 @Override
185 public String getJavaScriptPath() {
186 return _javaScriptPath;
187 }
188
189 @Override
190 public boolean getLoadFromServletContext() {
191 return _loadFromServletContext;
192 }
193
194 @Override
195 public String getName() {
196 return _name;
197 }
198
199 @Override
200 public String getPluginId() {
201 return getThemeId();
202 }
203
204 @Override
205 public String getPluginType() {
206 return Plugin.TYPE_THEME;
207 }
208
209 @Override
210 public String getResourcePath(
211 ServletContext servletContext, String portletId, String path) {
212
213 if (!PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
214 return ThemeHelper.getResourcePath(
215 servletContext, this, portletId, path);
216 }
217
218 String key = path;
219
220 if (Validator.isNotNull(portletId)) {
221 key = path.concat(StringPool.POUND).concat(portletId);
222 }
223
224 String resourcePath = _resourcePathsMap.get(key);
225
226 if (resourcePath != null) {
227 return resourcePath;
228 }
229
230 resourcePath = ThemeHelper.getResourcePath(
231 servletContext, this, portletId, path);
232
233 _resourcePathsMap.put(key, resourcePath);
234
235 return resourcePath;
236 }
237
238 @Override
239 public String getRootPath() {
240 return _rootPath;
241 }
242
243 @Override
244 public String getServletContextName() {
245 return _servletContextName;
246 }
247
248 @Override
249 public String getSetting(String key) {
250 String value = null;
251
252 ThemeSetting themeSetting = _themeSettingsMap.get(key);
253
254 if (themeSetting != null) {
255 value = themeSetting.getValue();
256 }
257
258 return value;
259 }
260
261 @Override
262 public String[] getSettingOptions(String key) {
263 String[] options = null;
264
265 ThemeSetting themeSetting = _themeSettingsMap.get(key);
266
267 if (themeSetting != null) {
268 options = themeSetting.getOptions();
269 }
270
271 return options;
272 }
273
274 @Override
275 public Map<String, ThemeSetting> getSettings() {
276 return _themeSettingsMap;
277 }
278
279 @Override
280 public Properties getSettingsProperties() {
281 Properties properties = new Properties();
282
283 for (String key : _themeSettingsMap.keySet()) {
284 ThemeSetting setting = _themeSettingsMap.get(key);
285
286 if (setting != null) {
287 properties.setProperty(key, setting.getValue());
288 }
289 }
290
291 return properties;
292 }
293
294 @Override
295 public SpriteImage getSpriteImage(String fileName) {
296 return _spriteImagesMap.get(fileName);
297 }
298
299 @Override
300 public String getStaticResourcePath() {
301 String proxyPath = PortalUtil.getPathProxy();
302
303 String virtualPath = getVirtualPath();
304
305 if (Validator.isNotNull(virtualPath)) {
306 return proxyPath.concat(virtualPath);
307 }
308
309 String contextPath = null;
310
311 if (!isWARFile()) {
312 contextPath = PortalWebResourcesUtil.getContextPath(
313 PortalWebResourceConstants.RESOURCE_TYPE_CSS);
314 }
315 else {
316 return getContextPath();
317 }
318
319 return proxyPath.concat(contextPath);
320 }
321
322 @Override
323 public String getTemplateExtension() {
324 return _templateExtension;
325 }
326
327 @Override
328 public String getTemplatesPath() {
329 return _templatesPath;
330 }
331
332 @Override
333 public ThemeCompanyLimit getThemeCompanyLimit() {
334 return _themeCompanyLimit;
335 }
336
337 @Override
338 public ThemeGroupLimit getThemeGroupLimit() {
339 return _themeGroupLimit;
340 }
341
342 @Override
343 public String getThemeId() {
344 return _themeId;
345 }
346
347 @Override
348 public long getTimestamp() {
349 return _timestamp;
350 }
351
352 @Override
353 public String getVelocityResourceListener() {
354 if (_loadFromServletContext) {
355 return TemplateConstants.SERVLET_SEPARATOR;
356 }
357 else {
358 return TemplateConstants.THEME_LOADER_SEPARATOR;
359 }
360 }
361
362 @Override
363 public String getVirtualPath() {
364 return _virtualPath;
365 }
366
367 @Override
368 public boolean getWapTheme() {
369 return _wapTheme;
370 }
371
372 @Override
373 public boolean getWARFile() {
374 return _warFile;
375 }
376
377 @Override
378 public boolean hasColorSchemes() {
379 if (!_colorSchemesMap.isEmpty()) {
380 return true;
381 }
382 else {
383 return false;
384 }
385 }
386
387 @Override
388 public int hashCode() {
389 return _themeId.hashCode();
390 }
391
392 @Override
393 public boolean isCompanyAvailable(long companyId) {
394 return isAvailable(getThemeCompanyLimit(), companyId);
395 }
396
397 @Override
398 public boolean isControlPanelTheme() {
399 return _controlPanelTheme;
400 }
401
402 @Override
403 public boolean isGroupAvailable(long groupId) {
404 return isAvailable(getThemeGroupLimit(), groupId);
405 }
406
407 @Override
408 public boolean isLoadFromServletContext() {
409 return _loadFromServletContext;
410 }
411
412 @Override
413 public boolean isPageTheme() {
414 return _pageTheme;
415 }
416
417 @Override
418 public boolean isWapTheme() {
419 return _wapTheme;
420 }
421
422 @Override
423 public boolean isWARFile() {
424 return _warFile;
425 }
426
427 @Override
428 public boolean resourceExists(
429 ServletContext servletContext, String portletId, String path)
430 throws Exception {
431
432 if (!PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
433 return ThemeHelper.resourceExists(
434 servletContext, this, portletId, path);
435 }
436
437 if (Validator.isNull(path)) {
438 return false;
439 }
440
441 String key = path;
442
443 if (Validator.isNotNull(portletId)) {
444 key = path.concat(StringPool.POUND).concat(portletId);
445 }
446
447 Boolean resourceExists = _resourceExistsMap.get(key);
448
449 if (resourceExists != null) {
450 return resourceExists;
451 }
452
453 resourceExists = ThemeHelper.resourceExists(
454 servletContext, this, portletId, path);
455
456 _resourceExistsMap.put(key, resourceExists);
457
458 return resourceExists;
459 }
460
461 @Override
462 public void setControlPanelTheme(boolean controlPanelTheme) {
463 _controlPanelTheme = controlPanelTheme;
464 }
465
466 @Override
467 public void setCssPath(String cssPath) {
468 _cssPath = cssPath;
469 }
470
471 @Override
472 public void setImagesPath(String imagesPath) {
473 _imagesPath = imagesPath;
474 }
475
476 @Override
477 public void setJavaScriptPath(String javaScriptPath) {
478 _javaScriptPath = javaScriptPath;
479 }
480
481 @Override
482 public void setLoadFromServletContext(boolean loadFromServletContext) {
483 _loadFromServletContext = loadFromServletContext;
484 }
485
486 @Override
487 public void setName(String name) {
488 _name = name;
489 }
490
491 @Override
492 public void setPageTheme(boolean pageTheme) {
493 _pageTheme = pageTheme;
494 }
495
496 @Override
497 public void setRootPath(String rootPath) {
498 _rootPath = rootPath;
499 }
500
501 @Override
502 public void setServletContextName(String servletContextName) {
503 _servletContextName = servletContextName;
504
505 if (Validator.isNotNull(_servletContextName)) {
506 _warFile = true;
507 }
508 else {
509 _warFile = false;
510 }
511 }
512
513 @Override
514 public void setSetting(String key, String value) {
515 ThemeSetting themeSetting = _themeSettingsMap.get(key);
516
517 if (themeSetting != null) {
518 themeSetting.setValue(value);
519 }
520 else {
521 addSetting(key, value, false, null, null, null);
522 }
523 }
524
525 @Override
526 public void setSpriteImages(
527 String spriteFileName, Properties spriteProperties) {
528
529 for (Map.Entry<Object, Object> entry : spriteProperties.entrySet()) {
530 String key = (String)entry.getKey();
531 String value = (String)entry.getValue();
532
533 int[] values = StringUtil.split(value, 0);
534
535 int offset = values[0];
536 int height = values[1];
537 int width = values[2];
538
539 SpriteImage spriteImage = new SpriteImage(
540 spriteFileName, key, offset, height, width);
541
542 _spriteImagesMap.put(key, spriteImage);
543 }
544 }
545
546 @Override
547 public void setTemplateExtension(String templateExtension) {
548 _templateExtension = templateExtension;
549 }
550
551 @Override
552 public void setTemplatesPath(String templatesPath) {
553 _templatesPath = templatesPath;
554 }
555
556 @Override
557 public void setThemeCompanyLimit(ThemeCompanyLimit themeCompanyLimit) {
558 _themeCompanyLimit = themeCompanyLimit;
559 }
560
561 @Override
562 public void setThemeGroupLimit(ThemeGroupLimit themeGroupLimit) {
563 _themeGroupLimit = themeGroupLimit;
564 }
565
566 @Override
567 public void setTimestamp(long timestamp) {
568 _timestamp = timestamp;
569 }
570
571 @Override
572 public void setVirtualPath(String virtualPath) {
573 if (_warFile && Validator.isNull(virtualPath)) {
574 virtualPath = PropsValues.THEME_VIRTUAL_PATH;
575 }
576
577 _virtualPath = virtualPath;
578 }
579
580 @Override
581 public void setWapTheme(boolean wapTheme) {
582 _wapTheme = wapTheme;
583 }
584
585 protected boolean isAvailable(ThemeCompanyLimit limit, long id) {
586 boolean available = true;
587
588 if (_log.isDebugEnabled()) {
589 _log.debug(
590 "Check if theme " + getThemeId() + " is available for " + id);
591 }
592
593 if (limit != null) {
594 List<ThemeCompanyId> includes = limit.getIncludes();
595 List<ThemeCompanyId> excludes = limit.getExcludes();
596
597 if (!includes.isEmpty() && !excludes.isEmpty()) {
598
599
600
601
602 if (_log.isDebugEnabled()) {
603 _log.debug("Check includes and excludes");
604 }
605
606 available = limit.isIncluded(id);
607
608 if (available) {
609 available = !limit.isExcluded(id);
610 }
611 }
612 else if (includes.isEmpty() && !excludes.isEmpty()) {
613
614
615
616
617 if (_log.isDebugEnabled()) {
618 _log.debug("Check excludes");
619 }
620
621 available = !limit.isExcluded(id);
622 }
623 else if (!includes.isEmpty() && excludes.isEmpty()) {
624
625
626
627
628 if (_log.isDebugEnabled()) {
629 _log.debug("Check includes");
630 }
631
632 available = limit.isIncluded(id);
633 }
634 else {
635
636
637
638
639 if (_log.isDebugEnabled()) {
640 _log.debug("No includes or excludes set");
641 }
642
643 available = true;
644 }
645 }
646
647 if (_log.isDebugEnabled()) {
648 _log.debug(
649 "Theme " + getThemeId() + " is " +
650 (!available ? "NOT " : "") + "available for " + id);
651 }
652
653 return available;
654 }
655
656 private static final Log _log = LogFactoryUtil.getLog(ThemeImpl.class);
657
658 private final Map<String, ColorScheme> _colorSchemesMap = new HashMap<>();
659 private boolean _controlPanelTheme;
660 private String _cssPath = "${root-path}/css";
661 private String _imagesPath = "${root-path}/images";
662 private String _javaScriptPath = "${root-path}/js";
663 private boolean _loadFromServletContext;
664 private String _name;
665 private boolean _pageTheme;
666 private final Map<String, Boolean> _resourceExistsMap =
667 new ConcurrentHashMap<>();
668 private final Map<String, String> _resourcePathsMap =
669 new ConcurrentHashMap<>();
670 private String _rootPath = "/";
671 private String _servletContextName = StringPool.BLANK;
672 private final Map<String, SpriteImage> _spriteImagesMap = new HashMap<>();
673 private String _templateExtension = "vm";
674 private String _templatesPath = "${root-path}/templates";
675 private ThemeCompanyLimit _themeCompanyLimit;
676 private ThemeGroupLimit _themeGroupLimit;
677 private final String _themeId;
678 private final Map<String, ThemeSetting> _themeSettingsMap =
679 new LinkedHashMap<>();
680 private long _timestamp;
681 private String _virtualPath = StringPool.BLANK;
682 private boolean _wapTheme;
683 private boolean _warFile;
684
685 }