Java tutorial
/* * This file is provided to you 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.raw.http; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.http.impl.cookie.DateUtils; import org.json.JSONException; import org.json.JSONObject; import com.basho.riak.client.IRiakObject; import com.basho.riak.client.RiakLink; import com.basho.riak.client.bucket.BucketProperties; import com.basho.riak.client.builders.BucketPropertiesBuilder; import com.basho.riak.client.builders.RiakObjectBuilder; import com.basho.riak.client.cap.Quorum; import com.basho.riak.client.convert.ConversionException; import com.basho.riak.client.http.RiakBucketInfo; import com.basho.riak.client.http.RiakClient; import com.basho.riak.client.http.RiakObject; import com.basho.riak.client.http.request.RequestMeta; import com.basho.riak.client.http.request.RiakWalkSpec; import com.basho.riak.client.http.response.BucketResponse; import com.basho.riak.client.http.response.IndexResponse; import com.basho.riak.client.http.response.MapReduceResponse; import com.basho.riak.client.http.response.WalkResponse; import com.basho.riak.client.http.util.Constants; import com.basho.riak.client.query.LinkWalkStep; import com.basho.riak.client.query.MapReduceResult; import com.basho.riak.client.query.WalkResult; import com.basho.riak.client.query.functions.NamedErlangFunction; import com.basho.riak.client.query.functions.NamedFunction; import com.basho.riak.client.query.functions.NamedJSFunction; import com.basho.riak.client.query.indexes.BinIndex; import com.basho.riak.client.query.indexes.IntIndex; import com.basho.riak.client.raw.DeleteMeta; import com.basho.riak.client.raw.FetchMeta; import com.basho.riak.client.raw.JSONErrorParser; import com.basho.riak.client.raw.RawClient; import com.basho.riak.client.raw.StoreMeta; import com.basho.riak.client.raw.query.LinkWalkSpec; import com.basho.riak.client.raw.query.MapReduceTimeoutException; import com.basho.riak.client.util.CharsetUtils; import com.basho.riak.client.util.UnmodifiableIterator; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.type.TypeFactory; /** * Static methods used internally by {@link HTTPClientAdapter} for converting * between http.{@link RiakClient} value classes and {@link RawClient} value * classes * * @author russell * */ public final class ConversionUtil { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); static { OBJECT_MAPPER.registerModule(new SimpleModule("http.ConversionUtil", Version.unknownVersion()) .addDeserializer(Quorum.class, new QuorumDeserializer()) .addDeserializer(NamedErlangFunction.class, new NamedErlangFunctionDeserializer()) .addDeserializer(NamedJSFunction.class, new NamedJSFunctionDeserializer())); } /** * All static methods so we don't want any instances created */ private ConversionUtil() { } /** * Converts a Collection from legacy http {@link RiakObject} to * {@link IRiakObject} * * @param siblings * the siblings from the http client * @return an array of {@link IRiakObject}, one for each member of * <code>siblings</code> */ static IRiakObject[] convert(Collection<com.basho.riak.client.http.RiakObject> siblings) { final Collection<IRiakObject> results = new ArrayList<IRiakObject>(); for (com.basho.riak.client.http.RiakObject object : siblings) { results.add(convert(object)); } return results.toArray(new IRiakObject[results.size()]); } /** * Convert a {@link RiakObject} to an {@link IRiakObject} * * @param object * the {@link RiakObject} to convert * @return */ static IRiakObject convert(final com.basho.riak.client.http.RiakObject o) { RiakObjectBuilder builder = RiakObjectBuilder.newBuilder(o.getBucket(), o.getKey()); builder.withValue(o.getValueAsBytes()); builder.withVClock(nullSafeGetBytes(o.getVclock())); builder.withVtag(o.getVtag()); builder.withDeleted(o.isDeleted()); String lastModified = o.getLastmod(); if (lastModified != null) { Date lastModDate = o.getLastmodAsDate(); builder.withLastModified(lastModDate.getTime()); } final Collection<RiakLink> links = new ArrayList<RiakLink>(); for (com.basho.riak.client.http.RiakLink link : o.iterableLinks()) { links.add(convert(link)); } builder.withLinks(links); @SuppressWarnings("rawtypes") final Collection<com.basho.riak.client.http.RiakIndex> indexes = o.getIndexes(); for (@SuppressWarnings("rawtypes") com.basho.riak.client.http.RiakIndex i : indexes) { if (i instanceof com.basho.riak.client.http.IntIndex) { builder.addIndex(i.getName(), (Long) i.getValue()); } if (i instanceof com.basho.riak.client.http.BinIndex) { builder.addIndex(i.getName(), (String) i.getValue()); } } builder.withContentType(o.getContentType()); final Map<String, String> userMetaData = new HashMap<String, String>(); for (String key : o.usermetaKeys()) { userMetaData.put(key, o.getUsermetaItem(key)); } builder.withUsermeta(userMetaData); return builder.build(); } /** * Convert a {@link com.basho.riak.client.http.RiakLink} to a * {@link RiakLink} * * @param link * the {@link com.basho.riak.client.http.RiakLink} to convert * @return a {@link RiakLink} with the same bucket/key/tag values */ static RiakLink convert(com.basho.riak.client.http.RiakLink link) { return new RiakLink(link.getBucket(), link.getKey(), link.getTag()); } /** * Get the <code>byte[]</code> of a vector clock string, in a null safe way. * @param vclock the String representation of a vector clock * @return <code>vclock</code> as an array of bytes or null (if <code>vclock</code> was null) */ static byte[] nullSafeGetBytes(String vclock) { return vclock == null ? null : CharsetUtils.utf8StringToBytes(vclock); } /** * Convert a {@link StoreMeta} into a {@link RequestMeta} for use with the * legacy http client * * @param storeMeta * the {@link StoreMeta} to convert * @return a {@link RequestMeta} populated with <code>w/dw/returnBody</code> * params from <code>storeMeta</code> */ static RequestMeta convert(StoreMeta storeMeta) { RequestMeta requestMeta = RequestMeta.writeParams(storeMeta.getW(), storeMeta.getDw()); if (storeMeta.hasReturnBody() && storeMeta.getReturnBody()) { requestMeta.setQueryParam(Constants.QP_RETURN_BODY, Boolean.toString(true)); } else { requestMeta.setQueryParam(Constants.QP_RETURN_BODY, Boolean.toString(false)); } if (storeMeta.hasPw()) { if (storeMeta.getPw().isSymbolic()) { requestMeta.setQueryParam(Constants.QP_PW, storeMeta.getPw().getName()); } else { requestMeta.setQueryParam(Constants.QP_PW, Integer.toString(storeMeta.getPw().getIntValue())); } } if (storeMeta.hasIfNoneMatch() && storeMeta.getIfNoneMatch()) { requestMeta.setIfNoneMatch(storeMeta.getEtags()); } if (storeMeta.hasIfNotModified() && storeMeta.getIfNotModified()) { requestMeta.setIfUnmodifiedSince(storeMeta.getLastModified()); } return requestMeta; } /** * Convert an {@link IRiakObject} to an http.{@link RiakObject}, requires a {@link RiakClient} * @param object the {@link IRiakObject} to convert * @return a {@link RiakObject} populate with {@link IRiakObject}'s data */ static com.basho.riak.client.http.RiakObject convert(IRiakObject object, final RiakClient client) { final List<com.basho.riak.client.http.RiakIndex<Long>> intIndexes = convertIntIndexes( object.allIntIndexesV2()); final List<com.basho.riak.client.http.RiakIndex<String>> binIndexes = convertBinIndexes( object.allBinIndexes()); @SuppressWarnings("rawtypes") final List<com.basho.riak.client.http.RiakIndex> allIndexes = new ArrayList<com.basho.riak.client.http.RiakIndex>( intIndexes); allIndexes.addAll(binIndexes); com.basho.riak.client.http.RiakObject riakObject = new com.basho.riak.client.http.RiakObject(client, object.getBucket(), object.getKey(), object.getValue(), object.getContentType(), getLinks(object), getUserMetaData(object), object.getVClockAsString(), formatDate(object.getLastModified()), object.getVtag(), allIndexes, false); return riakObject; } /** * @param binIndexes * @return */ private static List<com.basho.riak.client.http.RiakIndex<String>> convertBinIndexes( Map<BinIndex, Set<String>> binIndexes) { final List<com.basho.riak.client.http.RiakIndex<String>> converted = new ArrayList<com.basho.riak.client.http.RiakIndex<String>>(); for (Map.Entry<BinIndex, Set<String>> index : binIndexes.entrySet()) { String name = index.getKey().getFullname(); for (String v : index.getValue()) { converted.add(new com.basho.riak.client.http.BinIndex(name, v)); } } return converted; } /** * @param allIntIndexes * @return */ private static List<com.basho.riak.client.http.RiakIndex<Long>> convertIntIndexes( Map<IntIndex, Set<Long>> intIndexes) { final List<com.basho.riak.client.http.RiakIndex<Long>> converted = new ArrayList<com.basho.riak.client.http.RiakIndex<Long>>(); for (Map.Entry<IntIndex, Set<Long>> index : intIndexes.entrySet()) { String name = index.getKey().getFullname(); for (Long v : index.getValue()) { converted.add(new com.basho.riak.client.http.IntIndex(name, v)); } } return converted; } /** * {@link RiakObject} expects the date as a string in a certain format * @param lastModified the date to format * @return null (if <code>lastModified</code> was null) or a String of the date */ static String formatDate(Date lastModified) { if (lastModified == null) { return null; } return DateUtils.formatDate(lastModified); } /** * Copies the user meta data from an {@link IRiakObject} into a {@link Map} * @param object the {@link IRiakObject} whose meta data we want * @return the map of user meta (may be empty, won't be null) */ static Map<String, String> getUserMetaData(IRiakObject object) { final Map<String, String> userMetaData = new HashMap<String, String>(); for (Entry<String, String> entry : object.userMetaEntries()) { userMetaData.put(entry.getKey(), entry.getValue()); } return userMetaData; } /** * Copy the {@link RiakLink}s from an {@link IRiakObject} into a * {@link List} * * @param object * the {@link IRiakObject}s whose links we want * @return a {@link List} of {@link com.basho.riak.client.http.RiakLink}, * maybe empty, won't be null */ static List<com.basho.riak.client.http.RiakLink> getLinks(IRiakObject object) { final List<com.basho.riak.client.http.RiakLink> links = new ArrayList<com.basho.riak.client.http.RiakLink>(); for (RiakLink link : object) { links.add(convert(link)); } return links; } /** * Convert an http {@link com.basho.riak.client.http.RiakLink} to a * {@link RiakLink} * * @param link * the {@link com.basho.riak.client.http.RiakLink} to convert * @return a {@link RiakLink} with the same <code>bucket/key/tag</code> * data. */ static com.basho.riak.client.http.RiakLink convert(RiakLink link) { return new com.basho.riak.client.http.RiakLink(link.getBucket(), link.getKey(), link.getTag()); } /** * Copy the data from a {@link BucketResponse} into a * {@link BucketProperties} * * @param response * the {@link BucketResponse} to copy * @return a {@link BucketProperties} populated from <code>response</code> */ static BucketProperties convert(BucketResponse response) throws IOException { String schema = response.getBodyAsString(); JsonNode root = OBJECT_MAPPER.readValue(schema, JsonNode.class); BucketPropertiesBuilder builder = new BucketPropertiesBuilder(); JsonNode props = root.path(Constants.FL_SCHEMA); if (props.isMissingNode()) { throw new JsonMappingException("no 'props' field found"); } builder.allowSiblings(props.path(Constants.FL_SCHEMA_ALLOW_MULT).asBoolean()); builder.lastWriteWins(props.path(Constants.FL_SCHEMA_LAST_WRITE_WINS).asBoolean()); builder.nVal(props.path(Constants.FL_SCHEMA_NVAL).asInt()); builder.backend(props.path(Constants.FL_SCHEMA_BACKEND).textValue()); builder.smallVClock(props.path(Constants.FL_SCHEMA_SMALL_VCLOCK).asInt()); builder.bigVClock(props.path(Constants.FL_SCHEMA_BIG_VCLOCK).asInt()); builder.youngVClock(props.path(Constants.FL_SCHEMA_YOUNG_VCLOCK).asLong()); builder.oldVClock(props.path(Constants.FL_SCHEMA_OLD_VCLOCK).asLong()); for (JsonNode n : props.path(Constants.FL_SCHEMA_PRECOMMIT)) { if (n.path(Constants.FL_SCHEMA_FUN_NAME).isMissingNode()) { builder.addPrecommitHook(OBJECT_MAPPER.treeToValue(n, NamedErlangFunction.class)); } else { builder.addPrecommitHook(OBJECT_MAPPER.treeToValue(n, NamedJSFunction.class)); } } for (JsonNode n : props.path(Constants.FL_SCHEMA_POSTCOMMIT)) { builder.addPostcommitHook(OBJECT_MAPPER.treeToValue(n, NamedErlangFunction.class)); } builder.r(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_R), Quorum.class)); builder.w(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_W), Quorum.class)); builder.dw(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_DW), Quorum.class)); builder.rw(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_RW), Quorum.class)); // TODO backwards compatibility - remove when riak goes 1.3 if (!props.path(Constants.FL_SCHEMA_PR).isMissingNode()) { builder.pr(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_PR), Quorum.class)); } if (!props.path(Constants.FL_SCHEMA_PW).isMissingNode()) { builder.pw(OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_PW), Quorum.class)); } if (!props.path(Constants.FL_SCHEMA_BASIC_QUORUM).isMissingNode()) { builder.basicQuorum(props.path(Constants.FL_SCHEMA_BASIC_QUORUM).asBoolean()); } if (!props.path(Constants.FL_SCHEMA_NOT_FOUND_OK).isMissingNode()) { builder.notFoundOK(props.path(Constants.FL_SCHEMA_NOT_FOUND_OK).asBoolean()); } builder.chashKeyFunction( OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_CHASHFUN), NamedErlangFunction.class)); builder.linkWalkFunction( OBJECT_MAPPER.treeToValue(props.path(Constants.FL_SCHEMA_LINKFUN), NamedErlangFunction.class)); builder.search(props.path(Constants.FL_SCHEMA_SEARCH).asBoolean()); return builder.build(); } /** * Parse a http client chash_fun string into a {@link NamedErlangFunction} * * @param funString * a String of the format "mod:fun" * @return a {@link NamedErlangFunction} populated from * <code>funString</code> or <code>null</code> if the string cannot * be parsed. */ static NamedErlangFunction convert(String funString) { if (funString == null) { return null; } String[] fun = funString.split(":"); if (fun.length != 2) { return null; } return new NamedErlangFunction(fun[0], fun[1]); } /** * Turn a {@link BucketProperties} into a {@link RiakBucketInfo} for * persisting. * * @param bucketProperties * the {@link BucketProperties} to convert * @return a {@link RiakBucketInfo} populated from the * {@link BucketProperties} * @throws IOException */ static RiakBucketInfo convert(BucketProperties bucketProperties) throws IOException { String bucketSchemaJson = toJSON(bucketProperties); RiakBucketInfo rbi; try { rbi = new RiakBucketInfo(new JSONObject(bucketSchemaJson), null); } catch (JSONException e) { throw new IOException("Failed to create bucket schema JSON from JSON string: " + bucketSchemaJson, e); } return rbi; } /** * Converts a {@link BucketProperties} to a JSON string * @param bp * @return a String of JSON that is acceptable to {@link RiakBucketInfo} * @throws IOException * TODO: move this to a custom serializer? */ private static String toJSON(BucketProperties bp) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); JsonGenerator jg = new JsonFactory().createJsonGenerator(out, JsonEncoding.UTF8); jg.writeStartObject(); writeIfNotNull(jg, bp.getAllowSiblings(), Constants.FL_SCHEMA_ALLOW_MULT); writeIfNotNull(jg, bp.getNVal(), Constants.FL_SCHEMA_NVAL); writeIfNotNull(jg, bp.getLastWriteWins(), Constants.FL_SCHEMA_LAST_WRITE_WINS); writeIfNotNull(jg, bp.getBackend(), Constants.FL_SCHEMA_BACKEND); writeIfNotNull(jg, bp.getSmallVClock(), Constants.FL_SCHEMA_SMALL_VCLOCK); writeIfNotNull(jg, bp.getBigVClock(), Constants.FL_SCHEMA_BIG_VCLOCK); writeIfNotNull(jg, bp.getYoungVClock(), Constants.FL_SCHEMA_YOUNG_VCLOCK); writeIfNotNull(jg, bp.getOldVClock(), Constants.FL_SCHEMA_OLD_VCLOCK); writeIfNotNull(jg, bp.getR(), Constants.FL_SCHEMA_R); writeIfNotNull(jg, bp.getRW(), Constants.FL_SCHEMA_RW); writeIfNotNull(jg, bp.getW(), Constants.FL_SCHEMA_W); writeIfNotNull(jg, bp.getDW(), Constants.FL_SCHEMA_DW); writeIfNotNull(jg, bp.getPR(), Constants.FL_SCHEMA_PR); writeIfNotNull(jg, bp.getPW(), Constants.FL_SCHEMA_PW); writeIfNotNull(jg, bp.getBasicQuorum(), Constants.FL_SCHEMA_BASIC_QUORUM); writeIfNotNull(jg, bp.getNotFoundOK(), Constants.FL_SCHEMA_NOT_FOUND_OK); writeIfNotNull(jg, bp.getChashKeyFunction(), Constants.FL_SCHEMA_CHASHFUN); writeIfNotNull(jg, bp.getLinkWalkFunction(), Constants.FL_SCHEMA_LINKFUN); writeIfNotNull(jg, bp.getPostcommitHooks(), Constants.FL_SCHEMA_POSTCOMMIT); writeIfNotNull(jg, bp.getPrecommitHooks(), Constants.FL_SCHEMA_PRECOMMIT); writeIfNotNull(jg, bp.getSearch(), Constants.FL_SCHEMA_SEARCH); jg.writeEndObject(); jg.flush(); return CharsetUtils.asUTF8String(out.toByteArray()); } // TODO move to a serializer? private static void writeIfNotNull(JsonGenerator jg, Boolean value, String fieldName) throws IOException { if (value != null) { jg.writeBooleanField(fieldName, value); } } private static void writeIfNotNull(JsonGenerator jg, String value, String fieldName) throws IOException { if (value != null) { jg.writeStringField(fieldName, value); } } private static void writeIfNotNull(JsonGenerator jg, NamedErlangFunction value, String fieldName) throws IOException { if (value != null) { jg.writeFieldName(fieldName); writeNamedFun(jg, value); } } private static void writeNamedFun(JsonGenerator jg, NamedFunction nf) throws IOException { jg.writeStartObject(); if (nf instanceof NamedErlangFunction) { NamedErlangFunction nef = (NamedErlangFunction) nf; jg.writeStringField(Constants.FL_SCHEMA_FUN_MOD, nef.getMod()); jg.writeStringField(Constants.FL_SCHEMA_FUN_FUN, nef.getFun()); } else { NamedJSFunction njsf = (NamedJSFunction) nf; jg.writeStringField(Constants.FL_SCHEMA_FUN_NAME, njsf.getFunction()); } jg.writeEndObject(); } private static void writeIfNotNull(JsonGenerator jg, Quorum q, String fieldName) throws IOException { if (q != null) { if (q.isSymbolic()) { jg.writeStringField(fieldName, q.getName()); } else { jg.writeNumberField(fieldName, q.getIntValue()); } } } private static void writeIfNotNull(JsonGenerator jg, Integer value, String fieldName) throws IOException { if (value != null) { jg.writeNumberField(fieldName, value); } } private static void writeIfNotNull(JsonGenerator jg, Long value, String fieldName) throws IOException { if (value != null) { jg.writeNumberField(fieldName, value); } } private static void writeIfNotNull(JsonGenerator jg, Collection<? extends NamedFunction> value, String fieldName) throws IOException { if (value != null) { jg.writeArrayFieldStart(fieldName); for (NamedFunction nf : value) { writeNamedFun(jg, nf); } jg.writeEndArray(); } } /** * Turn a {@link MapReduceResponse} into a {@link MapReduceResult} Creates * an anonymous inner class implementation of {@link MapReduceResult} and * uses Jackson's ObjectMapper to convert the response payload. * * @param resp * the {@link MapReduceResponse} * @return a {@link MapReduceResult} view of the results in * <code>resp</code> * @throws MapReduceTimeoutException */ static MapReduceResult convert(final MapReduceResponse resp) throws IOException, MapReduceTimeoutException { if (resp.isError()) { if (JSONErrorParser.isTimeoutException(resp.getBodyAsString())) { throw new MapReduceTimeoutException(); } else { throw new IOException(resp.getBodyAsString()); } } final MapReduceResult result = new MapReduceResult() { public String getResultRaw() { return resp.getBodyAsString(); } public <T> Collection<T> getResult(Class<T> resultType) throws ConversionException { try { return OBJECT_MAPPER.readValue(getResultRaw(), OBJECT_MAPPER.getTypeFactory().constructCollectionType(Collection.class, resultType)); } catch (IOException e) { throw new ConversionException(e); } } }; return result; } /** * Convert a {@link LinkWalkSpec} to a String for execution by the http. * {@link RiakClient} * * @param linkWalkSpec * the {@link LinkWalkSpec} * @return a String representation of <code>linkWalkSpec</code> useful to * the http.{@link RiakClient} */ static String convert(LinkWalkSpec linkWalkSpec) { RiakWalkSpec riakWalkSpec = new RiakWalkSpec(); for (LinkWalkStep step : linkWalkSpec) { riakWalkSpec.addStep(step.getBucket(), step.getTag(), step.getKeep().toString()); } return riakWalkSpec.toString(); } /** * Converts a {@link WalkResponse} -> {@link WalkResult} * * Creates an anonymous implementation of {@link WalkResult} that exposes an * {@link UnmodifiableIterator} view of the results. * * @param walkResponse * An http.{@link RiakClient} {@link WalkResponse} * @return a new {@link WalkResult} */ static WalkResult convert(WalkResponse walkResponse) { final Collection<Collection<IRiakObject>> convertedSteps = new LinkedList<Collection<IRiakObject>>(); for (List<com.basho.riak.client.http.RiakObject> step : walkResponse.getSteps()) { final LinkedList<IRiakObject> objects = new LinkedList<IRiakObject>(); for (com.basho.riak.client.http.RiakObject o : step) { objects.add(convert(o)); } convertedSteps.add(objects); } return new WalkResult() { public Iterator<Collection<IRiakObject>> iterator() { return new UnmodifiableIterator<Collection<IRiakObject>>(convertedSteps.iterator()); } }; } /** * Convert an {@link IndexResponse} to a List of Strings * * @param response an {@link IndexResponse} * @return a List<String> or the empty list * @throws IOException * if {@link IndexResponse} isn't a success. */ static List<String> convert(IndexResponse response) throws IOException { if (response.isSuccess()) { return response.getKeys(); } else { throw new IOException(response.getBodyAsString()); } } /** * Convert a {@link FetchMeta} to a {@link RequestMeta} * * @param fetchMeta * the {@link FetchMeta} to convert * @return the {@link RequestMeta} */ static RequestMeta convert(FetchMeta fetchMeta) { RequestMeta rm = new RequestMeta(); if (fetchMeta.getR() != null) { if (fetchMeta.getR().isSymbolic()) { rm.setQueryParam(Constants.QP_R, fetchMeta.getR().getName()); } else { rm.setQueryParam(Constants.QP_R, Integer.toString(fetchMeta.getR().getIntValue())); } } if (fetchMeta.getPr() != null) { if (fetchMeta.getPr().isSymbolic()) { rm.setQueryParam(Constants.QP_PR, fetchMeta.getPr().getName()); } else { rm.setQueryParam(Constants.QP_PR, Integer.toString(fetchMeta.getPr().getIntValue())); } } if (fetchMeta.getNotFoundOK() != null) { rm.setQueryParam(Constants.QP_NOT_FOUND_OK, fetchMeta.getNotFoundOK().toString()); } if (fetchMeta.getBasicQuorum() != null) { rm.setQueryParam(Constants.QP_BASIC_QUORUM, fetchMeta.getBasicQuorum().toString()); } if (fetchMeta.getIfModifiedSince() != null) { rm.setIfModifiedSince(fetchMeta.getIfModifiedSince()); } return rm; } static RequestMeta convert(DeleteMeta deleteMeta) { if (deleteMeta == null) { return null; } RequestMeta rm = convert( new FetchMeta(deleteMeta.getR(), deleteMeta.getPr(), null, null, null, null, null, null)); if (deleteMeta.hasW()) { if (deleteMeta.getW().isSymbolic()) rm.setQueryParam(Constants.QP_W, deleteMeta.getW().getName()); else { rm.setQueryParam(Constants.QP_W, String.valueOf(deleteMeta.getW().getIntValue())); } } if (deleteMeta.hasPw()) { if (deleteMeta.getPw().isSymbolic()) { rm.setQueryParam(Constants.QP_PW, deleteMeta.getPw().getName()); } else { rm.setQueryParam(Constants.QP_PW, String.valueOf(deleteMeta.getPw().getIntValue())); } } if (deleteMeta.hasDw()) { if (deleteMeta.getDw().isSymbolic()) { rm.setQueryParam(Constants.QP_DW, deleteMeta.getDw().getName()); } else { rm.setQueryParam(Constants.QP_DW, String.valueOf(deleteMeta.getDw().getIntValue())); } } if (deleteMeta.hasRw()) { if (deleteMeta.getRw().isSymbolic()) { rm.setQueryParam(Constants.QP_RW, deleteMeta.getRw().getName()); } else { rm.setQueryParam(Constants.QP_RW, String.valueOf(deleteMeta.getRw().getIntValue())); } } if (deleteMeta.hasVclock()) { rm.setHeader(Constants.HDR_VCLOCK, deleteMeta.getVclock().asString()); } return rm; } }