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

net.oauth2.client.http.FormEncodeDataBinding Maven / Gradle / Ivy

The newest version!
/* 
 * Copyright (c) 2017 Georgi Pavlov ([email protected]).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the MIT license which accompanies 
 * this distribution, and is available at 
 * https://github.com/tengia/oauth-2/blob/master/LICENSE
 */

package net.oauth2.client.http;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Stream;

import commons.http.WwwFormUrlEncodedCodec;
import net.oauth2.ParametersMap;

/**
 * A www.form-encode codec for oauth payloads posted to OAuth Token Service.  
 *
 */
public class FormEncodeDataBinding extends WwwFormUrlEncodedCodec {
	
	public FormEncodeDataBinding() {}

	//Encoding

	/**
	 * Register custom serializer, e.g. for scopes with different delimiters than standard
	 */
	@Override
	public  FormEncodeDataBinding with(String mappedName, Serializer serializer) {
		return (FormEncodeDataBinding) super.with(mappedName, serializer);
	}
	
	/**
	 * Collection serializer for grant/token scopes that uses whitespace as delimeter.
	 *
	 * @param 
	 */
	public static class CollectionSerializer implements Serializer> {
		@Override
		public String serialize(Collection value) {
			return formatToDelimitedString(value);
		}
		private final static String SP = " ";
		public static  String formatToDelimitedString(Collection scopes){
			final StringBuilder sb = new StringBuilder();
			scopes.stream().forEach((el)-> {
				sb.append(el.toString()).append(SP);	
			});
			return sb.toString().trim();
		}
	}
	
	/**
	 * Encodes a parameters map grant/token payload into www.form-encode string
	 * 
	 * @param bag
	 * @param serializersMappings
	 * @return
	 */
	public  String encode(final T bag, @SuppressWarnings("rawtypes") Map serializersMappings) {
		Map grantRequestFormFrields = null;
		try {
			grantRequestFormFrields = bag.map();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return this.encodeStream(grantRequestFormFrields.entrySet().stream(), serializersMappings);
	}
	
	// Decoding
	
	/**
	 * Register custom deserializer, e.g. for scopes that use non-standard delimiter
	 */
	@Override
	public  FormEncodeDataBinding with(String mappedName, Deserializer deserializer) {
		return (FormEncodeDataBinding) super.with(mappedName, deserializer);
	}
	
	/**
	 * Deserizalizer for scope strings into collection. Implies whitespace as delimiter. 
	 * @param 
	 */
	public static class CollectionDeserializer implements Deserializer> {
		private String delimiterPattern;
		private boolean returnUnmodifiable;
		public CollectionDeserializer() {}
		@SuppressWarnings("unchecked")
		@Override
		public Collection deserialize(String input) {
			return (Collection) parseDelimitedString(input, this.delimiterPattern, this.returnUnmodifiable);
		}
		public static Collection parseDelimitedString(String delimitedString, String delimiterPattern, boolean returnUnmodifiable){
			if(delimiterPattern == null)
				delimiterPattern = "\\s+";
			String[] enumerationArr = delimitedString.split(delimiterPattern);
			Collection list = Stream.of(enumerationArr).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
			if(returnUnmodifiable)
				list = Collections.unmodifiableCollection(list);
			return list;
		}
		public CollectionDeserializer delimiter(String delimiterPattern) {
			this.delimiterPattern = delimiterPattern;
			return this;
		}
		public CollectionDeserializer unmodifiable(boolean returnUnmodifiable) {
			this.returnUnmodifiable = returnUnmodifiable;
			return this;
		}
	}
	
	/**
	 * Decodes a www.form-encode string into grant/token object of the given targetClass type T.
	 * Requires a constructor with a single Map parameter.
	 * 
	 * @param encodedString
	 * @param targetClass
	 * @param deserializersMapping
	 * @return
	 * @throws IOException
	 */
	public  T from(final String encodedString, final Class targetClass, @SuppressWarnings("rawtypes") final Map deserializersMapping) throws IOException{
		Map  parameters = from(encodedString, deserializersMapping);
		//TODO: the requirement for constructor with Map argument is implicit and cannot be enforced by interface unfortunately 
		Constructor constructor;
		try {
			constructor = targetClass.getConstructor(Map.class);
		} catch (NoSuchMethodException | SecurityException e) {
			throw new IOException(e);
		}
		T result = null;
		try {
			constructor.setAccessible(true);
			result = constructor.newInstance(parameters);
		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
		return result;
	}
	

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy