001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.image.SpriteProcessorUtil;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.plugin.PluginPackage;
022    import com.liferay.portal.kernel.plugin.Version;
023    import com.liferay.portal.kernel.servlet.ServletContextUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.ListUtil;
026    import com.liferay.portal.kernel.util.ReleaseInfo;
027    import com.liferay.portal.kernel.util.ServerDetector;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.xml.Document;
032    import com.liferay.portal.kernel.xml.Element;
033    import com.liferay.portal.kernel.xml.SAXReaderUtil;
034    import com.liferay.portal.model.ColorScheme;
035    import com.liferay.portal.model.PluginSetting;
036    import com.liferay.portal.model.PortletConstants;
037    import com.liferay.portal.model.Theme;
038    import com.liferay.portal.model.impl.ColorSchemeImpl;
039    import com.liferay.portal.model.impl.ThemeImpl;
040    import com.liferay.portal.plugin.PluginUtil;
041    import com.liferay.portal.service.base.ThemeLocalServiceBaseImpl;
042    import com.liferay.portal.theme.ThemeCompanyId;
043    import com.liferay.portal.theme.ThemeCompanyLimit;
044    import com.liferay.portal.theme.ThemeGroupId;
045    import com.liferay.portal.theme.ThemeGroupLimit;
046    import com.liferay.portal.util.PortalUtil;
047    import com.liferay.util.ContextReplace;
048    
049    import java.io.File;
050    
051    import java.util.ArrayList;
052    import java.util.HashSet;
053    import java.util.Iterator;
054    import java.util.List;
055    import java.util.Map;
056    import java.util.Properties;
057    import java.util.Set;
058    import java.util.concurrent.ConcurrentHashMap;
059    
060    import javax.servlet.ServletContext;
061    
062    /**
063     * @author Brian Wing Shun Chan
064     * @author Jorge Ferrer
065     */
066    public class ThemeLocalServiceImpl extends ThemeLocalServiceBaseImpl {
067    
068            public ColorScheme getColorScheme(
069                            long companyId, String themeId, String colorSchemeId,
070                            boolean wapTheme)
071                    throws SystemException {
072    
073                    colorSchemeId = GetterUtil.getString(colorSchemeId);
074    
075                    Theme theme = getTheme(companyId, themeId, wapTheme);
076    
077                    Map<String, ColorScheme> colorSchemesMap = theme.getColorSchemesMap();
078    
079                    ColorScheme colorScheme = colorSchemesMap.get(colorSchemeId);
080    
081                    if (colorScheme == null) {
082                            List<ColorScheme> colorSchemes = theme.getColorSchemes();
083    
084                            if (colorSchemes.size() > 0) {
085                                    for (int i = (colorSchemes.size() - 1); i >= 0; i--) {
086                                            colorScheme = colorSchemes.get(i);
087    
088                                            if (colorScheme.isDefaultCs()) {
089                                                    break;
090                                            }
091                                    }
092                            }
093                    }
094    
095                    if (colorScheme == null) {
096                            if (wapTheme) {
097                                    colorSchemeId = ColorSchemeImpl.getDefaultWapColorSchemeId();
098                            }
099                            else {
100                                    colorSchemeId =
101                                            ColorSchemeImpl.getDefaultRegularColorSchemeId();
102                            }
103                    }
104    
105                    if (colorScheme == null) {
106                            colorScheme = ColorSchemeImpl.getNullColorScheme();
107                    }
108    
109                    return colorScheme;
110            }
111    
112            public Theme getTheme(long companyId, String themeId, boolean wapTheme)
113                    throws SystemException {
114    
115                    themeId = GetterUtil.getString(themeId);
116    
117                    Theme theme = _getThemes(companyId).get(themeId);
118    
119                    if (theme == null) {
120                            if (_log.isWarnEnabled()) {
121                                    _log.warn(
122                                            "No theme found for specified theme id " + themeId +
123                                                    ". Returning the default theme.");
124                            }
125    
126                            if (wapTheme) {
127                                    themeId = ThemeImpl.getDefaultWapThemeId(companyId);
128                            }
129                            else {
130                                    themeId = ThemeImpl.getDefaultRegularThemeId(companyId);
131                            }
132    
133                            theme = _themes.get(themeId);
134                    }
135    
136                    if (theme == null) {
137                            if (_themes.isEmpty()) {
138                                    if (_log.isDebugEnabled()) {
139                                            _log.debug("No themes are installed");
140                                    }
141    
142                                    return null;
143                            }
144    
145                            _log.error(
146                                    "No theme found for default theme id " + themeId +
147                                            ". Returning a random theme.");
148    
149                            Iterator<Map.Entry<String, Theme>> itr =
150                                    _themes.entrySet().iterator();
151    
152                            while (itr.hasNext()) {
153                                    Map.Entry<String, Theme> entry = itr.next();
154    
155                                    theme = entry.getValue();
156                            }
157                    }
158    
159                    return theme;
160            }
161    
162            public List<Theme> getThemes(long companyId) {
163                    List<Theme> themes = ListUtil.fromCollection(
164                            _getThemes(companyId).values());
165    
166                    return ListUtil.sort(themes);
167            }
168    
169            public List<Theme> getThemes(
170                            long companyId, long groupId, long userId, boolean wapTheme)
171                    throws SystemException {
172    
173                    List<Theme> themes = getThemes(companyId);
174    
175                    themes = (List<Theme>)PluginUtil.restrictPlugins(
176                            themes, companyId, userId);
177    
178                    Iterator<Theme> itr = themes.iterator();
179    
180                    while (itr.hasNext()) {
181                            Theme theme = itr.next();
182    
183                            if ((theme.getThemeId().equals("controlpanel")) ||
184                                    (!theme.isGroupAvailable(groupId)) ||
185                                    (theme.isWapTheme() != wapTheme)) {
186    
187                                    itr.remove();
188                            }
189                    }
190    
191                    return themes;
192            }
193    
194            public List<Theme> getWARThemes() {
195                    List<Theme> themes = ListUtil.fromCollection(_themes.values());
196    
197                    Iterator<Theme> itr = themes.iterator();
198    
199                    while (itr.hasNext()) {
200                            Theme theme = itr.next();
201    
202                            if (!theme.isWARFile()) {
203                                    itr.remove();
204                            }
205                    }
206    
207                    return themes;
208            }
209    
210            public List<String> init(
211                    ServletContext servletContext, String themesPath,
212                    boolean loadFromServletContext, String[] xmls,
213                    PluginPackage pluginPackage) {
214    
215                    return init(
216                            null, servletContext, themesPath, loadFromServletContext, xmls,
217                            pluginPackage);
218            }
219    
220            public List<String> init(
221                    String servletContextName, ServletContext servletContext,
222                    String themesPath, boolean loadFromServletContext, String[] xmls,
223                    PluginPackage pluginPackage) {
224    
225                    List<String> themeIds = new ArrayList<String>();
226    
227                    try {
228                            for (int i = 0; i < xmls.length; i++) {
229                                    Set<String> themes = _readThemes(
230                                            servletContextName, servletContext, themesPath,
231                                            loadFromServletContext, xmls[i], pluginPackage);
232    
233                                    Iterator<String> itr = themes.iterator();
234    
235                                    while (itr.hasNext()) {
236                                            String themeId = itr.next();
237    
238                                            if (!themeIds.contains(themeId)) {
239                                                    themeIds.add(themeId);
240                                            }
241                                    }
242                            }
243                    }
244                    catch (Exception e) {
245                            e.printStackTrace();
246                    }
247    
248                    _themesPool.clear();
249    
250                    return themeIds;
251            }
252    
253            public void uninstallThemes(List<String> themeIds) {
254                    for (int i = 0; i < themeIds.size(); i++) {
255                            String themeId = themeIds.get(i);
256    
257                            _themes.remove(themeId);
258    
259                            layoutTemplateLocalService.uninstallLayoutTemplates(themeId);
260                    }
261    
262                    _themesPool.clear();
263            }
264    
265            private List<ThemeCompanyId> _getCompanyLimitExcludes(Element el) {
266                    List<ThemeCompanyId> includes = new ArrayList<ThemeCompanyId>();
267    
268                    if (el != null) {
269                            List<Element> companyIds = el.elements("company-id");
270    
271                            for (int i = 0; i < companyIds.size(); i++) {
272                                    Element companyIdEl = companyIds.get(i);
273    
274                                    String name = companyIdEl.attributeValue("name");
275                                    String pattern = companyIdEl.attributeValue("pattern");
276    
277                                    ThemeCompanyId themeCompanyId = null;
278    
279                                    if (Validator.isNotNull(name)) {
280                                            themeCompanyId = new ThemeCompanyId(name, false);
281                                    }
282                                    else if (Validator.isNotNull(pattern)) {
283                                            themeCompanyId = new ThemeCompanyId(pattern, true);
284                                    }
285    
286                                    if (themeCompanyId != null) {
287                                            includes.add(themeCompanyId);
288                                    }
289                            }
290                    }
291    
292                    return includes;
293            }
294    
295            private List<ThemeCompanyId> _getCompanyLimitIncludes(Element el) {
296                    return _getCompanyLimitExcludes(el);
297            }
298    
299            private List<ThemeGroupId> _getGroupLimitExcludes(Element el) {
300                    List<ThemeGroupId> includes = new ArrayList<ThemeGroupId>();
301    
302                    if (el != null) {
303                            List<Element> groupIds = el.elements("group-id");
304    
305                            for (int i = 0; i < groupIds.size(); i++) {
306                                    Element groupIdEl = groupIds.get(i);
307    
308                                    String name = groupIdEl.attributeValue("name");
309                                    String pattern = groupIdEl.attributeValue("pattern");
310    
311                                    ThemeGroupId themeGroupId = null;
312    
313                                    if (Validator.isNotNull(name)) {
314                                            themeGroupId = new ThemeGroupId(name, false);
315                                    }
316                                    else if (Validator.isNotNull(pattern)) {
317                                            themeGroupId = new ThemeGroupId(pattern, true);
318                                    }
319    
320                                    if (themeGroupId != null) {
321                                            includes.add(themeGroupId);
322                                    }
323                            }
324                    }
325    
326                    return includes;
327            }
328    
329            private List<ThemeGroupId> _getGroupLimitIncludes(Element el) {
330                    return _getGroupLimitExcludes(el);
331            }
332    
333            private Map<String, Theme> _getThemes(long companyId) {
334                    Map<String, Theme> themes = _themesPool.get(companyId);
335    
336                    if (themes == null) {
337                            themes = new ConcurrentHashMap<String, Theme>();
338    
339                            Iterator<Map.Entry<String, Theme>> itr =
340                                    _themes.entrySet().iterator();
341    
342                            while (itr.hasNext()) {
343                                    Map.Entry<String, Theme> entry = itr.next();
344    
345                                    String themeId = entry.getKey();
346                                    Theme theme = entry.getValue();
347    
348                                    if (theme.isCompanyAvailable(companyId)) {
349                                            themes.put(themeId, theme);
350                                    }
351                            }
352    
353                            _themesPool.put(companyId, themes);
354                    }
355    
356                    return themes;
357            }
358    
359            private Version _getVersion(String version) {
360                    if (version.equals("${current-version}")) {
361                            version = ReleaseInfo.getVersion();
362                    }
363    
364                    return Version.getInstance(version);
365            }
366    
367            private void _readColorSchemes(
368                    Element theme, Map<String, ColorScheme> colorSchemes,
369                    ContextReplace themeContextReplace) {
370    
371                    Iterator<Element> itr = theme.elements("color-scheme").iterator();
372    
373                    while (itr.hasNext()) {
374                            Element colorScheme = itr.next();
375    
376                            ContextReplace colorSchemeContextReplace =
377                                    (ContextReplace)themeContextReplace.clone();
378    
379                            String id = colorScheme.attributeValue("id");
380    
381                            colorSchemeContextReplace.addValue("color-scheme-id", id);
382    
383                            ColorScheme colorSchemeModel = colorSchemes.get(id);
384    
385                            if (colorSchemeModel == null) {
386                                    colorSchemeModel = new ColorSchemeImpl(id);
387                            }
388    
389                            String name = GetterUtil.getString(
390                                    colorScheme.attributeValue("name"), colorSchemeModel.getName());
391    
392                            name = colorSchemeContextReplace.replace(name);
393    
394                            boolean defaultCs = GetterUtil.getBoolean(
395                                    colorScheme.elementText("default-cs"),
396                                    colorSchemeModel.isDefaultCs());
397    
398                            String cssClass = GetterUtil.getString(
399                                    colorScheme.elementText("css-class"),
400                                    colorSchemeModel.getCssClass());
401    
402                            cssClass = colorSchemeContextReplace.replace(cssClass);
403    
404                            colorSchemeContextReplace.addValue("css-class", cssClass);
405    
406                            String colorSchemeImagesPath = GetterUtil.getString(
407                                    colorScheme.elementText("color-scheme-images-path"),
408                                    colorSchemeModel.getColorSchemeImagesPath());
409    
410                            colorSchemeImagesPath = colorSchemeContextReplace.replace(
411                                    colorSchemeImagesPath);
412    
413                            colorSchemeContextReplace.addValue(
414                                    "color-scheme-images-path", colorSchemeImagesPath);
415    
416                            colorSchemeModel.setName(name);
417                            colorSchemeModel.setDefaultCs(defaultCs);
418                            colorSchemeModel.setCssClass(cssClass);
419                            colorSchemeModel.setColorSchemeImagesPath(colorSchemeImagesPath);
420    
421                            colorSchemes.put(id, colorSchemeModel);
422                    }
423            }
424    
425            private Set<String> _readThemes(
426                            String servletContextName, ServletContext servletContext,
427                            String themesPath, boolean loadFromServletContext, String xml,
428                            PluginPackage pluginPackage)
429                    throws Exception {
430    
431                    Set<String> themeIds = new HashSet<String>();
432    
433                    if (xml == null) {
434                            return themeIds;
435                    }
436    
437                    Document doc = SAXReaderUtil.read(xml, true);
438    
439                    Element root = doc.getRootElement();
440    
441                    Version portalVersion = _getVersion(ReleaseInfo.getVersion());
442    
443                    boolean compatible = false;
444    
445                    Element compatibilityEl = root.element("compatibility");
446    
447                    if (compatibilityEl != null) {
448                            Iterator<Element> itr = compatibilityEl.elements(
449                                    "version").iterator();
450    
451                            while (itr.hasNext()) {
452                                    Element versionEl = itr.next();
453    
454                                    Version version = _getVersion(versionEl.getTextTrim());
455    
456                                    if (version.includes(portalVersion)) {
457                                            compatible = true;
458    
459                                            break;
460                                    }
461                            }
462                    }
463    
464                    if (!compatible) {
465                            _log.error(
466                                    "Themes in this WAR are not compatible with " +
467                                            ReleaseInfo.getServerInfo());
468    
469                            return themeIds;
470                    }
471    
472                    ThemeCompanyLimit companyLimit = null;
473    
474                    Element companyLimitEl = root.element("company-limit");
475    
476                    if (companyLimitEl != null) {
477                            companyLimit = new ThemeCompanyLimit();
478    
479                            Element companyIncludesEl =
480                                    companyLimitEl.element("company-includes");
481    
482                            if (companyIncludesEl != null) {
483                                    companyLimit.setIncludes(
484                                            _getCompanyLimitIncludes(companyIncludesEl));
485                            }
486    
487                            Element companyExcludesEl =
488                                    companyLimitEl.element("company-excludes");
489    
490                            if (companyExcludesEl != null) {
491                                    companyLimit.setExcludes(
492                                            _getCompanyLimitExcludes(companyExcludesEl));
493                            }
494                    }
495    
496                    ThemeGroupLimit groupLimit = null;
497    
498                    Element groupLimitEl = root.element("group-limit");
499    
500                    if (groupLimitEl != null) {
501                            groupLimit = new ThemeGroupLimit();
502    
503                            Element groupIncludesEl = groupLimitEl.element("group-includes");
504    
505                            if (groupIncludesEl != null) {
506                                    groupLimit.setIncludes(_getGroupLimitIncludes(groupIncludesEl));
507                            }
508    
509                            Element groupExcludesEl =
510                                    groupLimitEl.element("group-excludes");
511    
512                            if (groupExcludesEl != null) {
513                                    groupLimit.setExcludes(_getGroupLimitExcludes(groupExcludesEl));
514                            }
515                    }
516    
517                    long timestamp = ServletContextUtil.getLastModified(servletContext);
518    
519                    Iterator<Element> itr1 = root.elements("theme").iterator();
520    
521                    while (itr1.hasNext()) {
522                            Element theme = itr1.next();
523    
524                            ContextReplace themeContextReplace = new ContextReplace();
525    
526                            themeContextReplace.addValue("themes-path", themesPath);
527    
528                            String themeId = theme.attributeValue("id");
529    
530                            if (servletContextName != null) {
531                                    themeId =
532                                            themeId + PortletConstants.WAR_SEPARATOR +
533                                                    servletContextName;
534                            }
535    
536                            themeId = PortalUtil.getJsSafePortletId(themeId);
537    
538                            themeContextReplace.addValue("theme-id", themeId);
539    
540                            themeIds.add(themeId);
541    
542                            Theme themeModel = _themes.get(themeId);
543    
544                            if (themeModel == null) {
545                                    themeModel = new ThemeImpl(themeId);
546    
547                                    _themes.put(themeId, themeModel);
548                            }
549    
550                            themeModel.setTimestamp(timestamp);
551    
552                            PluginSetting pluginSetting =
553                                    pluginSettingLocalService.getDefaultPluginSetting();
554    
555                            themeModel.setPluginPackage(pluginPackage);
556                            themeModel.setDefaultPluginSetting(pluginSetting);
557    
558                            themeModel.setThemeCompanyLimit(companyLimit);
559                            themeModel.setThemeGroupLimit(groupLimit);
560    
561                            if (servletContextName != null) {
562                                    themeModel.setServletContextName(servletContextName);
563                            }
564    
565                            themeModel.setLoadFromServletContext(loadFromServletContext);
566    
567                            String name = GetterUtil.getString(
568                                    theme.attributeValue("name"), themeModel.getName());
569    
570                            String rootPath = GetterUtil.getString(
571                                    theme.elementText("root-path"), themeModel.getRootPath());
572    
573                            rootPath = themeContextReplace.replace(rootPath);
574    
575                            themeContextReplace.addValue("root-path", rootPath);
576    
577                            String templatesPath = GetterUtil.getString(
578                                    theme.elementText("templates-path"),
579                                    themeModel.getTemplatesPath());
580    
581                            templatesPath = themeContextReplace.replace(templatesPath);
582                            templatesPath = StringUtil.safePath(templatesPath);
583    
584                            themeContextReplace.addValue("templates-path", templatesPath);
585    
586                            String cssPath = GetterUtil.getString(
587                                    theme.elementText("css-path"), themeModel.getCssPath());
588    
589                            cssPath = themeContextReplace.replace(cssPath);
590                            cssPath = StringUtil.safePath(cssPath);
591    
592                            themeContextReplace.addValue("css-path", cssPath);
593    
594                            String imagesPath = GetterUtil.getString(
595                                    theme.elementText("images-path"),
596                                    themeModel.getImagesPath());
597    
598                            imagesPath = themeContextReplace.replace(imagesPath);
599                            imagesPath = StringUtil.safePath(imagesPath);
600    
601                            themeContextReplace.addValue("images-path", imagesPath);
602    
603                            String javaScriptPath = GetterUtil.getString(
604                                    theme.elementText("javascript-path"),
605                                    themeModel.getJavaScriptPath());
606    
607                            javaScriptPath = themeContextReplace.replace(javaScriptPath);
608                            javaScriptPath = StringUtil.safePath(javaScriptPath);
609    
610                            themeContextReplace.addValue("javascript-path", javaScriptPath);
611    
612                            String virtualPath = GetterUtil.getString(
613                                    theme.elementText("virtual-path"), themeModel.getVirtualPath());
614    
615                            String templateExtension = GetterUtil.getString(
616                                    theme.elementText("template-extension"),
617                                    themeModel.getTemplateExtension());
618    
619                            themeModel.setName(name);
620                            themeModel.setRootPath(rootPath);
621                            themeModel.setTemplatesPath(templatesPath);
622                            themeModel.setCssPath(cssPath);
623                            themeModel.setImagesPath(imagesPath);
624                            themeModel.setJavaScriptPath(javaScriptPath);
625                            themeModel.setVirtualPath(virtualPath);
626                            themeModel.setTemplateExtension(templateExtension);
627    
628                            Element settingsEl = theme.element("settings");
629    
630                            if (settingsEl != null) {
631                                    Iterator<Element> itr2 = settingsEl.elements(
632                                            "setting").iterator();
633    
634                                    while (itr2.hasNext()) {
635                                            Element settingEl = itr2.next();
636    
637                                            String key = settingEl.attributeValue("key");
638                                            String value = settingEl.attributeValue("value");
639    
640                                            themeModel.setSetting(key, value);
641                                    }
642                            }
643    
644                            themeModel.setWapTheme(GetterUtil.getBoolean(
645                                    theme.elementText("wap-theme"), themeModel.isWapTheme()));
646    
647                            Element rolesEl = theme.element("roles");
648    
649                            if (rolesEl != null) {
650                                    Iterator<Element> itr2 = rolesEl.elements(
651                                            "role-name").iterator();
652    
653                                    while (itr2.hasNext()) {
654                                            Element roleNameEl = itr2.next();
655    
656                                            pluginSetting.addRole(roleNameEl.getText());
657                                    }
658                            }
659    
660                            _readColorSchemes(
661                                    theme, themeModel.getColorSchemesMap(), themeContextReplace);
662                            _readColorSchemes(
663                                    theme, themeModel.getColorSchemesMap(), themeContextReplace);
664    
665                            Element layoutTemplatesEl = theme.element("layout-templates");
666    
667                            if (layoutTemplatesEl != null) {
668                                    Element standardEl = layoutTemplatesEl.element("standard");
669    
670                                    if (standardEl != null) {
671                                            layoutTemplateLocalService.readLayoutTemplate(
672                                                    servletContextName, servletContext, null,
673                                                    standardEl, true, themeId, pluginPackage);
674                                    }
675    
676                                    Element customEl = layoutTemplatesEl.element("custom");
677    
678                                    if (customEl != null) {
679                                            layoutTemplateLocalService.readLayoutTemplate(
680                                                    servletContextName, servletContext, null,
681                                                    customEl, false, themeId, pluginPackage);
682                                    }
683                            }
684    
685                            if (!themeModel.isWapTheme()) {
686                                    _setSpriteImages(servletContext, themeModel, imagesPath);
687                            }
688                    }
689    
690                    return themeIds;
691            }
692    
693            private void _setSpriteImages(
694                            ServletContext servletContext, Theme theme, String resourcePath)
695                    throws Exception {
696    
697                    Set<String> resourcePaths = servletContext.getResourcePaths(
698                            resourcePath);
699    
700                    if (resourcePaths == null) {
701                            return;
702                    }
703    
704                    List<File> images = new ArrayList<File>(resourcePaths.size());
705    
706                    for (String curResourcePath : resourcePaths) {
707                            if (curResourcePath.endsWith(StringPool.SLASH)) {
708                                    _setSpriteImages(servletContext, theme, curResourcePath);
709                            }
710                            else if (curResourcePath.endsWith(".png")) {
711                                    String realPath = ServletContextUtil.getRealPath(
712                                            servletContext, curResourcePath);
713    
714                                    if (realPath != null) {
715                                            images.add(new File(realPath));
716                                    }
717                                    else {
718                                            if (ServerDetector.isTomcat()) {
719                                                    if (_log.isInfoEnabled()) {
720                                                            _log.info(ServletContextUtil.LOG_INFO_SPRITES);
721                                                    }
722                                            }
723                                            else {
724                                                    _log.error(
725                                                            "Real path for " + curResourcePath + " is null");
726                                            }
727                                    }
728                            }
729                    }
730    
731                    String spriteFileName = ".sprite.png";
732                    String spritePropertiesFileName = ".sprite.properties";
733                    String spritePropertiesRootPath = ServletContextUtil.getRealPath(
734                            servletContext, theme.getImagesPath());
735    
736                    Properties spriteProperties = SpriteProcessorUtil.generate(
737                            images, spriteFileName, spritePropertiesFileName,
738                            spritePropertiesRootPath, 16, 16, 10240);
739    
740                    if (spriteProperties == null) {
741                            return;
742                    }
743    
744                    spriteFileName =
745                            resourcePath.substring(
746                                    theme.getImagesPath().length(), resourcePath.length()) +
747                            spriteFileName;
748    
749                    theme.setSpriteImages(spriteFileName, spriteProperties);
750            }
751    
752            private static Log _log = LogFactoryUtil.getLog(
753                    ThemeLocalServiceImpl.class);
754    
755            private static Map<String, Theme> _themes =
756                    new ConcurrentHashMap<String, Theme>();
757            private static Map<Long, Map<String, Theme>> _themesPool =
758                    new ConcurrentHashMap<Long, Map<String, Theme>>();
759    
760    }