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