/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.utils; import java.beans.PropertyDescriptor; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.servlet.ServletContext; import nl.strohalm.cyclos.entities.settings.AccessSettings; import nl.strohalm.cyclos.entities.settings.AlertSettings; import nl.strohalm.cyclos.entities.settings.LocalSettings; import nl.strohalm.cyclos.entities.settings.LogSettings; import nl.strohalm.cyclos.entities.settings.MailSettings; import nl.strohalm.cyclos.entities.settings.MailTranslation; import nl.strohalm.cyclos.entities.settings.MessageSettings; import nl.strohalm.cyclos.services.settings.SettingsService; import org.apache.commons.beanutils.PropertyUtils; import org.springframework.web.context.ServletContextAware; /** * Helper class for storing and retrieving settings from the web context * @author luis */ public class SettingsHelper implements ServletContextAware { /** * An object which behaves as a Map, but delegates calls to a settings object. This class is used by JSP's EL, which can invoke properties with * the same name as the settings object, but the target object itself is always returned by factory methods, like * {@link SettingsHelper#getLocalSettings(ServletContext)}, {@link SettingsHelper#getAccessSettings(ServletContext)} and so on. * @author luis */ private abstract static class SettingsProxyMap implements Map<String, Object> { private class SettingsProxyMapEntry implements Map.Entry<String, Object> { private final Object setting; private final String property; public SettingsProxyMapEntry(final Object setting, final String property) { this.setting = setting; this.property = property; } @Override public String getKey() { return property; } @Override public Object getValue() { return PropertyHelper.get(setting, property); } @Override public Object setValue(final Object value) { throw new UnsupportedOperationException(); } } private Set<String> properties; private SettingsProxyMap() { // Get the property names properties = new HashSet<String>(); final Object setting = getSetting(); final PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(setting); for (final PropertyDescriptor descriptor : descriptors) { // Both readable and writable properties if (descriptor.getReadMethod() != null) { properties.add(descriptor.getName()); } } } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public boolean containsKey(final Object key) { return properties.contains(key); } @Override public boolean containsValue(final Object value) { throw new UnsupportedOperationException(); } @Override public Set<Map.Entry<String, Object>> entrySet() { final Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>(); final Object setting = getSetting(); for (final String property : properties) { entries.add(new SettingsProxyMapEntry(setting, property)); } return entries; } @Override public Object get(final Object key) { if (!containsKey(key)) { throw new IllegalArgumentException("Property " + key + " is not available in " + getSetting().getClass()); } return PropertyHelper.get(getSetting(), key.toString()); } @Override public boolean isEmpty() { return size() == 0; } @Override public Set<String> keySet() { return Collections.unmodifiableSet(properties); } @Override public Object put(final String key, final Object value) { throw new UnsupportedOperationException(); } @Override public void putAll(final Map<? extends String, ? extends Object> m) { throw new UnsupportedOperationException(); } @Override public Object remove(final Object key) { throw new UnsupportedOperationException(); } @Override public int size() { return properties.size(); } @Override public Collection<Object> values() { throw new UnsupportedOperationException(); } protected abstract Object getSetting(); } public static final String ACCESS_KEY = "accessSettings"; public static final String ALERT_KEY = "alertSettings"; public static final String LOCAL_KEY = "localSettings"; public static final String LOG_KEY = "logSettings"; public static final String MAIL_KEY = "mailSettings"; public static final String MAIL_TRANSLATION_KEY = "mailTranslation"; public static final String MESSAGE_KEY = "messageSettings"; private SettingsService settingsService; @Override public void setServletContext(final ServletContext servletContext) { // Store a proxy for each setting type final Object accessProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getAccessSettings(); } }; servletContext.setAttribute(ACCESS_KEY, accessProxy); final Object alertProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getAlertSettings(); } }; servletContext.setAttribute(ALERT_KEY, alertProxy); final Object localProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getLocalSettings(); } }; servletContext.setAttribute(LOCAL_KEY, localProxy); final Object logProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getLogSettings(); } }; servletContext.setAttribute(LOG_KEY, logProxy); final Object mailProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getMailSettings(); } }; servletContext.setAttribute(MAIL_KEY, mailProxy); final Object mailTranslationProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getMailTranslation(); } }; servletContext.setAttribute(MAIL_TRANSLATION_KEY, mailTranslationProxy); final Object messageProxy = new SettingsProxyMap() { @Override protected Object getSetting() { return getMessageSettings(); } }; servletContext.setAttribute(MESSAGE_KEY, messageProxy); } public void setSettingsService(final SettingsService settingsService) { this.settingsService = settingsService; } private AccessSettings getAccessSettings() { return settingsService.getAccessSettings(); } private AlertSettings getAlertSettings() { return settingsService.getAlertSettings(); } private LocalSettings getLocalSettings() { return settingsService.getLocalSettings(); } private LogSettings getLogSettings() { return settingsService.getLogSettings(); } private MailSettings getMailSettings() { return settingsService.getMailSettings(); } private MailTranslation getMailTranslation() { return settingsService.getMailTranslation(); } private MessageSettings getMessageSettings() { return settingsService.getMessageSettings(); } }