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

io.rivulet.converter.QueryConverter Maven / Gradle / Ivy

The newest version!
package io.rivulet.converter;

import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/* Converter which creates a request query string either by replacing a target query string or by appending values to a target
 * query string. */
public class QueryConverter extends ForcedTypeConverter {

    private static final long serialVersionUID = -4113324628916395735L;
    // Used to convert between a map made from the target value and the source value
    private final MapConverter intermediateConverter;
    // Whether the original query string and its replacement should be encoded.
    private final boolean encoded;

    private QueryConverter(boolean append, boolean encoded) {
        super(ConverterPriority.VERY_LOW);
        this.intermediateConverter = MapConverter.getInstance(append);
        this.encoded = encoded;
    }

    @Override
    public boolean isInPlace() {
        return false;
    }

    @Override
    public boolean canConvert(Class targetType, Class sourceType) {
        return targetType.equals(String.class) && intermediateConverter.canConvert(Map.class, sourceType);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Object convert(Object target, Object source) {
        try {
            if(target != null && !(target instanceof String)) {
                return null;
            }
            HashMap originalMap = parseOriginalQuery((String)target);
            HashMap resultMap = (HashMap)intermediateConverter.convert(originalMap, source);
            return makeQueryString(resultMap);
        } catch(Exception e) {
            return null;
        }
    }

    /* Returns a map of key-value parameter pairs from the specified query string. */
    public HashMap parseOriginalQuery(String queryString) {
        HashMap params = new HashMap<>();
        if(queryString != null) {
            List pairs = URLEncodedUtils.parse(queryString, Consts.UTF_8);
            for (NameValuePair pair : pairs) {
                params.put(pair.getName(), pair.getValue());
            }
        }
        return params;
    }

    /* Returns a query string containing the key value pairs of the specified map. */
    private String makeQueryString(Map map) {
        if(encoded) {
            List pairs = new LinkedList<>();
            for(String key : map.keySet()) {
                pairs.add(new BasicNameValuePair(key, map.get(key)));
            }
            return URLEncodedUtils.format(pairs, Consts.UTF_8);
        } else {
            StringBuilder builder = new StringBuilder();
            boolean first = true;
            for(String key : map.keySet()) {
                if(first) {
                    first = false;
                } else {
                    builder.append('&');
                }
                builder.append(key).append('=').append(map.get(key));
            }
            return builder.toString();
        }
    }

    @Override
    public String toString() {
        return String.format("", encoded ? "encoded" : "decoded", intermediateConverter);
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;

        QueryConverter that = (QueryConverter) o;

        if (encoded != that.encoded) return false;
        return intermediateConverter.equals(that.intermediateConverter);
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        result = 31 * result + intermediateConverter.hashCode();
        result = 31 * result + (encoded ? 1 : 0);
        return result;
    }

    /* Provides access to the instances of QueryConverter. */
    public static QueryConverter getInstance(boolean append, boolean encoded) {
        if(append) {
            if(encoded) {
                return QueryConverterSingletons.ENCODED_APPENDING_INSTANCE;
            } else {
                return QueryConverterSingletons.DECODED_APPENDING_INSTANCE;
            }
        } else {
            if(encoded) {
                return QueryConverterSingletons.ENCODED_REPLACING_INSTANCE;
            } else {
                return QueryConverterSingletons.DECODED_REPLACING_INSTANCE;
            }
        }
    }

    /* Inner class used to provide access to the four instances of QueryConverter and ensure that only four instances of
     * QueryConverter are ever created. */
    private static class QueryConverterSingletons {
        private static final QueryConverter ENCODED_APPENDING_INSTANCE = new QueryConverter(true, true);
        private static final QueryConverter DECODED_APPENDING_INSTANCE = new QueryConverter(true, false);
        private static final QueryConverter ENCODED_REPLACING_INSTANCE = new QueryConverter(false, true);
        private static final QueryConverter DECODED_REPLACING_INSTANCE = new QueryConverter(false, false);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy