package org.restler.spring.data.methods;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.reflect.TypeToken;
import org.restler.client.Call;
import org.restler.spring.data.util.RepositoryUtils;
import org.restler.util.UriBuilder;
import org.springframework.web.util.UriComponentsBuilder;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.net.URI;
import java.util.Map;
import java.util.Set;
/**
* DefaultRepositoryMethod used for extracting getDescription method implementation.
*/
public abstract class DefaultRepositoryMethod implements RepositoryMethod {
public Call getDescription(URI baseUrl, Class<?> declaringClass, ImmutableMultimap<String, String> requestParams, Map<String, Object> pathVariables, Set<Object> unmappedArgs) {
String methodMappedUriString;
Class<?> idClass = TypeToken.of(getRepositoryType(declaringClass).getActualTypeArguments()[1]).getRawType();
String repositoryUri = RepositoryUtils.getRepositoryPath(declaringClass.getInterfaces()[0]);
methodMappedUriString = getPathPart(unmappedArgs.toArray());
String uriTemplate = UriComponentsBuilder.fromUriString("/").pathSegment(repositoryUri, methodMappedUriString).build().toUriString();
// TODO: implement more generic solution
unmappedArgs.stream().
filter(unmappedArg -> idClass.isAssignableFrom(unmappedArg.getClass())).
forEach(unmappedArg -> pathVariables.put("id", unmappedArg));
return getCall(url(baseUrl, uriTemplate, requestParams, pathVariables), declaringClass, unmappedArgs.toArray());
}
protected ParameterizedTypeImpl getRepositoryType(Class<?> repositoryClass) {
Class repositoryType = (Class) repositoryClass.getMethods()[0].getDeclaringClass().getGenericInterfaces()[0];
return (ParameterizedTypeImpl) repositoryType.getGenericInterfaces()[0];
}
protected abstract Call getCall(URI uri, Class<?> declaringClass, Object[] args);
protected abstract String getPathPart(Object[] args);
private URI url(URI baseUrl, String pathTemplate, ImmutableMultimap<String, String> queryParams, Map<String, Object> pathVariables) {
return new UriBuilder(baseUrl).
path(pathTemplate).
queryParams(queryParams).
pathVariables(pathVariables).build();
}
}