
com.basho.riak.client.api.commands.kv.KvResponseBase Maven / Gradle / Ivy
Show all versions of riak-client Show documentation
/*
* Copyright 2014 Brian Roach .
*
* 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.basho.riak.client.api.commands.kv;
import com.basho.riak.client.api.cap.ConflictResolver;
import com.basho.riak.client.api.cap.ConflictResolverFactory;
import com.basho.riak.client.api.cap.UnresolvedConflictException;
import com.basho.riak.client.api.cap.VClock;
import com.basho.riak.client.api.convert.Converter;
import com.basho.riak.client.api.convert.ConverterFactory;
import com.basho.riak.client.api.convert.reflection.AnnotationUtil;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.RiakObject;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.ArrayList;
import java.util.List;
/**
* Base abstract class that KV responses extend.
*
* @author Brian Roach
* @since 2.0
*/
abstract class KvResponseBase
{
private final Location location;
private final List values;
protected KvResponseBase(Init> builder)
{
this.location = builder.location;
this.values = builder.values;
}
/**
* Determine if this response contains any returned values.
* @return true if values are present, false otherwise.
*/
public boolean hasValues()
{
return !values.isEmpty();
}
/**
* Return the number of values contained in this response.
*
* If siblings are present at the {@code Location}, all values
* are returned.
*
* @return the number of values in this response.
*/
public int getNumberOfValues()
{
return values.size();
}
/**
* Get all the objects returned in this response.
*
* If siblings were present in Riak for the object you were fetching,
* this method will return all of them to you.
*
* @return a list of values as RiakObjects
*/
public List getValues()
{
return values;
}
/**
* Get the vector clock returned with this response.
*
* When storing/retrieving core Java types ({@code HashMap},
* {@code ArrayList},{@code String}, etc) or non-annotated POJOs
* this method allows you to retrieve the vector clock.
*
* @return The vector clock or null if one is not present.
*/
public VClock getVectorClock()
{
if (hasValues())
{
return values.get(0).getVClock();
}
else
{
return null;
}
}
/**
* Get all the objects returned in this response.
*
* If siblings were present in Riak for the object you were fetching,
* this method will return all of them to you.
*
*
* The values will be converted to the supplied class using the
* {@link com.basho.riak.client.convert.Converter} returned from the {@link com.basho.riak.client.convert.ConverterFactory}.
* By default this will be the {@link com.basho.riak.client.convert.JSONConverter},
* or no conversion at all if you pass in {@code RiakObject.class}.
*
* @param clazz the class to be converted to
* @return a list of values, converted to the supplied class.
* @see ConverterFactory
* @see Converter
*/
public List getValues(Class clazz)
{
Converter converter = ConverterFactory.getInstance().getConverter(clazz);
return convertValues(converter);
}
/**
* Get a single, resolved object from this response.
*
* The values will be converted to the supplied class using the
* {@link com.basho.riak.client.convert.Converter} returned from the {@link com.basho.riak.client.convert.ConverterFactory}.
* By default this will be the {@link com.basho.riak.client.convert.JSONConverter},
* or no conversion at all if you pass in {@code RiakObject.class}. If there are multiple
* values present (siblings), they will then be resolved using the
* {@link com.basho.riak.client.cap.ConflictResolver} returned by the {@link com.basho.riak.client.cap.ConflictResolverFactory}.
*
* @param clazz the class to be converted to.
* @return the single, resolved value converted to the supplied class.
* @throws UnresolvedConflictException
* @see ConverterFactory
* @see Converter
* @see ConflictResolverFactory
* @see ConflictResolver
*/
public T getValue(Class clazz) throws UnresolvedConflictException
{
Converter converter = ConverterFactory.getInstance().getConverter(clazz);
List convertedValues = convertValues(converter);
ConflictResolver resolver =
ConflictResolverFactory.getInstance().getConflictResolver(clazz);
T resolved = resolver.resolve(convertedValues);
if (hasValues() && resolved != null)
{
VClock vclock = values.get(0).getVClock();
AnnotationUtil.setVClock(resolved, vclock);
}
return resolved;
}
/**
* Get a single, resolved object from this response.
*
* The values will be converted to the supplied class using the
* {@link com.basho.riak.client.convert.Converter} returned from the {@link com.basho.riak.client.convert.ConverterFactory}.
* By default this will be the {@link com.basho.riak.client.convert.JSONConverter},
* or no conversion at all if you pass in {@code RiakObject.class}. If there are multiple
* values present (siblings), they will then be resolved using the
* {@link com.basho.riak.client.cap.ConflictResolver} returned by the {@link com.basho.riak.client.cap.ConflictResolverFactory}.
*
*
* This version should only be used if you're converting to a parameterized
* generic domain object. For example:
*
* {@literal TypeReference>} tr = new {@literal TypeReference>}(){};
* {@literal MyPojo} myPojo = response.getValue(tr);
*
*
* @param typeReference The TypeReference of the class to be converted to.
* @return the single, resolved value converted to the supplied class.
* @throws UnresolvedConflictException
* @see ConverterFactory
* @see Converter
* @see ConflictResolverFactory
* @see ConflictResolver
*/
public T getValue(TypeReference typeReference) throws UnresolvedConflictException
{
Converter converter = ConverterFactory.getInstance().getConverter(typeReference);
List convertedValues = convertValues(converter);
ConflictResolver resolver =
ConflictResolverFactory.getInstance().getConflictResolver(typeReference);
T resolved = resolver.resolve(convertedValues);
if (hasValues() && resolved != null)
{
VClock vclock = values.get(0).getVClock();
AnnotationUtil.setVClock(resolved, vclock);
}
return resolved;
}
/**
* Get the objects returned in this response.
*
* If siblings were present in Riak for the object you were fetching,
* this method will return all of them to you.
*
*
* The values will be converted to the supplied class using the
* {@link com.basho.riak.client.convert.Converter} returned from the {@link com.basho.riak.client.convert.ConverterFactory}.
* By default this will be the {@link com.basho.riak.client.convert.JSONConverter},
* or no conversion at all if you pass in a TypeReference for {@code RiakObject.class}.
*
*
* This version should only be used if you're converting to a parameterized
* generic domain object. For example:
*
* {@literal TypeReference>} tr = new {@literal TypeReference>}(){};
* {@literal List>} list = response.getValues(tr);
*
*
* @param typeReference the TypeReference for the class to be converted to
* @return a list of values, converted to the supplied class.
* @see ConverterFactory
* @see Converter
*/
public List getValues(TypeReference typeReference)
{
Converter converter = ConverterFactory.getInstance().getConverter(typeReference);
return convertValues(converter);
}
private List convertValues(Converter converter)
{
List convertedValues = new ArrayList(values.size());
for (RiakObject ro : values)
{
convertedValues.add(converter.toDomain(ro, location));
}
return convertedValues;
}
/**
* @ExcludeFromJavadoc
*/
protected static abstract class Init>
{
private Location location;
private List values = new ArrayList();
protected abstract T self();
abstract KvResponseBase build();
T withLocation(Location location)
{
this.location = location;
return self();
}
T withValues(List values)
{
this.values.addAll(values);
return self();
}
}
}