org.fusesource.restygwt.client.AbstractJsonEncoderDecoder.java Source code

Java tutorial

Introduction

Here is the source code for org.fusesource.restygwt.client.AbstractJsonEncoderDecoder.java

Source

/**
 * Copyright (C) 2009-2010 the original author or authors.
 * See the notice.md file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * 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.fusesource.restygwt.client;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNull;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.XMLParser;

import org.fusesource.restygwt.client.Json.Style;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *
 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
 * @author <a href="http://www.acuedo.com">Dave Finch</a>
 */
abstract public class AbstractJsonEncoderDecoder<T> implements JsonEncoderDecoder<T> {

    // /////////////////////////////////////////////////////////////////
    // Built in encoders for the native types.
    // /////////////////////////////////////////////////////////////////
    public static final AbstractJsonEncoderDecoder<Boolean> BOOLEAN = new AbstractJsonEncoderDecoder<Boolean>() {

        public Boolean decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            JSONBoolean bool = value.isBoolean();
            if (bool == null) {
                throw new DecodingException("Expected a json boolean, but was given: " + value);
            }
            return bool.booleanValue();
        }

        public JSONValue encode(Boolean value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return JSONBoolean.getInstance(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Character> CHAR = new AbstractJsonEncoderDecoder<Character>() {

        public Character decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return (char) toDouble(value);
        }

        public JSONValue encode(Character value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Short> SHORT = new AbstractJsonEncoderDecoder<Short>() {

        public Short decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return (short) toDouble(value);
        }

        public JSONValue encode(Short value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Integer> INT = new AbstractJsonEncoderDecoder<Integer>() {

        public Integer decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return (int) toDouble(value);
        }

        public JSONValue encode(Integer value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Long> LONG = new AbstractJsonEncoderDecoder<Long>() {

        public Long decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return (long) toDouble(value);
        }

        public JSONValue encode(Long value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Float> FLOAT = new AbstractJsonEncoderDecoder<Float>() {

        public Float decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return (float) toDouble(value);
        }

        public JSONValue encode(Float value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<Double> DOUBLE = new AbstractJsonEncoderDecoder<Double>() {

        public Double decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return toDouble(value);
        }

        public JSONValue encode(Double value) throws EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONNumber(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<String> STRING = new AbstractJsonEncoderDecoder<String>() {

        public String decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            JSONString str = value.isString();
            if (str == null) {
                throw new DecodingException("Expected a json string, but was given: " + value);
            }
            return str.stringValue();
        }

        public JSONValue encode(String value) throws EncodingException {
            if (value == null) {
                return JSONNull.getInstance();
            }
            return new JSONString(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<BigDecimal> BIG_DECIMAL = new AbstractJsonEncoderDecoder<BigDecimal>() {

        @Override
        public JSONValue encode(BigDecimal value)
                throws org.fusesource.restygwt.client.JsonEncoderDecoder.EncodingException {
            if (value == null) {
                return JSONNull.getInstance();
            }
            return new JSONString(value.toString());
        }

        @Override
        public BigDecimal decode(JSONValue value)
                throws org.fusesource.restygwt.client.JsonEncoderDecoder.DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            return toBigDecimal(value);
        }
    };

    public static final AbstractJsonEncoderDecoder<BigInteger> BIG_INTEGER = new AbstractJsonEncoderDecoder<BigInteger>() {

        @Override
        public JSONValue encode(BigInteger value)
                throws org.fusesource.restygwt.client.JsonEncoderDecoder.EncodingException {
            if (value == null) {
                return null;
            }
            return new JSONString(value.toString());
        }

        @Override
        public BigInteger decode(JSONValue value)
                throws org.fusesource.restygwt.client.JsonEncoderDecoder.DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            JSONNumber number = value.isNumber();
            if (number == null) {
                throw new DecodingException("Expected a json number, but was given: " + value);
            }

            // Doing a straight conversion from string to BigInteger will not work for large values
            // So we convert to BigDecimal first and then convert it to BigInteger.
            return new BigDecimal(value.toString()).toBigInteger();
        }
    };

    public static final AbstractJsonEncoderDecoder<Document> DOCUMENT = new AbstractJsonEncoderDecoder<Document>() {

        public Document decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            JSONString str = value.isString();
            if (str == null) {
                throw new DecodingException("Expected a json string, but was given: " + value);
            }
            return XMLParser.parse(str.stringValue());
        }

        public JSONValue encode(Document value) throws EncodingException {
            if (value == null) {
                return JSONNull.getInstance();
            }
            return new JSONString(value.toString());
        }
    };

    public static final AbstractJsonEncoderDecoder<JSONValue> JSON_VALUE = new AbstractJsonEncoderDecoder<JSONValue>() {

        public JSONValue decode(JSONValue value) throws DecodingException {
            return value;
        }

        public JSONValue encode(JSONValue value) throws EncodingException {
            return value;
        }
    };

    public static final AbstractJsonEncoderDecoder<Date> DATE = new AbstractJsonEncoderDecoder<Date>() {

        public Date decode(JSONValue value) throws DecodingException {
            if (value == null || value.isNull() != null) {
                return null;
            }
            JSONString str = value.isString();
            if (str == null) {
                throw new DecodingException("Expected a json string, but was given: " + value);
            }

            String format = Defaults.getDateFormat();
            if (str.stringValue() == null || str.stringValue().length() == 0) {
                return null;
            } else if (format != null) {
                return DateTimeFormat.getFormat(format).parse(str.stringValue());
            } else {
                return DateTimeFormat.getMediumDateTimeFormat().parse(str.stringValue());
            }
        }

        public JSONValue encode(Date value) throws EncodingException {
            if (value == null) {
                return JSONNull.getInstance();
            }
            String format = Defaults.getDateFormat();
            if (format != null) {
                return new JSONString(DateTimeFormat.getFormat(format).format(value));
            } else {
                return new JSONString(DateTimeFormat.getMediumDateTimeFormat().format(value));
            }
        }
    };

    // /////////////////////////////////////////////////////////////////
    // Helper Methods.
    // /////////////////////////////////////////////////////////////////

    static public BigDecimal toBigDecimal(JSONValue value) {
        JSONNumber number = value.isNumber();
        if (number == null) {
            throw new DecodingException("Expected a json number, but was given: " + value);
        }
        return new BigDecimal(value.toString());
    }

    static public double toDouble(JSONValue value) {
        JSONNumber number = value.isNumber();
        if (number == null) {
            throw new DecodingException("Expected a json number, but was given: " + value);
        }
        return number.doubleValue();
    }

    static public JSONObject toObject(JSONValue value) {
        JSONObject object = value.isObject();
        if (object == null) {
            throw new DecodingException("Expected a json obejct, but was given: " + object);
        }
        return object;
    }

    static public <Type> List<Type> toList(JSONValue value, AbstractJsonEncoderDecoder<Type> encoder) {
        if (value == null || value.isNull() != null) {
            return null;
        }
        JSONArray array = value.isArray();
        if (array == null) {
            throw new DecodingException("Expected a json array, but was given: " + value);
        }

        ArrayList<Type> rc = new ArrayList<Type>(array.size());
        int size = array.size();
        for (int i = 0; i < size; i++) {
            rc.add(encoder.decode(array.get(i)));
        }
        return rc;
    }

    static public <Type> Set<Type> toSet(JSONValue value, AbstractJsonEncoderDecoder<Type> encoder) {
        if (value == null || value.isNull() != null) {
            return null;
        }
        JSONArray array = value.isArray();
        if (array == null) {
            throw new DecodingException("Expected a json array, but was given: " + value);
        }

        HashSet<Type> rc = new HashSet<Type>(array.size() * 2);
        int size = array.size();
        for (int i = 0; i < size; i++) {
            rc.add(encoder.decode(array.get(i)));
        }
        return rc;
    }

    static public <Type> Map<String, Type> toMap(JSONValue value, AbstractJsonEncoderDecoder<Type> encoder,
            Style style) {
        if (value == null || value.isNull() != null) {
            return null;
        }

        switch (style) {
        case DEFAULT:
        case SIMPLE: {
            JSONObject object = value.isObject();
            if (object == null) {
                throw new DecodingException("Expected a json object, but was given: " + value);
            }

            HashMap<String, Type> rc = new HashMap<String, Type>(object.size() * 2);
            for (String key : object.keySet()) {
                rc.put(key, encoder.decode(object.get(key)));
            }
            return rc;
        }
        case JETTISON_NATURAL: {
            JSONObject object = value.isObject();
            if (object == null) {
                throw new DecodingException("Expected a json object, but was given: " + value);
            }
            value = object.get("entry");
            if (value == null) {
                throw new DecodingException("Expected an entry array not found");
            }
            JSONArray entries = value.isArray();
            if (entries == null) {
                throw new DecodingException("Expected an entry array, but was given: " + value);
            }

            HashMap<String, Type> rc = new HashMap<String, Type>(object.size() * 2);
            for (int i = 0; i < entries.size(); i++) {
                JSONObject entry = entries.get(i).isObject();
                if (entry == null)
                    throw new DecodingException("Expected an entry object, but was given: " + value);
                JSONValue key = entry.get("key");
                if (key == null)
                    throw new DecodingException("Expected an entry key field not found");
                JSONString k = key.isString();
                if (k == null)
                    throw new DecodingException("Expected an entry key to be a string, but was given: " + value);

                rc.put(k.stringValue(), encoder.decode(entry.get("value")));
            }
            return rc;
        }
        default:
            throw new UnsupportedOperationException("The encoding style is not yet suppored: " + style.name());
        }
    }

    static public <Type> JSONValue toJSON(Map<String, Type> value, AbstractJsonEncoderDecoder<Type> encoder,
            Style style) {
        if (value == null) {
            return JSONNull.getInstance();
        }

        switch (style) {
        case DEFAULT:
        case SIMPLE: {
            JSONObject rc = new JSONObject();
            for (Entry<String, Type> t : value.entrySet()) {
                rc.put(t.getKey(), encoder.encode(t.getValue()));
            }
            return rc;
        }
        case JETTISON_NATURAL: {
            JSONObject rc = new JSONObject();
            JSONArray entries = new JSONArray();
            int i = 0;
            for (Entry<String, Type> t : value.entrySet()) {
                JSONObject entry = new JSONObject();
                entry.put("key", new JSONString(t.getKey()));
                entry.put("value", encoder.encode(t.getValue()));
                entries.set(i++, entry);
            }
            rc.put("entry", entries);
            return rc;
        }
        default:
            throw new UnsupportedOperationException("The encoding style is not yet suppored: " + style.name());
        }
    }

    static public <Type> JSONValue toJSON(Collection<Type> value, AbstractJsonEncoderDecoder<Type> encoder) {
        if (value == null) {
            return JSONNull.getInstance();
        }
        JSONArray rc = new JSONArray();
        int i = 0;
        for (Type t : value) {
            rc.set(i++, encoder.encode(t));
        }
        return rc;
    }

}