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