Java tutorial
/* * [y] hybris Platform * * Copyright (c) 2000-2015 hybris AG * All rights reserved. * * This software is the confidential and proprietary information of hybris * ("Confidential Information"). You shall not disclose such Confidential * Information and shall use it only in accordance with the terms of the * license agreement you entered into with hybris. * * */ package com.jnj.b2b.storefront.web.theme; import de.hybris.platform.acceleratorservices.addonsupport.RequiredAddOnsNameProvider; import de.hybris.platform.util.Utilities; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required; import org.springframework.context.ApplicationContext; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.support.AbstractMessageSource; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.core.io.ResourceLoader; import org.springframework.ui.context.Theme; import org.springframework.ui.context.ThemeSource; import org.springframework.ui.context.support.SimpleTheme; /** * CustomResourceBundleThemeSource. Supports site and theme specific resource bundles. Uses a * ReloadableResourceBundleMessageSource to load the theme file. Delegates to a message source if the theme specific * file cannot be found. */ public class StorefrontResourceBundleSource implements ThemeSource, ResourceLoaderAware, MessageSource { private static final Logger LOG = Logger.getLogger(StorefrontResourceBundleSource.class); private MessageSource parentMessageSource; private MessageSource lastMessageSource; private int cacheSeconds; private ResourceLoader resourceLoader; private boolean fallbackToSystemLocale; private String defaultEncoding; private String basenamePrefix; private String addonBasenamePrefix; private String basePrefix; private String sitePrefix; private String themePrefix; private RequiredAddOnsNameProvider requiredAddOnsNameProvider; @Autowired private ApplicationContext appContext; /** * Map from theme name to Theme instance */ private final Map<String, Theme> themeCache = new HashMap<String, Theme>(); protected MessageSource getParentMessageSource() { return parentMessageSource; } @Required public void setParentMessageSource(final MessageSource parentMessageSource) { this.parentMessageSource = parentMessageSource; } protected String getDefaultEncoding() { return defaultEncoding; } @Required public void setDefaultEncoding(final String defaultEncoding) { this.defaultEncoding = defaultEncoding; } public int getCacheSeconds() { return cacheSeconds; } @Required public void setCacheSeconds(final int cacheSeconds) { this.cacheSeconds = cacheSeconds; } public ResourceLoader getResourceLoader() { return resourceLoader; } public String getSitePrefix() { return sitePrefix; } @Required public void setSitePrefix(final String sitePrefix) { this.sitePrefix = sitePrefix; } public String getThemePrefix() { return themePrefix; } @Required public void setThemePrefix(final String themePrefix) { this.themePrefix = themePrefix; } @Override public void setResourceLoader(final ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public RequiredAddOnsNameProvider getRequiredAddOnsNameProvider() { return requiredAddOnsNameProvider; } @Required public void setRequiredAddOnsNameProvider(final RequiredAddOnsNameProvider requiredAddOnsNameProvider) { this.requiredAddOnsNameProvider = requiredAddOnsNameProvider; } /** * @param fallbackToSystemLocale * the fallbackToSystemLocale to set */ public void setFallbackToSystemLocale(final boolean fallbackToSystemLocale) { this.fallbackToSystemLocale = fallbackToSystemLocale; } public String getBasenamePrefix() { return basenamePrefix; } public String getAddonBasenamePrefix() { return addonBasenamePrefix; } @Required public void setAddonBasenamePrefix(final String addonBasenamePrefix) { this.addonBasenamePrefix = addonBasenamePrefix; } @Required public void setBasenamePrefix(final String basenamePrefix) { this.basenamePrefix = basenamePrefix; } public String getBasePrefix() { return basePrefix; } @Required public void setBasePrefix(final String basePrefix) { this.basePrefix = basePrefix; } /** * This implementation returns a SimpleTheme instance, holding a ResourceBundle-based MessageSource whose basename * corresponds to the given site name (prefixed by the configured "siteBasenamePrefix") which then delegates to a * ResourceBundle-based MessageSource whose basename corresponds to the theme name (prefixed by the configured * "themeBasenamePrefix") which in turn delegates to the {@link #getParentMessageSource()}. * * <p> * SimpleTheme instances are cached per theme name. * * <p> * Uses reloadable MessageSources to reflect changes to the underlying files. Set the {@link #setCacheSeconds(int)} * to control how long the files should be cached for. * * @param themeName * the theme name * @see #setSiteBasenamePrefix * @see #setThemeBasenamePrefix */ @Override public Theme getTheme(final String themeName) { if (themeName == null) { return null; } synchronized (this.themeCache) { // Look for the theme in the cache { final Theme theme = this.themeCache.get(themeName); if (theme != null) { return theme; } } // Split the theme name into site and theme parts final String[] strings = splitThemeName(themeName); final String uiExperiencePart = strings[0]; final String sitePart = strings[1]; final String themePart = strings[2]; final String siteBasename = getBasenamePrefix() + getSitePrefix() + "-" + sitePart; final String themeBasename = getBasenamePrefix() + getThemePrefix() + "-" + themePart; final String uiExperienceCode = uiExperiencePart.toLowerCase(); final List<String> addOnNames = requiredAddOnsNameProvider .getAddOns(StringUtils.remove(appContext.getApplicationName(), "/")); // Build the messages sources from most general to most specific final MessageSource addOnBaseMessageSrouce = createAddOnMessageSource(addOnNames, getParentMessageSource(), getBasePrefix()); final MessageSource themeMessageSource = createMessageSource(themeBasename, addOnBaseMessageSrouce); final MessageSource addOnThemeMessageSource = createAddOnMessageSource(addOnNames, themeMessageSource, getThemePrefix(), themePart); final MessageSource themeUiExperienceMessageSource = createMessageSource( themeBasename + "-" + uiExperienceCode, addOnThemeMessageSource); final MessageSource addOnThemeUiMessageSource = createAddOnMessageSource(addOnNames, themeUiExperienceMessageSource, getThemePrefix(), themePart, uiExperienceCode); final MessageSource siteMessageSource = createMessageSource(siteBasename, addOnThemeUiMessageSource); final MessageSource addOnSiteMessageSource = createAddOnMessageSource(addOnNames, siteMessageSource, getSitePrefix(), sitePart); final MessageSource siteUiExperienceMessageSource = createMessageSource( siteBasename + "-" + uiExperienceCode, addOnSiteMessageSource); final MessageSource addOnSiteUiMessageSource = createAddOnMessageSource(addOnNames, siteUiExperienceMessageSource, getSitePrefix(), sitePart, uiExperienceCode); lastMessageSource = addOnSiteUiMessageSource; // Create the new theme final Theme theme = new SimpleTheme(themeName, addOnSiteUiMessageSource); this.themeCache.put(themeName, theme); if (LOG.isDebugEnabled()) { LOG.debug("Theme created: name '" + themeName + "', iteBasename [" + siteBasename + "], themeBasename [" + themeBasename + "]"); } return theme; } } protected MessageSource createAddOnMessageSource(final List<String> addOnNames, final MessageSource parentMessageSource, final String... nameParts) { if (addOnNames.isEmpty()) { return parentMessageSource; } final StringBuffer nameBuffer = new StringBuffer(); for (final String part : nameParts) { nameBuffer.append(part); nameBuffer.append('-'); } String lastBasenamePart = nameBuffer.toString(); lastBasenamePart = lastBasenamePart.substring(0, lastBasenamePart.length() - 1); MessageSource messageSource = null; MessageSource tmpParentMessageSource = parentMessageSource; for (final String addOnName : addOnNames) { final String basename = getAddonBasenamePrefix() + addOnName + "/" + lastBasenamePart; if (LOG.isDebugEnabled()) { LOG.debug("AddOn message reource basename: " + basename); } messageSource = createMessageSource(basename, tmpParentMessageSource); tmpParentMessageSource = messageSource; } return messageSource; } protected String getExtensionNameForWebroot(final ApplicationContext appContext) { String extensionName = null; try { final String currentWebinfPath = appContext.getResource("/WEB-INF").getFile().getCanonicalPath(); final Map<String, String> installedWebModules = Utilities.getInstalledWebModules(); final Set<String> installedWebModuleNames = installedWebModules.keySet(); for (final String webModuleName : installedWebModuleNames) { final String webModuleWebinf = webModuleName + "/web/webroot/WEB-INF"; if (FilenameUtils.separatorsToUnix(currentWebinfPath).contains(webModuleWebinf)) { extensionName = webModuleName; break; } } } catch (final IOException e) { if (LOG.isDebugEnabled()) { LOG.debug("No WEB-INF found"); } } return extensionName; } protected String[] splitThemeName(final String themeName) { return themeName.split(",", 3); } protected MessageSource createMessageSource(final String basename, final MessageSource parentMessageSource) { final AbstractMessageSource messageSource = createMessageSource(basename); messageSource.setParentMessageSource(parentMessageSource); messageSource.setUseCodeAsDefaultMessage(true); return messageSource; } protected AbstractMessageSource createMessageSource(final String basename) { final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename(basename); messageSource.setCacheSeconds(getCacheSeconds()); messageSource.setResourceLoader(getResourceLoader()); messageSource.setFallbackToSystemLocale(fallbackToSystemLocale); messageSource.setDefaultEncoding(getDefaultEncoding()); return messageSource; } @Override public String getMessage(final String code, final Object[] args, final String defaultMessage, final Locale locale) { if (lastMessageSource != null) { return lastMessageSource.getMessage(code, args, defaultMessage, locale); } return getParentMessageSource().getMessage(code, args, defaultMessage, locale); } @Override public String getMessage(final String code, final Object[] args, final Locale locale) throws NoSuchMessageException { return this.getMessage(code, args, null, locale); } @Override public String getMessage(final MessageSourceResolvable resolvable, final Locale locale) throws NoSuchMessageException { if (lastMessageSource != null) { return lastMessageSource.getMessage(resolvable, locale); } return getParentMessageSource().getMessage(resolvable, locale); } }