All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.chargebee.internal.Resource Maven / Gradle / Ivy

There is a newer version: 3.28.0
Show newest version
package com.chargebee.internal;

import com.chargebee.Environment;
import java.io.*;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.*;

/**
 * Base class for the ChargeBee model objects
 *
 * @param  The concrete type of the model
 */
public class Resource {

    private static final Logger logger = Logger.getLogger(Resource.class.getName());

    public final JSONObject jsonObj;

    private static final String unknown = "_UNKNOWN";

    public Resource(JSONObject jsonObj){
        this.jsonObj = jsonObj;
    }

    public Resource(String jsonStr){
        try {
            jsonObj = new JSONObject(jsonStr);
        } catch(JSONException jexp) {
            throw new RuntimeException(jexp);
        }
    }

    public Resource(InputStream is) throws IOException {
        this(new BufferedReader(new InputStreamReader(is)));
    }

    public Resource(BufferedReader rd) throws IOException {
        this(getAsString(rd));
    }

    private static String getAsString(BufferedReader rd) throws IOException {
        StringBuilder buf = new StringBuilder();
        String line = null;
        while((line = rd.readLine()) != null) {
            buf.append(line);
        }
        return buf.toString();
    }

    public  String reqString(String key) {
        return assertReqProp(key, optString(key));
    }

    public String optString(String key) {
        return optional(key, String.class);
    }
    
    public Boolean reqBoolean(String key) {
        return assertReqProp(key, optional(key, Boolean.class));
    }

    public Boolean optBoolean(String key) {
        return optional(key, Boolean.class);
    }
    
    public Integer reqInteger(String key) {
        return assertReqProp(key, optInteger( key));
    }

    public Integer optInteger(String key) {
        Integer value = optional( key, Integer.class);
        try{
            return (value != null)? new Integer(value.intValue()):null;
        }catch(Exception ex){
            throw conversionException(key);
        }
    }

    public Long reqLong(String key) {
        return assertReqProp(key, optLong( key));
    }

    public Long optLong(String key) {
        Object val = jsonObj.opt(key);
        if(val == null) {
            return null;
        }
        // special handling for Long. Accepting both Long and Integer values !!
        if(val instanceof Long) {
            return (Long)val;
        } else if(val instanceof Integer) {
            return ((Integer)val).longValue();
        } else {
            throw new RuntimeException("Wrong type. Expecing Long type but got "
                    + val.getClass().getSimpleName());
        }
    }

    public JSONObject reqJSONObject(String key){
        return assertReqProp(key, optJSONObject(key));
    }

    public JSONObject optJSONObject(String key){
        return optional(key,JSONObject.class);
    }

    public Timestamp reqTimestamp(String key) {
        return assertReqProp(key, optTimestamp( key));
    }

    public Timestamp optTimestamp(String key) {
        Integer unxTime = optional(key, Integer.class);
        return (unxTime != null)? new Timestamp(unxTime * 1000l) : null;
    }

    public  E reqEnum(String key, Class enumClass) {
        return assertReqProp(key, optEnum(key, enumClass));
    }

    public  E optEnum(String key, Class enumClass) {
        String value = optString(key);
        if(value == null) {
            return null;
        }
        try {
           return (E) Enum.valueOf(enumClass, value.toUpperCase());
        }catch(Exception ex){
           logger.log(Level.SEVERE, " The property {0} has unexpected value {1}", new Object[]{key, value});
           return (E) Enum.valueOf(enumClass, unknown);
        }
    }

    /**
     * @param  The sub-resource type
     */
    public  List reqList(String key,Class claz) {
        List list = optList(key, claz);
        if(list.isEmpty()) {
            throw new RuntimeException("The sub-resource [" + key + "] is not present");
        }
        return list;
    }

    /**
     * @param  The sub-resource type
     */
    public  List optList(String key, Class claz){
        JSONArray arr = jsonObj.optJSONArray(key);
        if(arr == null){
            return Collections.EMPTY_LIST;
        }

        List toRet = new ArrayList(arr.length());
        for (int i = 0; i < arr.length(); i++) {
            JSONObject json = arr.optJSONObject(i);
            toRet.add(ClazzUtil.createInstance(claz, json));
        }
        return toRet;
    }


    private  T optional(String key, Class type) {
        Object val = jsonObj.opt(key);
        if(val == null) {
            return null;
        }
        if(!type.isAssignableFrom(val.getClass())){
            throw new RuntimeException("Type mismatch for property " + key
                    + " . Expected " + type.getName() + " but contains " + val.getClass().getName());
        }
        return (T)val;
    }

    public String toJson() {
        return jsonObj.toString();
    }

    @Override
    public String toString() {
        try {
            return jsonObj.toString(2);
        } catch (JSONException ex) {
            throw new RuntimeException(ex);
        }
    }

    // util methods
    //=============

    private  T assertReqProp(String key,T val) {
        if(val == null){
            throw new RuntimeException("The property [" + key + "] is not present ");
        }
        return val;
    }

    private RuntimeException conversionException(String key){
        return new RuntimeException("The property " + key + " not in the required format");
    }

    protected static String url(String ... paths){
        return url(Environment.defaultConfig(), paths);
    }

    protected static String nullCheck(String id) {
        if(id == null || id.isEmpty()) {
            throw new RuntimeException("id cannot be null/empty");
        }
        return id;
    }

    protected static String url(Environment env, String ... paths){
        StringBuilder strBuf = new StringBuilder(env.apiBaseUrl());
        for (String path : paths) {
            try {//Using URLEncoder is wrong as it encodes for form. Replace it with Google's CharEscapers.java
                strBuf.append('/').append(URLEncoder.encode(path, Environment.CHARSET));
            } catch (UnsupportedEncodingException ex) {
                throw new RuntimeException(ex);
            }
        }
        return strBuf.toString();
    }


}