com.opower.rest.client.generator.util.StringConverters.java Source code

Java tutorial

Introduction

Here is the source code for com.opower.rest.client.generator.util.StringConverters.java

Source

/**
 *    Copyright 2014 Opower, Inc.
 *    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 com.opower.rest.client.generator.util;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapMaker;

import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.NewCookie;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentMap;

public class StringConverters {

    private static ConcurrentMap<Class<?>, StringConverter<?>> CONVERTERS;

    public static <T> StringConverter<T> getStringConverter(Class<T> clazz) {
        if (CONVERTERS == null) {
            synchronized (StringConverters.class) {
                if (CONVERTERS == null) {
                    CONVERTERS = init();
                }
            }
        }
        @SuppressWarnings("unchecked")
        StringConverter<T> converterToUse = (StringConverter<T>) CONVERTERS.get(clazz);
        return converterToUse;
    }

    private static ConcurrentMap<Class<?>, StringConverter<?>> init() {
        ConcurrentMap<Class<?>, StringConverter<?>> map = new MapMaker().makeMap();
        map.putAll(ImmutableMap.<Class<?>, StringConverter<?>>builder()
                .put(Optional.absent().getClass(), new OptionalConverter())
                .put(Optional.of(true).getClass(), new OptionalConverter())
                .put(Cookie.class, new CookieStringConverter()).put(EntityTag.class, new EntityTagDelegate())
                .put(Locale.class, new LocaleDelegate()).put(MediaType.class, new MediaTypeStringConverter())
                .put(URI.class, new UriStringConverter()).put(NewCookie.class, new NewCookieStringConverter())
                .put(CacheControl.class, new CacheControlDelegate()).build());
        return map;
    }

    private static abstract class OneWayStringConverter<T> implements StringConverter<T> {
        @Override
        public T fromString(String string) {
            throw new UnsupportedOperationException();
        }
    }

    public static class OptionalConverter extends OneWayStringConverter<Optional<?>> {
        @Override
        public String toString(Optional<?> value) {
            if (value.isPresent()) {
                return value.get().toString();
            }

            return null;
        }
    }

    public static class CookieStringConverter extends OneWayStringConverter<Cookie> {
        public String toString(Cookie cookie) {
            StringBuffer buf = new StringBuffer();
            ServerCookie.appendCookieValue(buf, 0, cookie.getName(), cookie.getValue(), cookie.getPath(),
                    cookie.getDomain(), null, -1, false);
            return buf.toString();
        }
    }

    public static class EntityTagDelegate extends OneWayStringConverter<EntityTag> {

        public String toString(EntityTag value) {
            String weak = value.isWeak() ? "W/" : "";
            return weak + value.getValue();
        }

    }

    public static class LocaleDelegate extends OneWayStringConverter<Locale> {

        public String toString(Locale value) {
            return toLanguageString(value);
        }

        /**
         * HTTP 1.1 has different String format for language than what java.util.Locale does '-' instead of '_'
         * as a separator
         *
         * @param value
         * @return
         */
        private String toLanguageString(Locale value) {
            StringBuffer buf = new StringBuffer(value.getLanguage().toLowerCase());
            if (value.getCountry() != null && !value.getCountry().equals(""))
                buf.append("-").append(value.getCountry().toLowerCase());
            return buf.toString();
        }
    }

    public static class MediaTypeStringConverter implements StringConverter<MediaType> {

        @Override
        public MediaType fromString(String type) {
            if (type == null)
                throw new IllegalArgumentException("MediaType value is null");
            return parse(type);
        }

        public static MediaType parse(String type) {
            String params = null;
            int idx = type.indexOf(";");
            if (idx > -1) {
                params = type.substring(idx + 1).trim();
                type = type.substring(0, idx);
            }
            String major = null;
            String subtype = null;
            String[] paths = type.split("/");
            if (paths.length < 2 && type.equals("*")) {
                major = "*";
                subtype = "*";

            } else if (paths.length != 2) {
                throw new IllegalArgumentException("Failure parsing MediaType string: " + type);
            } else if (paths.length == 2) {
                major = paths[0];
                subtype = paths[1];
            }
            if (params != null && !params.equals("")) {
                HashMap<String, String> typeParams = new HashMap<String, String>();

                int start = 0;

                while (start < params.length()) {
                    start = setParam(typeParams, params, start);
                }
                return new MediaType(major, subtype, typeParams);
            } else {
                return new MediaType(major, subtype);
            }
        }

        static int getEndName(String params, int start) {
            int equals = params.indexOf('=', start);
            int semicolon = params.indexOf(';', start);
            if (equals == -1 && semicolon == -1)
                return params.length();
            if (equals == -1)
                return semicolon;
            if (semicolon == -1)
                return equals;
            int end = (equals < semicolon) ? equals : semicolon;
            return end;
        }

        public static int setParam(HashMap<String, String> typeParams, String params, int start) {
            boolean quote = false;
            boolean backslash = false;

            int end = getEndName(params, start);
            String name = params.substring(start, end).trim();
            if (end < params.length() && params.charAt(end) == '=')
                end++;

            StringBuilder buffer = new StringBuilder(params.length() - end);
            int i = end;
            for (; i < params.length(); i++) {
                char c = params.charAt(i);

                switch (c) {
                case '"': {
                    if (backslash) {
                        backslash = false;
                        buffer.append(c);
                    } else {
                        quote = !quote;
                    }
                    break;
                }
                case '\\': {
                    if (backslash) {
                        backslash = false;
                        buffer.append(c);
                    }
                    break;
                }
                case ';': {
                    if (!quote) {
                        String value = buffer.toString().trim();
                        typeParams.put(name, value);
                        return i + 1;
                    } else {
                        buffer.append(c);
                    }
                    break;
                }
                default: {
                    buffer.append(c);
                    break;
                }
                }
            }
            String value = buffer.toString().trim();
            typeParams.put(name, value);
            return i;
        }

        public String toString(MediaType type) {
            String rtn = type.getType().toLowerCase() + "/" + type.getSubtype().toLowerCase();
            if (type.getParameters() == null || type.getParameters().size() == 0)
                return rtn;
            for (String name : type.getParameters().keySet()) {
                String val = type.getParameters().get(name);
                rtn += ";" + name + "=\"" + val + "\"";
            }
            return rtn;
        }
    }

    public static class UriStringConverter extends OneWayStringConverter<URI> {

        public String toString(URI uri) {
            return uri.toASCIIString();
        }
    }

    public static class NewCookieStringConverter extends OneWayStringConverter<NewCookie> {

        protected void quote(StringBuilder b, String value) {
            if (value.indexOf(' ') > -1) {
                b.append('"');
                b.append(value);
                b.append('"');
            } else {
                b.append(value);
            }
        }

        public String toString(NewCookie cookie) {
            StringBuilder b = new StringBuilder();

            b.append(cookie.getName()).append('=');
            quote(b, cookie.getValue());

            b.append(";").append("Version=").append(cookie.getVersion());

            if (cookie.getComment() != null) {
                b.append(";Comment=");
                quote(b, cookie.getComment());
            }
            if (cookie.getDomain() != null) {
                b.append(";Domain=");
                quote(b, cookie.getDomain());
            }
            if (cookie.getPath() != null) {
                b.append(";Path=");
                quote(b, cookie.getPath());
            }
            if (cookie.getMaxAge() != -1) {
                b.append(";Max-Age=");
                b.append(cookie.getMaxAge());
            }
            if (cookie.isSecure())
                b.append(";Secure");
            return b.toString();
        }
    }

    public static class CacheControlDelegate extends OneWayStringConverter<CacheControl> {

        private StringBuffer addDirective(String directive, StringBuffer buffer) {
            if (buffer.length() > 0)
                buffer.append(", ");
            buffer.append(directive);
            return buffer;
        }

        public String toString(CacheControl value) {
            StringBuffer buffer = new StringBuffer();
            if (value.isNoCache()) {
                List<String> fields = value.getNoCacheFields();
                if (fields.size() < 1) {
                    addDirective("no-cache", buffer);
                } else {
                    for (String field : value.getNoCacheFields()) {
                        addDirective("no-cache", buffer).append("=\"").append(field).append("\"");
                    }
                }
            }
            if (value.isMustRevalidate())
                addDirective("must-revalidate", buffer);
            if (value.isNoTransform())
                addDirective("no-transform", buffer);
            if (value.isNoStore())
                addDirective("no-store", buffer);
            if (value.isProxyRevalidate())
                addDirective("rest-revalidate", buffer);
            if (value.getSMaxAge() > -1)
                addDirective("s-maxage", buffer).append("=").append(value.getSMaxAge());
            if (value.getMaxAge() > -1)
                addDirective("max-age", buffer).append("=").append(value.getMaxAge());
            if (value.isPrivate()) {
                List<String> fields = value.getPrivateFields();
                if (fields.size() < 1)
                    addDirective("private", buffer);
                else {
                    for (String field : value.getPrivateFields()) {
                        addDirective("private", buffer).append("=\"").append(field).append("\"");
                    }
                }
            }
            for (String key : value.getCacheExtension().keySet()) {
                String val = value.getCacheExtension().get(key);
                addDirective(key, buffer);
                if (val != null && !"".equals(val)) {
                    buffer.append("=\"").append(val).append("\"");
                }
            }
            return buffer.toString();
        }

    }
}