Package com.papercut.silken

Source Code of com.papercut.silken.Utils

package com.papercut.silken;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.primitives.Primitives;
import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.msgs.SoyMsgBundle;
import com.google.template.soy.msgs.restricted.SoyMsg;
import com.google.template.soy.msgs.restricted.SoyMsgBundleImpl;

/**
* Various utility methods.
*
* @author chris
*/
public class Utils {

    private Utils() {}
  
   
    /**
     * Convert all data stored in a POJO or Map<String, Object> into a format compatible with Soy's DataMap.
     * This method will convert nested POJOs to a corresponding nested Maps.
     *
     * @param obj The Map or POJO who's data should be converted.
     * @return A Map of data compatible with Soy.
     */
    @SuppressWarnings("unchecked")
    public static  Map<String, ?> toSoyCompatibleMap(Object obj) {
        Object ret = toSoyCompatibleObjects(obj);
        if (!(ret instanceof Map)) {
            throw new IllegalArgumentException("Input should be a Map or POJO.");
        }
       
        return (Map<String, ?>) ret;
    }
   
    /**
     * Convert an object (or graph of objects) to types compatible with Soy (data able to be stored in SoyDataMap).
     * This will convert:
     *    - POJOs to Maps
     *    - Iterables to Lists
     *    - all strings and primitives remain as is.
     *   
     * @param obj The object to convert.
     * @return The object converted (in applicable).
     */
    private static Object toSoyCompatibleObjects(Object obj) {
       
        if (obj == null) {
            return obj;
        }

        if (Primitives.isWrapperType(obj.getClass())
                || obj.getClass().isPrimitive()
                || obj instanceof String) {
            return obj;
        }

        if (obj instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) obj;
            Map<String, Object> newMap = new HashMap<String, Object>(map.size());
            for (String key : map.keySet()) {
                newMap.put(key, toSoyCompatibleObjects(map.get(key)));
            }
            return newMap;
        }

        if (obj instanceof Iterable<?>) {
            List<Object> list = Lists.newArrayList();
            for (Object subValue : ((Iterable<?>) obj)) {
                list.add(toSoyCompatibleObjects(subValue));
            }           
            return list;
        }
       
        if (obj.getClass().isArray()) {
            return obj;
        }

        // At this point we must assume it's a POJO so map-it.
        {
            @SuppressWarnings("unchecked")
            Map<String, Object> pojoMap = (Map<String, Object>) pojoToMap(obj);
            Map<String, Object> newMap = new HashMap<String, Object>(pojoMap.size());
            for (String key : pojoMap.keySet()) {
                newMap.put(key, toSoyCompatibleObjects(pojoMap.get(key)));
            }
            return newMap;
        }
    }
    
    /**
     * Convert a Java POJO (aka Bean) to a Map<String, Object>.
     * @param pojo The Java pojo object with standard getters and setters.
     * @return Pojo data as a Map.
     */
    public static Map<String, ?> pojoToMap(Object pojo) {

        Map<String, Object> map = new HashMap<String, Object>();
       
        BeanInfo beanInfo;
        try {
            beanInfo = Introspector.getBeanInfo(pojo.getClass());

            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : propertyDescriptors) {
                if (pd.getReadMethod() != null && !"class".equals(pd.getName())) {
                    map.put(pd.getName(), pd.getReadMethod().invoke(pojo));
                }
            }
       
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return map;
    }
   
    /**
     * Convert (at least attempt) any object to a SoyMapData instance.
     * @param obj The object to convert.
     * @return The created SoyMapData.
     */
    public static SoyMapData objectToSoyDataMap(Object obj) {
      if (obj == null) {
        return new SoyMapData();
      }
      if (obj instanceof SoyMapData) {
        return (SoyMapData) obj;
      }
      return new SoyMapData(toSoyCompatibleMap(obj));
    }
   
    /**
     * Merge two SoyMapData resources.  If the two maps to merge contain duplicate key names, source
     * s2 will overwrite s1. 
     * @param s1 1st resource map.
     * @param s2 2nd resource map.
     * @return A new SoyMapData object containing data from both source.
     */
    public static SoyMapData mergeSoyMapData(SoyMapData s1, SoyMapData s2) {
        Preconditions.checkNotNull(s1);
        Preconditions.checkNotNull(s2);
        SoyMapData merged = new SoyMapData();
        for (String key: s1.getKeys()) {
            merged.putSingle(key, s1.getSingle(key));
        }
        for (String key: s2.getKeys()) {
            merged.putSingle(key, s2.getSingle(key));
        }
        return merged;
    }
   
    /**
     * Take a list of SoyMsgBundles and merge. This is a little hacky but to make life easier we'll use an
     * internal/restricted class: SoyMsgBundleImpl.
     *
     * @param soyMsgBundles
     *            A list of SoyMsgBundles to merge.
     * @return a merged set of messages.
     */
    public static SoyMsgBundle mergeMsgBundles(List<SoyMsgBundle> soyMsgBundles) {

        Preconditions.checkArgument(soyMsgBundles != null && soyMsgBundles.size() > 0, "No MsgBundels defined");

        String localString = "";
        List<SoyMsg> msgs = Lists.newArrayList();

        for (SoyMsgBundle smb : soyMsgBundles) {
            localString = smb.getLocaleString();
            Iterator<SoyMsg> iter = smb.iterator();
            while (iter.hasNext()) {
                msgs.add(iter.next());
            }
        }

        return new SoyMsgBundleImpl(localString, msgs);
    }
   

    /**
     * Referenced from: http://www.java2s.com/Code/Java/Data-Type/ConvertsaStringtoaLocale.htm
     *
     * <p>Converts a String to a Locale.</p>
     *
     * <p>This method takes the string format of a locale and creates the
     * locale object from it.</p>
     *
     * <pre>
     *   LocaleUtils.toLocale("en")         = new Locale("en", "")
     *   LocaleUtils.toLocale("en_GB")      = new Locale("en", "GB")
     *   LocaleUtils.toLocale("en_GB_xxx")  = new Locale("en", "GB", "xxx")   (#)
     * </pre>
     *
     * <p>(#) The behaviour of the JDK variant constructor changed between JDK1.3 and JDK1.4.
     * In JDK1.3, the constructor upper cases the variant, in JDK1.4, it doesn't.
     * Thus, the result from getVariant() may vary depending on your JDK.</p>
     *
     * <p>This method validates the input strictly.
     * The language code must be lowercase.
     * The country code must be uppercase.
     * The separator must be an underscore.
     * The length must be correct.
     * </p>
     *
     * @param str  the locale String to convert, null returns null
     * @return a Locale, null if null input
     * @throws IllegalArgumentException if the string is an invalid format
     */
    public static Locale stringToLocale(String str) {
        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len != 2 && len != 5 && len < 7) {
            throw new IllegalArgumentException("Invalid locale format: " + str);
        }
        char ch0 = str.charAt(0);
        char ch1 = str.charAt(1);
        if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z') {
            throw new IllegalArgumentException("Invalid locale format: " + str);
        }
        if (len == 2) {
            return new Locale(str, "");
        } else {
            if (str.charAt(2) != '_') {
                throw new IllegalArgumentException("Invalid locale format: " + str);
            }
            char ch3 = str.charAt(3);
            if (ch3 == '_') {
                return new Locale(str.substring(0, 2), "", str.substring(4));
            }
            char ch4 = str.charAt(4);
            if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z') {
                throw new IllegalArgumentException("Invalid locale format: " + str);
            }
            if (len == 5) {
                return new Locale(str.substring(0, 2), str.substring(3, 5));
            } else {
                if (str.charAt(5) != '_') {
                    throw new IllegalArgumentException("Invalid locale format: " + str);
                }
                return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
            }
        }
    }

}
TOP

Related Classes of com.papercut.silken.Utils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.