/** * XWeb project * Created by Hamed Abdollahpour * https://github.com/abdollahpour/xweb */ package ir.xweb.module; import ir.xweb.util.Tools; import java.io.File; import java.lang.String; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; public class ModuleParam implements Map<String, Object>, Cloneable { /** * We have 3 data, String, collection and ModuleParam */ private final HashMap<String, Object> data; public ModuleParam() { this((Map<String, Object>) null); } public ModuleParam(final Map<String, Object> data) { if (data != null) { final HashMap<String, Object> m = new HashMap<String, Object>(); m.putAll(data); this.data = (HashMap<String, Object>) m.clone(); } else { this.data = new HashMap<String, Object>(); } } protected ModuleParam(final ModuleParam m) { this(m == null ? null : m.data); } /*protected void put(final String name, final String value, final boolean isDefault) { final Object oldValue = data.put(name, value); if(isDefault) { defaults.add(name); } else if(oldValue != null) { defaults.remove(name); } }*/ public String get(String name, String def) { return getString(name, def); } private <T> T get(final Class<T> clazz, final String name, final T def) { final Object o = this.data.get(name); if(o != null) { if(clazz.isInstance(o)) { return clazz.cast(o); } } return def; } public String getString(final String name, final String def) { return getString(name, null, def); } public String getString(final String name, final String glue, final String def) { final Object o = this.data.get(name); if(o != null) { if(o instanceof String) { final String s = (String)o; if(s.length() > 0) { return s; } } if(glue != null) { if(o instanceof Collection) { return Tools.implode(glue, (Collection) o); } } return o.toString(); } return def; } public String getString(final String name) { return getString(name, null); } public String[] getStrings(final String name, final char... separator) { return getStrings(name, new String[0], separator); } public String[] getStrings(final String name, final String[] def, final char... separator) { final Collection list = get(Collection.class, name, null); if(list != null && list.size() > 0) { final String[] strings = new String[list.size()]; final Iterator iterator = list.iterator(); for(int i=0; i<strings.length; i++) { strings[i] = iterator.next().toString(); } return strings; } final String value = getString(name); if(value != null && value.length() > 0) { if(separator.length > 0) { // create splitter regex final String imploded = new String(separator); final String regex = "[" + imploded.replaceAll("([^a-zA-z0-9])", "\\\\$1") + "]+"; final String[] strings = value.split(regex); return strings; } else { return new String[]{value}; } } return def; } public Integer getInt(final String name, final Integer def) { final Integer i = get(Integer.class, name, null); if(i != null) { return i; } final String s = getString(name); if(s != null && s.length() > 0) { return Integer.parseInt(s); } return def; } public Integer getInt(final String name) { return getInt(name, null); } public Float getFloat(final String name, final Float def) { final Float f = get(Float.class, name, null); if(f != null) { return f; } final String s = getString(name); if(s != null && s.length() > 0) { return Float.parseFloat(s); } return def; } public Float getFloat(final String name) { return getFloat(name, null); } public Double getDouble(final String name, final Double def) { final Double d = get(Double.class, name, null); if(d != null) { return d; } final String s = getString(name); if(s != null && s.length() > 0) { return Double.parseDouble(s); } return def; } public Double getDouble(final String name) { return getDouble(name, null); } public Long getLong(final String name, final Long def) { final Long l = get(Long.class, name, null); if(l != null) { return l; } final String s = getString(name); if(s != null && s.length() > 0) { return Long.parseLong(s); } return def; } public Long getLong(final String name) { return getLong(name, (Long)null); } public Long[] getLongs(final String name, final char... separator) { return getLongs(name, new Long[0], separator); } public Long[] getLongs(final String name, final Long[] def, final char... separator) { final Collection list = get(Collection.class, name, null); if(list != null && list.size() > 0) { final Iterator iterator = list.iterator(); final Object o = iterator.next(); if(o instanceof Long) { final Long[] longs = new Long[list.size()]; longs[0] = (Long)o; for(int i=1; i<longs.length; i++) { longs[i] = (Long)iterator.next(); } } } final String[] strings = getStrings(name, separator); if(strings != null && strings.length > 0) { final Long[] longs = new Long[strings.length]; for(int i=0; i<strings.length; i++) { longs[i] = Long.parseLong(strings[i]); } return longs; } return def; } public Double[] getDoubles(final String name, final char... separator) { return getDoubles(name, new Double[0], separator); } public Double[] getDoubles(final String name, final Double[] def, final char... separator) { final Collection list = get(Collection.class, name, null); if(list != null && list.size() > 0) { final Iterator iterator = list.iterator(); final Object o = iterator.next(); if(o instanceof Double) { final Double[] doubles = new Double[list.size()]; doubles[0] = (Double)o; for(int i=1; i<doubles.length; i++) { doubles[i] = (Double)iterator.next(); } } } final String[] strings = getStrings(name, separator); if(strings != null && strings.length > 0) { final Double[] doubles = new Double[strings.length]; for(int i=0; i<strings.length; i++) { doubles[i] = Double.parseDouble(strings[i]); } return doubles; } return def; } public Byte getByte(final String name, final Byte def) { final Byte b = get(Byte.class, name, null); if(b != null) { return b; } final String s = getString(name); if(s != null && s.length() > 0) { return Byte.parseByte(s); } return def; } public Byte getByte(final String name) { return getByte(name, null); } public Boolean getBoolean(final String name, final Boolean def) { final Boolean b = get(Boolean.class, name, null); if(b != null) { return b; } final String s = getString(name); if(s != null && s.length() > 0) { return Boolean.parseBoolean(s); } return def; } public Boolean getBoolean(final String name) { return getBoolean(name, null); } public URL getURL(final String name, final URL def) throws IllegalArgumentException { final String s = getString(name); try { return (s == null || s.length() == 0) ? def : new URL(s); } catch (Exception ex) { throw new IllegalArgumentException("Illegal URL: " + s); } } public File getFile(final String name, final File def) { String path = getString(name, null); return path == null ? def : new File(path); } public File getFile(final String name) { return getFile(name, null); } public Locale getLocale(final String name, final Locale def) { final String s = getString(name); if((s == null || s.length() == 0)) { return def; } Locale locale = parseLocale(s); if(!isValid(locale)) { throw new IllegalArgumentException("Locale is not valid. Name:" + name + ", Value: " + s); } return locale; } public Locale getLocale(final String name) { return getLocale(name, null); } public Date getDate(final String name, final String pattern, final Date def) { return getDate(name, pattern, null, def); } public Date getDate(final String name, final String pattern, final TimeZone zone, final Date def) { final SimpleDateFormat format = new SimpleDateFormat(pattern); if(zone != null) { format.setTimeZone(zone); } final String s = getString(name); try { return (s == null || s.length() == 0) ? def : format.parse(s); } catch (Exception ex) { throw new IllegalArgumentException("Value for " + name + " (" + s + ") is not valid for " + pattern + " pattern", ex); } } public ModuleParam getParam(final String name, final ModuleParam def) { final Object o = this.data.get(name); if(o != null && o instanceof ModuleParam) { return (ModuleParam) o; } return def; } public ModuleParam getParam(final String name) { return getParam(name, null); } /** * http://stackoverflow.com/questions/3684747/how-to-validate-a-locale-in-java * @param locale * @return */ private boolean isValid(Locale locale) { try { return locale.getISO3Language() != null && locale.getISO3Country() != null; } catch (MissingResourceException e) { return false; } } /** * http://stackoverflow.com/questions/3684747/how-to-validate-a-locale-in-java * @param locale * @return */ private Locale parseLocale(String locale) { if(locale == null) { throw new IllegalArgumentException("null locale"); } String[] parts = locale.split("_"); switch (parts.length) { case 3: return new Locale(parts[0], parts[1], parts[2]); case 2: return new Locale(parts[0], parts[1]); case 1: return new Locale(parts[0]); default: throw new IllegalArgumentException("Invalid locale: " + locale); } } /*public ValidModuleParam validate2(String name, Collection<?> values, boolean required) throws ModuleException { if(name == null) { throw new IllegalArgumentException("null name"); } String value = data.get(name); if(required && (value == null || value.length() == 0)) { throw new ModuleException("Illegal parameter: " + name); } if(values != null && (value != null && value.length() > 0)) { if(!values.contains(value)) { throw new ModuleException("Invalid parameter. name: " + name + ", value: " + value); } } return new ValidModuleParam(data, name); }*/ public ValidModuleParam exists(String name) throws ModuleException { return validate(name, null, true); } public ValidModuleParam validate(final String name, final String regex, final boolean required) throws ModuleException { if(name == null) { throw new IllegalArgumentException("null name"); } if(required) { if(!hasValueFor(name)) { throw new ModuleException("Parameter required but not found: " + name); } } final String value = getString(name); if(regex != null && (value != null && value.length() > 0)) { if(!value.matches(regex)) { throw new ModuleException("Invalid parameter. name: " + name + ", value: " + value); } } return new ValidModuleParam(this, name); } @Override public int size() { return data.size(); } @Override public boolean isEmpty() { return data.isEmpty(); } @Override public boolean containsKey(Object key) { return data.containsKey(key); } public boolean hasValueFor(final Object key) { final Object o = data.get(key); if(o != null) { // if string type, we also check empty string if(o instanceof String) { return ((String)o).length() > 0; } return true; } return false; } @Override public boolean containsValue(Object value) { return data.containsValue(value); } /** * This method just return string values not sub ModuleParam(s) * @param key * @return */ @Override public Object get(Object key) { return data.get(key); } @Override public Object put(String key, Object value) { return data.put(key, value); } @Override public Object remove(Object key) { return data.remove(key); } @Override public void putAll(Map<? extends String, ? extends Object> m) { data.putAll(m); } @Override public void clear() { data.clear(); } @Override public Set<String> keySet() { return data.keySet(); } /*public boolean isDefaultProperties(final String name) { return defaults.contains(name); }*/ @Override public Collection<Object> values() { return data.values(); } @Override public Set<Entry<String, Object>> entrySet() { return data.entrySet(); } @Override protected Object clone() throws CloneNotSupportedException { final ModuleParam p = new ModuleParam(this); return p; } }