Java tutorial
/******************************************************************************************* * Copyright (c) 2016, zzg.zhou(11039850@qq.com) * * Monalisa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program 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 Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************************/ package com.tsc9526.monalisa.tools.datatable; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.tsc9526.monalisa.orm.model.Model; import com.tsc9526.monalisa.tools.clazz.MelpClass; import com.tsc9526.monalisa.tools.clazz.MelpClass.ClassHelper; import com.tsc9526.monalisa.tools.clazz.MelpClass.FGS; import com.tsc9526.monalisa.tools.converters.impl.ArrayTypeConversion; import com.tsc9526.monalisa.tools.json.MelpJson; import com.tsc9526.monalisa.tools.misc.MelpException; import com.tsc9526.monalisa.tools.string.MelpDate; import com.tsc9526.monalisa.tools.string.MelpString; /** * * case insensitive and linked hash map * * @author zzg.zhou(11039850@qq.com) */ public class DataMap extends CaseInsensitiveMap<Object> { private static final long serialVersionUID = -8132926422921115814L; public static DataMap fromXml(String xml) { return MelpString.xml2Map(xml); } public static DataMap fromJson(String json) { return MelpString.json2Map(json); } public static DataMap fromMap(Map<?, ?> map) { return new DataMap(map); } public static DataMap fromBean(Object bean) { return MelpClass.convert(bean, DataMap.class); } public DataMap() { } public DataMap(int initialCapacity) { super(initialCapacity); } public DataMap(Map<?, ?> m) { super(); replace(m); } public DataMap(String key, Object value) { this.put(key, value); } public String toJson() { return toJson(true); } public String toJson(boolean pretty) { GsonBuilder gb = MelpJson.createGsonBuilder(); if (pretty) { gb.setPrettyPrinting(); } return gb.create().toJson(this); } public void replace(Map<?, ?> other) { clear(); if (other != null) { Map<String, Object> tmp = new LinkedHashMap<String, Object>(); for (Entry<?, ?> entry : other.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); tmp.put(key == null ? null : key.toString(), value); } this.putAll(tmp); } } /** * all keys will be added to this prefix * * @param prefix the prefix key * @return a new DataMap */ public DataMap addPrefix(String prefix) { DataMap x = new DataMap(); for (Entry<String, Object> entry : entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (key == null) { x.put(key, value); } else { x.put(prefix + key, value); } } return x; } /** * all the keys that contain a given prefix will be truncated * * @param prefix the prefix key * @return a new DataMap */ public DataMap removePrefix(String prefix) { DataMap x = new DataMap(); int len = prefix.length(); for (Entry<String, Object> entry : entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (key != null && key.startsWith(prefix)) { x.put(key.substring(len), value); } else { x.put(key, value); } } return x; } @SuppressWarnings("unchecked") public <T> T gets(Object key) { return (T) super.get(key); } public <T> T gets(Object key, T defaultValue) { T ret = gets(key); if (ret == null) { ret = defaultValue; } return ret; } /** * if the value associated with the key is null and defaultValue is not null, put defaultValue. * * @param key the map key the default value * @param defaultValue the default value if null * * @param <T> result type * * @return the value associated with the key. */ public <T> T getsPut(Object key, T defaultValue) { T ret = gets(key); if (ret == null) { ret = defaultValue; if (defaultValue != null) { put(key.toString(), defaultValue); } } return ret; } @SuppressWarnings("unchecked") public <T> T as(Class<T> toClass) { try { if (Map.class.isAssignableFrom(toClass)) { return (T) this; } T r = toClass.newInstance(); ClassHelper mc = MelpClass.getClassHelper(toClass); for (FGS fgs : mc.getFields()) { fgs.mapto(this, r); } return r; } catch (Exception e) { return MelpException.throwRuntimeException(e); } } /** * Join key and value, default charset is utf-8 * * @return key1=v1&key2=v2&key3=v3... */ public String toUrlQuery() { return toUrlQuery("utf-8"); } /** * Join key and value using the charset * * @param charset encode values using the charset * * @return key1=v1&key2=v2&key3=v3... */ public String toUrlQuery(String charset) { String split = "&"; StringBuilder sb = new StringBuilder(); for (java.util.Map.Entry<String, Object> entry : entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (value == null) { joinAppend(sb, charset, split, key, ""); } else { if (value.getClass().isArray()) { Object[] vs = null; if (value.getClass().getComponentType().isPrimitive()) { ArrayTypeConversion conversion = new ArrayTypeConversion(); vs = (Object[]) conversion.convert(value, Object[].class); } else { vs = (Object[]) value; } joinAppend(sb, charset, split, key, vs); } else if (value instanceof List) { joinAppend(sb, charset, split, key, (List<?>) value); } else { joinAppend(sb, charset, split, key, value.toString()); } } } return sb.toString(); } private void joinAppend(StringBuilder sb, String charset, String split, String key, Object[] vs) { for (Object o : vs) { joinAppend(sb, charset, split, key, o == null ? "" : o.toString()); } } private void joinAppend(StringBuilder sb, String charset, String split, String key, List<?> vs) { for (Object o : vs) { joinAppend(sb, charset, split, key, o == null ? "" : o.toString()); } } private void joinAppend(StringBuilder sb, String charset, String split, String key, String value) { if (sb.length() > 0) { sb.append(split); } try { String v = URLEncoder.encode(value, charset); sb.append(key).append("=").append(v); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * * @param index The first key is 0. * @return Object value */ @SuppressWarnings("unchecked") public Object get(int index) { Map.Entry<String, Object> entry = (Map.Entry<String, Object>) this.entrySet().toArray()[index]; return entry.getValue(); } /** * <b>For example:</b> <br> * <code> * DataMap m=DataMap.fromJson("{'f1':{'f2':'yes'}}"); * <br> * m.getByPath("f1/f2") = "yes" * * </code> * <br><br> * <b>Another example(array):</b> <br> * <code> * DataMap m=DataMap.fromJson("{'f1':{'f2':['a','b','c']}}"); * <br> m.getByPath("f1/f2[1]") = "a" * <br> m.getByPath("f1/f2[2]") = "b" * <br> m.getByPath("f1/f2[3]") = "c" * <br> * <br> m.getByPath("f1/f2[-1]") = "c" * <br> m.getByPath("f1/f2[-2]") = "b" * <br> m.getByPath("f1/f2[-3]") = "a" * </code> * * @param pathString split by / * @param <T> result type * @return the object value, maybe null */ public <T> T getByPath(String pathString) { String paths = pathString; if (paths.startsWith("/")) { paths = paths.substring(1); } String[] sv = paths.split("/"); Object ret = null; Object m = this; for (int i = 0; i < sv.length; i++) { Object v = getValue(m, sv[i]); if (i == (sv.length - 1)) { ret = v; } else { if (v != null) { m = v; } else { break; } } } @SuppressWarnings("unchecked") T r = (T) ret; return r; } public <T> T getByPath(String paths, T defaultValue) { T r = getByPath(paths); if (r == null) { r = defaultValue; } return r; } private Object getValue(Object v, String fieldName) { // name[0] String name = fieldName; Integer index = null; int x = name.indexOf('['); if (x > 0 && name.endsWith("]")) { index = Integer.parseInt(name.substring(x + 1, name.length() - 1).trim()); name = name.substring(0, x); } Object ret = null; if (v instanceof Map) { ret = ((Map<?, ?>) v).get(name); } else if (v instanceof JsonObject) { ret = ((JsonObject) v).get(name); } else if (v instanceof Model) { ret = ((Model<?>) v).get(name); } else { ClassHelper mc = MelpClass.getClassHelper(v); FGS fgs = mc.getField(name); if (fgs != null) { ret = fgs.getObject(v); } } return getFromList(ret, index); } private Object getFromList(Object obj, Integer index) { if (index != null && obj instanceof List) { List<?> list = (List<?>) obj; if (index < 0) { return list.get(list.size() + index); } else { return list.get(index - 1); } } return obj; } protected Object getOne(String key) { Object v = get(key); if (v != null && v.getClass().isArray()) { Object[] vs = null; if (v.getClass().getComponentType().isPrimitive()) { ArrayTypeConversion conversion = new ArrayTypeConversion(); vs = (Object[]) conversion.convert(v, Object[].class); } else { vs = (Object[]) v; } if (vs != null && vs.length > 0) { return vs[0]; } else { return ""; } } else { return v; } } public String getString(String key, String defaultValue) { String v = getString(key); if (v == null) { v = defaultValue; } return v; } public String getString(String key) { Object v = getOne(key); if (v == null) { return null; } else { return v.toString(); } } public Integer[] getIntegerValues(String key) { String[] xs = getStringValues(key); if (xs != null) { Integer[] rs = new Integer[xs.length]; for (int i = 0; i < xs.length; i++) { rs[i] = Integer.parseInt(xs[i]); } return rs; } else { return new Integer[0]; } } public String[] getStringValues(String key) { Object v = get(key); if (v == null) { v = get(key + "[]"); } if (v == null) { return new String[0]; } else { if (v.getClass().isArray()) { Object[] os = (Object[]) v; String[] r = new String[os.length]; for (int i = 0; i < r.length; i++) { r[i] = os[i] == null ? null : os[i].toString(); } return r; } else { return new String[] { v.toString() }; } } } public boolean getBool(String key, boolean defaultValue) { Boolean v = getBoolean(key); if (v == null) { v = defaultValue; } return v; } public Boolean getBoolean(String key) { Object v = getOne(key); if (v == null) { return (Boolean) v; } else { if ("".equals(v)) { return Boolean.FALSE; } if (v instanceof Boolean) { return (Boolean) v; } else { return Boolean.valueOf("" + v); } } } public int getInt(String key, int defaultValue) { Integer v = getInteger(key); if (v == null) { v = defaultValue; } return v; } public Integer getInteger(String key) { Object v = getOne(key); if (v == null) { return null; } else { if ("".equals(v)) { return null; } if (v instanceof Integer) { return (Integer) v; } else if (v instanceof Double) { return ((Double) v).intValue(); } else { return Integer.parseInt("" + v); } } } public long getLong(String key, long defaultValue) { Long v = getLong(key); if (v == null) { v = defaultValue; } return v; } public Long getLong(String key) { Object v = getOne(key); if (v == null) { return null; } else { if ("".equals(v)) { return null; } if (v instanceof Long) { return (Long) v; } else if (v instanceof Double) { return ((Double) v).longValue(); } else { return Long.parseLong("" + v); } } } public float getFloat(String key, float defaultValue) { Float v = getFloat(key); if (v == null) { v = defaultValue; } return v; } public Float getFloat(String key) { Object v = getOne(key); if (v == null) { return null; } else { if ("".equals(v)) { return null; } if (v instanceof Float) { return (Float) v; } else if (v instanceof Double) { return ((Double) v).floatValue(); } else { return Float.parseFloat("" + v); } } } public double getDouble(String key, double defaultValue) { Double v = getDouble(key); if (v == null) { v = defaultValue; } return v; } public Double getDouble(String key) { Object v = getOne(key); if (v == null) { return null; } else { if ("".equals(v)) { return null; } if (v instanceof Double) { return (Double) v; } else { return Double.parseDouble("" + v); } } } /** * Auto detect the date format:<br> * yyyy-MM-dd<br> * yyyy-MM-dd HH<br> * yyyy-MM-dd HH:mm<br> * yyyy-MM-dd HH:mm:ss<br> * yyyy-MM-dd HH:mm:ss.SSS<br> * * @param key label of the column * * @return date value */ public Date getDate(String key) { return getDate(key, null, null); } /** * @param key label of the column * @param defaultValue return this value if null * @return date value * * @see #getDate(String) */ public Date getDate(String key, Date defaultValue) { return getDate(key, null, defaultValue); } /** * * @param key label of the column * @param format new SimpleDateFormat(format): auto detect date format if null or '' * @param defaultValue return this value if null * @return date value * * @see #getDate(String) */ public Date getDate(String key, String format, Date defaultValue) { return MelpDate.getDate(getOne(key), format, defaultValue); } }