Java tutorial
/* * Copyright (C) Mike Murphy 2003-2015 <mike.murphy@xmlactions.org><mwjmurphy@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.xmlactions.action.config; import java.io.Serializable; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.text.StrSubstitutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.xmlactions.action.ActionConsts; import org.xmlactions.action.actions.BaseAction; import org.xmlactions.common.locale.LocaleUtils; import org.xmlactions.common.theme.Theme; @SuppressWarnings("serial") //public abstract class ExecContext extends HashMap<String, Object> implements IExecContext { public abstract class ExecContext implements IExecContext, Serializable { private final static Logger log = LoggerFactory.getLogger(ExecContext.class); private ApplicationContext applicationContext; /** list of maps accessible using xxx:key where xxx reference maps.key */ private Map<String, Map<String, Object>> namedMaps = createMaps(); private Map<String, Object> rootMap = new HashMap<String, Object>(); private Map<String, Map<String, Object>> actionMaps = createActionMaps(); /** * @deprecated - use spring bean scope="session" or "request" */ public void copyTo(IExecContext dest) { dest.setApplicationContext(getApplicationContext()); // dest.setRootMap(getRootMap()); // why copy the root map dest.setActionMaps(getActionMaps()); Map<String, Object> map = dest.getActionMaps().get("request"); if (map != null) { map.clear(); } map = dest.getActionMaps().get(PERSISTENCE_MAP); if (map != null) { map.clear(); } dest.setNamedMaps(getNamedMaps()); Map<String, Map<String, Object>> maps = dest.getNamedMaps(); for (String key : maps.keySet()) { if (log.isDebugEnabled()) { log.debug("namedMaps key:" + key); } } Set<Entry<String, Object>> set = entrySet(); Iterator<Entry<String, Object>> iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); dest.put(entry.getKey(), entry.getValue()); if (log.isDebugEnabled()) { log.debug("key:" + entry.getKey()); } } set = rootMap.entrySet(); iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); dest.put(entry.getKey(), entry.getValue()); if (log.isDebugEnabled()) { log.debug("key:" + entry.getKey()); } } } private static Map<String, Map<String, Object>> createMaps() { Map<String, Map<String, Object>> maps = new HashMap<String, Map<String, Object>>(); maps.put(PERSISTENCE_MAP, new HashMap<String, Object>()); return maps; } private static Map<String, Map<String, Object>> createActionMaps() { Map<String, Map<String, Object>> maps = new HashMap<String, Map<String, Object>>(); maps.put(DEFAULT_ACTION_MAP, new HashMap<String, Object>()); return maps; } public ExecContext(List<Object> actionMaps, List<Object> localMaps, List<Object> themes) { if (actionMaps != null) { for (Object object : actionMaps) { if (object instanceof Map) { Map<String, String> map = (Map<String, String>) object; this.actionMaps.get(DEFAULT_ACTION_MAP).putAll(map); } else if (object instanceof Properties) { Properties props = (Properties) object; Enumeration enumeration = props.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); this.actionMaps.get(DEFAULT_ACTION_MAP).put(key, props.getProperty(key)); } } } } if (localMaps != null) { for (Object object : localMaps) { if (object instanceof Map) { Map<String, String> map = (Map<String, String>) object; this.putAll(map); } else if (object instanceof Properties) { Properties props = (Properties) object; Enumeration enumeration = props.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); this.put(key, props.getProperty(key)); } } else if (object instanceof XMLConfiguration) { addXmlConfiguration((XMLConfiguration) object); } } } if (themes != null) { for (Object object : themes) { if (object instanceof Theme) { addThemes((Theme) object); } else if (object instanceof Properties) { Properties props = (Properties) object; addThemes(props); } } } } /** * @deprecated - replaced with constructor ExecContext(List<Object> actionMaps, List<Object> localMaps, List<Object> themes) * @param actionMaps * @param localMaps */ public ExecContext(List<Object> actionMaps, List<Object> localMaps) { if (actionMaps != null) { for (Object object : actionMaps) { if (object instanceof Map) { Map<String, String> map = (Map<String, String>) object; this.actionMaps.get(DEFAULT_ACTION_MAP).putAll(map); } else if (object instanceof Properties) { Properties props = (Properties) object; Enumeration enumeration = props.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); this.actionMaps.get(DEFAULT_ACTION_MAP).put(key, props.getProperty(key)); } } } } if (localMaps != null) { for (Object object : localMaps) { if (object instanceof Map) { Map<String, String> map = (Map<String, String>) object; this.putAll(map); } else if (object instanceof Properties) { Properties props = (Properties) object; Enumeration enumeration = props.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); this.put(key, props.getProperty(key)); } } } } } public Object put(String key, Object value) { int index; if ((index = key.indexOf(':')) > 0 && index < key.length() - 1) { String mapKey = key.substring(0, index); Map<String, Object> selectedMap = getMap(mapKey); if (selectedMap == null) { selectedMap = new Hashtable<String, Object>(); namedMaps.put(mapKey, selectedMap); } if (selectedMap != null) { return selectedMap.put(key.substring(index + 1), value); } } return rootMap.put(key, value); } public String getString(String key) { return (String) get((Object) key); } public String getStringQuietly(String key) { String value = getString(key); if (value == null) return key; return (value); } /** * get a value for key. * <p> * if key has : as in xxx:key then find the value in a map assigned to the xxx in maps.<br/> * e.g. <code>get("session:id")</code> returns the value of <code>maps.get("session").get("id");</code> * </p> * <p> * if the key has "lang:key:resouces:language:country:variant" * <br/>or "lang:key" uses the default resource file and the default locale * <br/>or "lang:key:resource" uses the resource file and the default locale * <br/>or "lang:key::language" uses the default resource file and the language locale * <br/>... * </p> * <p> * if the key has "replace:value:regex:replacement" perform a String.replaceAll * <p> * The replacementPattern format is "replace:value:regex:replacement" * <br/>"replace" replacement instruction * <br/>"value" the string to perform the replacement on * <br/>"regex" the expression for the replacement * <br/>"replacement" the replacement value * </p> * </p> * * @return the value for key or null if not found. * */ public Object get(Object key) { int index; String k = (String) key; Validate.notEmpty(k, "Empty key passed as parameter for call to get(key)"); if ((index = k.indexOf(':')) > 0 && index < k.length() - 1) { if (index == LANG_REF.length() && k.startsWith(LANG_REF)) { return new LanguageLocale().getLang(this, k); } else if (index == REPLACE_REF.length() && k.startsWith(REPLACE_REF)) { return org.xmlactions.action.utils.StringUtils.replace(this, replace(k)); } else if (index == THEME_REF.length() && k.startsWith(THEME_REF)) { return getThemeValueQuietly(k.substring(index + 1)); } else if (index == APPLICATIONCONTEXT_REF.length() && k.startsWith(APPLICATIONCONTEXT_REF)) { return getApplicationContext().getBean(k.substring(index + 1)); } else { Map<String, Object> selectedMap = getMap(k.substring(0, index)); if (selectedMap != null) { Object obj = selectedMap.get(k.substring(index + 1)); if (obj != null && obj instanceof String) { String s = (String) obj; if (s.startsWith("${") && s.indexOf(k) == 2) { obj = "[" + k + "]"; } else { obj = replace((String) obj); } } return obj; } return null; } } else { if (rootMap.containsKey(key)) { Object obj = rootMap.get(key); if (obj != null && obj instanceof String) { obj = replace((String) obj); } return obj; } else { try { if (applicationContext != null) { Object obj = applicationContext.getBean((String) key); if (obj != null && obj instanceof String) { obj = replace((String) obj); } return obj; } } catch (Throwable t) { log.info(t.getMessage()); } return null; } } } /** * Looks for a named map in 2 places. 1) the applicationContext and 2) the namedMaps * @param key - used to find the map * @return the found map or null */ private Map<String, Object> getMap(String key) { Map<String, Object> map = null; if (applicationContext != null && applicationContext.containsBean(key)) { map = (Map<String, Object>) applicationContext.getBean(key); } if (map == null && namedMaps.containsKey(key)) { map = namedMaps.get(key); } return map; } public String replace(String content) { return StrSubstitutor.replace(content, this); } public String getLocalizedString(String resource, String key) { Validate.notEmpty(resource, "No Resource (locale file) has been set for call to getLocalIzedString(resource, [" + key + "]);"); try { ResourceBundle res = ResourceBundle.getBundle(resource); return res.getString(key); } catch (Exception ex) { // ignore the exception return "[" + key + "] " + "error[" + ex.getMessage() + "]"; } } public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } public ApplicationContext getApplicationContext() { return applicationContext; } /** * Stores a "key - value" into the persistence map. * <p> * if the Key contains a named map it will insert it into the named map instead. * </p> * <p> * Values may be retrieved using 'persistence:xxx' where persistence is the persistent named map. * </p> */ public void persist(String key, Object value) { getPersistenceMap().put(key, value); } /** * Get a persisted value from permanent storage * <p> * The permanent storage may be a HttpSession or database entry. Depends on how the persistence is managed. * </p> */ public Object getPersisted(String key) { return getPersistenceMap().get(key); } public Map<String, Object> getPersistenceMap() { return getNamedMap(PERSISTENCE_MAP); } public Map<String, Object> getNamedMap(String mapName) { return namedMaps.get(mapName); } public void addNamedMap(String mapName, Map<String, Object> map) { namedMaps.put(mapName, map); } public void addThemes(Properties props) { // String themeName = Theme.getThemeName(props); Theme theme = new Theme(props); // theme.setName(themeName); addThemes(theme); } public void addThemes(Theme newTheme) { if (get(DEFAULT_THEME_MAP) == null) { put(DEFAULT_THEME_MAP, newTheme); } else { Theme theme = (Theme) get(DEFAULT_THEME_MAP); theme.appendTheme(newTheme); } } public Theme getThemes() { if (get(DEFAULT_THEME_MAP) == null) { String error = LocaleUtils.getLocalizedString(ActionConsts.UXML_ACTION_LANG_FILE_NAME, ActionConsts.LANG_KEY_NO_THEME_SET); error = String.format(error, DEFAULT_THEME_MAP); throw new IllegalArgumentException(error); } return (Theme) get(DEFAULT_THEME_MAP); } public BaseAction getActionClass(String actionMapName, String actionKey) throws ClassNotFoundException, InstantiationException, IllegalAccessException { BaseAction action = null; String className = getAction(actionMapName, actionKey); if (StringUtils.isNotEmpty(className)) { Class<?> clas = ClassUtils.getClass(className); Object bean = clas.newInstance(); if (!(bean instanceof BaseAction)) { throw new InstantiationException("class [" + bean.getClass().getName() + " must extend [" + BaseAction.class.getName() + "]"); } action = (BaseAction) bean; } else { log.info("no action class found for [" + actionMapName + "][" + actionKey + "]"); // throw new IllegalArgumentException("no action class found for [" + actionMapName + "][" + actionKey + "]"); } return action; } /** * Returns a class that matches the xml action name. This differs from * the getActionClass in that it does not require the class to extend BaseAction. * @param actionMapName * @param actionKey * @return matching class * @throws ClassNotFoundException * @throws InstantiationException * @throws IllegalAccessException */ public Object getClassAsObject(String actionMapName, String actionKey) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Object bean = null; String className = getAction(actionMapName, actionKey); if (StringUtils.isNotEmpty(className)) { Class<?> clas = ClassUtils.getClass(className); bean = clas.newInstance(); } else { throw new IllegalArgumentException( "no action class found for [" + actionMapName + "][" + actionKey + "]"); } return bean; } public String getAction(String actionMapName, String actionKey) { String className = null; Map<String, Object> map; try { if (actionMapName == null) { map = actionMaps.get(DEFAULT_ACTION_MAP); } else { map = actionMaps.get(actionMapName); if (map == null) { return getAction(null, actionKey); } } if (map != null) { className = (String) map.get(actionKey); if (StringUtils.isEmpty(className)) { if (StringUtils.isNotEmpty(actionMapName)) { return getAction(null, actionKey); } } } return className; } catch (ClassCastException ex) { throw new IllegalArgumentException( ex.getMessage() + " - actionMapName[" + actionMapName + "] actionKey [" + actionKey + "]", ex); } } public void setDefaultLocaleFileName(String defaultLocaleFileName) { put(DEFAULT_LOCALE_FILE, defaultLocaleFileName); } /** * Remove any persistence settings before reloading session or cookie * persistence. * public void reset() { Map<String, Object> map = getPersistenceMap(); map.clear(); return; } */ /** * @deprecated does nothing don't make this call */ public void clear() { reset(); } public boolean containsKey(Object key) { return rootMap.containsKey(key); } public boolean containsValue(Object value) { return rootMap.containsValue(value); } public Set<java.util.Map.Entry<String, Object>> entrySet() { return rootMap.entrySet(); } public boolean isEmpty() { return rootMap.isEmpty(); } public Set<String> keySet() { return rootMap.keySet(); } public void putAll(Map<? extends String, ? extends Object> m) { rootMap.putAll(m); } public Object remove(Object key) { return rootMap.remove(key); } public int size() { return rootMap.size(); } public Collection<Object> values() { return rootMap.values(); } private Map<String, Object> convertPropertiesToMap(Properties props) { Map<String, Object> map = new HashMap<String, Object>(); for (Object key : props.keySet()) { map.put((String) key, props.get(key)); } return map; } public void addXmlConfig(String xmlResourceName) throws ConfigurationException { // log.debug("xmlResourceName:" + xmlResourceName); URL url = PropertyContainer.class.getResource(xmlResourceName); Validate.notNull(url, "Missing xml configuration file [" + xmlResourceName + "]"); XMLConfiguration config = new XMLConfiguration(url); addXmlConfiguration(config); } private void addXmlConfiguration(XMLConfiguration config) { Iterator<String> iterator = config.getKeys(); while (iterator.hasNext()) { String key = iterator.next(); // log.debug("key:" + key); this.put(key, config.getProperty(key)); } } public void addProperties(Properties props) { Map<String, Object> map = convertPropertiesToMap(props); putAll(map); } public void addMap(Map map) { putAll(map); } public void addActions(Properties props) { Map<String, Object> map = convertPropertiesToMap(props); this.actionMaps.get(DEFAULT_ACTION_MAP).putAll(map); } public void addActions(Map map) { this.actionMaps.get(DEFAULT_ACTION_MAP).putAll(map); } public void addNamedActions(String actionMapName, Properties props) { Map<String, Object> map = convertPropertiesToMap(props); Map<String, Object> actionMap = actionMaps.get(actionMapName); if (actionMap == null) { actionMap = new HashMap<String, Object>(); actionMaps.put(actionMapName, actionMap); } actionMap.putAll(map); } public void addNamedActions(String actionMapName, Map map) { Map<String, Object> actionMap = actionMaps.get(actionMapName); if (actionMap == null) { actionMap = new HashMap<String, Object>(); actionMaps.put(actionMapName, actionMap); } actionMap.putAll(map); } private List<String> notices = new ArrayList<String>(); public void addNotice(String msg) { this.notices.add(msg); } public void clearNotices() { this.notices = new ArrayList<String>(); } public Map<String, Object> getRootMap() { return rootMap; } public void setRootMap(Map<String, Object> rootMap) { this.rootMap = rootMap; } public Map<String, Map<String, Object>> getNamedMaps() { return namedMaps; } public void setNamedMaps(Map<String, Map<String, Object>> namedMaps) { this.namedMaps = namedMaps; } public Map<String, Map<String, Object>> getActionMaps() { return actionMaps; } public void setActionMaps(Map<String, Map<String, Object>> actionMaps) { this.actionMaps = actionMaps; } public String getThemeValueQuietly(String key) { Theme theme = getSelectedTheme(); if (theme != null) { String cssValue = theme.getValue(key); if (cssValue != null) { return cssValue; } } return key; } public Theme getSelectedTheme() { String selectedThemeName = getString(SELECTED_THEME_NAME); Theme theme = null; if (selectedThemeName != null) { theme = getThemes().getTheme(selectedThemeName); } if (theme == null) { selectedThemeName = getString(DEFAULT_THEME_NAME); theme = getThemes().getTheme(selectedThemeName); } return theme; } public String show() { StringBuilder sb = new StringBuilder("\n"); Map<String, Map<String, Object>> maps = getActionMaps(); for (String key : maps.keySet()) { sb.append("actionMaps:key[" + key + "]\n"); Map<String, Object> map = maps.get(key); for (String innerkey : map.keySet()) { sb.append(" " + key + ":key[" + innerkey + "] value[" + map.get(innerkey) + "]\n"); } } maps = getNamedMaps(); for (String key : maps.keySet()) { sb.append("namedMaps:key[" + key + "]\n"); Map<String, Object> map = maps.get(key); for (String innerkey : map.keySet()) { sb.append(" " + key + ":key[" + innerkey + "] value[" + map.get(innerkey) + "]\n"); } } Set<Entry<String, Object>> set = entrySet(); Iterator<Entry<String, Object>> iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); sb.append("key[" + entry.getKey() + "]\n"); } set = rootMap.entrySet(); iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); sb.append("key[" + entry.getKey() + "]\n"); } sb.append("themes\n"); sb.append("default_theme_name:" + DEFAULT_THEME_NAME); sb.append("default_theme_map:" + DEFAULT_THEME_MAP); return sb.toString(); } }