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

com.basho.riak.client.api.convert.reflection.AnnotationInfo Maven / Gradle / Ivy

The newest version!
/*
 * 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.api.convert.reflection;

import static com.basho.riak.client.api.convert.reflection.ClassUtil.getFieldValue;
import static com.basho.riak.client.api.convert.reflection.ClassUtil.setFieldValue;
import static com.basho.riak.client.api.convert.reflection.ClassUtil.getMethodValue;
import static com.basho.riak.client.api.convert.reflection.ClassUtil.setMethodValue;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.basho.riak.client.core.query.links.RiakLink;
import com.basho.riak.client.api.cap.BasicVClock;
import com.basho.riak.client.api.cap.VClock;
import com.basho.riak.client.core.query.UserMetadata.RiakUserMetadata;
import com.basho.riak.client.core.query.indexes.BigIntIndex;
import com.basho.riak.client.core.query.indexes.IndexType;
import com.basho.riak.client.core.query.indexes.LongIntIndex;
import com.basho.riak.client.core.query.indexes.RawIndex;
import com.basho.riak.client.core.query.indexes.RiakIndexes;
import com.basho.riak.client.core.query.indexes.StringBinIndex;
import com.basho.riak.client.core.query.links.RiakLinks;
import com.basho.riak.client.core.util.BinaryValue;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.LinkedList;

/**
 * Class that containsKeyKey the Riak annotated fields for an annotated class
 *
 * @author russell
 *
 */
public class AnnotationInfo
{
    private final Field riakKeyField;
    private final Method riakKeySetter;
    private final Method riakKeyGetter;
    private final List usermetaFields;
    private final List usermetaMethods;
    private final List indexFields;
    private final List indexMethods;
    private final Field riakLinksField;
    private final Method riakLinksGetter;
    private final Method riakLinksSetter;
    private final Field riakVClockField;
    private final Method riakVClockSetter;
    private final Method riakVClockGetter;
    private final Field riakTombstoneField;
    private final Method riakTombstoneSetter;
    private final Method riakTombstoneGetter;
    private final Field riakContentTypeField;
    private final Method riakContentTypeGetter;
    private final Method riakContentTypeSetter;
    private final Field riakLastModifiedField;
    private final Method riakLastModifiedSetter;
    private final Field riakVTagField;
    private final Method riakVTagSetter;
    private final Field riakBucketNameField;
    private final Method riakBucketNameSetter;
    private final Method riakBucketNameGetter;
    private final Field riakBucketTypeField;
    private final Method riakBucketTypeSetter;
    private final Method riakBucketTypeGetter;

    private AnnotationInfo(Builder builder)
    {
        this.riakKeyField = builder.riakKeyField;
        this.riakKeyGetter = builder.riakKeyGetter;
        this.riakKeySetter = builder.riakKeySetter;
        this.riakLinksField = builder.riakLinksField;
        this.riakLinksGetter = builder.riakLinksGetter;
        this.riakLinksSetter = builder.riakLinksSetter;
        this.riakVClockField = builder.riakVClockField;
        this.riakVClockGetter = builder.riakVClockGetter;
        this.riakVClockSetter = builder.riakVClockSetter;
        this.riakTombstoneField = builder.riakTombstoneField;
        this.riakTombstoneGetter = builder.riakTombstoneGetter;
        this.riakTombstoneSetter = builder.riakTombstoneSetter;
        this.usermetaFields = builder.usermetaFields;
        this.usermetaMethods = builder.usermetaMethods;
        this.indexFields = builder.indexFields;
        this.indexMethods = builder.indexMethods;
        this.riakContentTypeField = builder.riakContentTypeField;
        this.riakContentTypeGetter = builder.riakContentTypeGetter;
        this.riakContentTypeSetter = builder.riakContentTypeSetter;
        this.riakLastModifiedField = builder.riakLastModifiedField;
        this.riakLastModifiedSetter = builder.riakLastModified;
        this.riakVTagField = builder.riakVTagField;
        this.riakVTagSetter = builder.riakVTagSetter;
        this.riakBucketNameField = builder.riakBucketNameField;
        this.riakBucketNameGetter = builder.riakBucketNameGetter;
        this.riakBucketNameSetter = builder.riakBucketNameSetter;
        this.riakBucketTypeField = builder.riakBucketTypeField;
        this.riakBucketTypeGetter = builder.riakBucketTypeGetter;
        this.riakBucketTypeSetter = builder.riakBucketTypeSetter;
    }

    /**
     * Returns the key.
     * 

* The @RiakKey annotation allows for any type to be used. this method will * call the object's toString() method to return a String. *

* * @param the type of the domain object * @param obj the domain object * @return the String representation of the key */ public BinaryValue getRiakKey(T obj) { // TODO: charset BinaryValue key = null; if (riakKeyGetter != null) { if (riakKeyGetter.getReturnType().isArray()) { Object o = getMethodValue(riakKeyGetter, obj); if (o != null) { key = BinaryValue.create((byte[]) o); } } else { Object o = getMethodValue(riakKeyGetter, obj); if (o != null) { key = BinaryValue.create((String) o); } } } else if (riakKeyField != null) { if (riakKeyField.getType().equals(String.class)) { Object o = getFieldValue(riakKeyField, obj); if (o != null) { key = BinaryValue.create((String) o); } } else { Object o = getFieldValue(riakKeyField, obj); if (o != null) { key = BinaryValue.create((byte[]) o); } } } return key; } // TODO: charset public void setRiakKey(T obj, BinaryValue key) { if (riakKeySetter != null) { if (riakKeySetter.getParameterTypes()[0].isArray()) { setMethodValue(riakKeySetter, obj, key.unsafeGetValue()); } else { setMethodValue(riakKeySetter, obj, key.toString()); } } else if (riakKeyField != null) { if (riakKeyField.getType().equals(String.class)) { setFieldValue(riakKeyField, obj, key.toString()); } else { setFieldValue(riakKeyField, obj, key.unsafeGetValue()); } } } // TODO: charset in annotation public BinaryValue getRiakBucketName(T obj) { BinaryValue bucketName = null; if (riakBucketNameGetter != null) { if (riakBucketNameGetter.getReturnType().isArray()) { Object o = getMethodValue(riakBucketNameGetter, obj); if (o != null) { bucketName = BinaryValue.create((byte[]) o); } } else { Object o = getMethodValue(riakBucketNameGetter, obj); if (o != null) { bucketName = BinaryValue.create((String) o); } } } else if (riakBucketNameField != null) { if (riakBucketNameField.getType().equals(String.class)) { Object o = getFieldValue(riakBucketNameField, obj); if (o != null) { bucketName = BinaryValue.create((String) o); } } else { Object o = getFieldValue(riakBucketNameField, obj); if (o != null) { bucketName = BinaryValue.create((byte[]) o); } } } return bucketName; } // TODO: charset in annotation public void setRiakBucketName(T obj, BinaryValue bucketName) { if (riakBucketNameSetter != null) { if (riakBucketNameSetter.getParameterTypes()[0].isArray()) { setMethodValue(riakBucketNameSetter, obj, bucketName.unsafeGetValue()); } else { setMethodValue(riakBucketNameSetter, obj, bucketName.toString()); } } else if (riakBucketNameField != null) { if (riakBucketNameField.getType().equals(String.class)) { setFieldValue(riakBucketNameField, obj, bucketName.toString()); } else { setFieldValue(riakBucketNameField, obj, bucketName.unsafeGetValue()); } } } // TODO: charset in annotation public BinaryValue getRiakBucketType(T obj) { BinaryValue bucketType = null; if (riakBucketTypeGetter != null) { if (riakBucketTypeGetter.getReturnType().isArray()) { Object o = getMethodValue(riakBucketTypeGetter, obj); if (o != null) { bucketType = BinaryValue.create((byte[]) o); } } else { Object o = getMethodValue(riakBucketTypeGetter, obj); if (o != null) { bucketType = BinaryValue.create((String) o); } } } else if (riakBucketTypeField != null) { if (riakBucketTypeField.getType().equals(String.class)) { Object o = getFieldValue(riakBucketTypeField, obj); if (o != null) { bucketType = BinaryValue.create((String) o); } } else { Object o = getFieldValue(riakBucketTypeField, obj); if (o != null) { bucketType = BinaryValue.create((byte[]) o); } } } return bucketType; } // TODO: charset in annotation public void setRiakBucketType(T obj, BinaryValue bucketType) { if (riakBucketTypeSetter != null) { if (riakBucketTypeSetter.getParameterTypes()[0].isArray()) { setMethodValue(riakBucketTypeSetter, obj, bucketType.unsafeGetValue()); } else { setMethodValue(riakBucketTypeSetter, obj, bucketType.toString()); } } else if (riakBucketTypeField != null) { if (riakBucketTypeField.getType().equals(String.class)) { setFieldValue(riakBucketTypeField, obj, bucketType.toString()); } else { setFieldValue(riakBucketTypeField, obj, bucketType.unsafeGetValue()); } } } public boolean hasRiakVClock() { return riakVClockField != null || riakVClockSetter != null; } public VClock getRiakVClock(T obj) { VClock vclock = null; // We allow the annotated field to be either an actual VClock, or // a byte array. if (riakVClockGetter != null) { if (riakVClockGetter.getReturnType().isArray()) { vclock = new BasicVClock((byte[]) getMethodValue(riakVClockGetter, obj)); } else { vclock = (VClock) getMethodValue(riakVClockGetter, obj); } } else if (riakVClockField != null) { if (riakVClockField.getType().isAssignableFrom(VClock.class)) { vclock = (VClock) getFieldValue(riakVClockField, obj); } else { vclock = new BasicVClock((byte[]) getFieldValue(riakVClockField, obj)); } } return vclock; } public void setRiakVClock(T obj, VClock vclock) { // We allow the annotated field to be either an actual VClock, or // a byte array. This is enforced in the AnnotationScanner if (riakVClockSetter != null) { Class pType = riakVClockSetter.getParameterTypes()[0]; if (pType.isArray()) { setMethodValue(riakVClockSetter, obj, vclock.getBytes()); } else { setMethodValue(riakVClockSetter, obj, vclock); } } else if (riakVClockField != null) { if (riakVClockField.getType().isAssignableFrom(VClock.class)) { setFieldValue(riakVClockField, obj, vclock); } else { setFieldValue(riakVClockField, obj, vclock.getBytes()); } } } public Boolean getRiakTombstone(T obj) { Boolean tombstone = null; if (riakTombstoneGetter != null) { tombstone = (Boolean) getMethodValue(riakTombstoneGetter, obj); } else if (riakTombstoneField != null) { tombstone = (Boolean) getFieldValue(riakTombstoneField, obj); } return tombstone; } public void setRiakTombstone(T obj, Boolean isDeleted) { if (riakTombstoneSetter != null) { setMethodValue(riakTombstoneSetter, obj, isDeleted); } else if (riakTombstoneField != null) { setFieldValue(riakTombstoneField, obj, isDeleted); } } public String getRiakContentType(T obj) { String contentType = null; if (riakContentTypeGetter != null) { contentType = (String) getMethodValue(riakContentTypeGetter, obj); } else if (riakContentTypeField != null) { contentType = (String) getFieldValue(riakContentTypeField, obj); } return contentType; } public void setRiakContentType(T obj, String contentType) { if (riakContentTypeSetter != null) { setMethodValue(riakContentTypeSetter, obj, contentType); } else if (riakContentTypeField != null) { setFieldValue(riakContentTypeField, obj, contentType); } } public void setRiakLastModified(T obj, Long lastModified) { if (riakLastModifiedSetter != null) { setMethodValue(riakLastModifiedSetter, obj, lastModified); } else if (riakLastModifiedField != null) { setFieldValue(riakLastModifiedField, obj, lastModified); } } public void setRiakVTag(T obj, String vtag) { if (riakVTagSetter != null) { setMethodValue(riakVTagSetter, obj, vtag); } else if (riakVTagField != null) { setFieldValue(riakVTagField, obj, vtag); } } public RiakUserMetadata getUsermetaData(RiakUserMetadata container, T obj) { for (UsermetaField uf : usermetaFields) { switch (uf.getFieldType()) { case MAP: @SuppressWarnings("unchecked") Map map = (Map) getFieldValue(uf.getField(), obj); if (map != null) { container.put(map); } break; case STRING: Object o = getFieldValue(uf.getField(), obj); String val = o == null ? null : o.toString(); String key = uf.getUsermetaDataKey(); // null is not a user meta datum if (o != null) { container.put(key, val); } break; default: break; } } for (UsermetaMethod um : usermetaMethods) { switch (um.getMethodType()) { case MAP_GETTER: @SuppressWarnings("unchecked") Map map = (Map) getMethodValue(um.getMethod(), obj); if (map != null) { container.put(map); } break; case STRING_GETTER: Object o = getMethodValue(um.getMethod(), obj); String val = o == null ? null : o.toString(); String key = um.getUsermetaDataKey(); if (o != null) { container.put(key, val); } break; default: break; } } return container; } /** * Populates an @RiakUsermeta annotated domain object with the User metadata. * @param * @param userMetadata * @param obj */ public void setUsermetaData(RiakUserMetadata userMetadata, T obj) { Field mapField = null; for (UsermetaField uf : usermetaFields) { switch (uf.getFieldType()) { case STRING: if (userMetadata.containsKey(uf.getUsermetaDataKey())) { setFieldValue(uf.getField(), obj, userMetadata.get(uf.getUsermetaDataKey())); userMetadata.remove(uf.getUsermetaDataKey()); } break; case MAP: mapField = uf.getField(); break; default: break; } } Method mapSetter = null; for (UsermetaMethod um : usermetaMethods) { switch (um.getMethodType()) { case STRING_SETTER: if (userMetadata.containsKey(um.getUsermetaDataKey())) { setMethodValue(um.getMethod(), obj, userMetadata.get(um.getUsermetaDataKey())); userMetadata.remove(um.getUsermetaDataKey()); } break; case MAP_SETTER: mapSetter = um.getMethod(); break; default: break; } } if (mapSetter != null || mapField != null) { Map mapCopy = new HashMap<>(userMetadata.size()); for (Map.Entry entry : userMetadata.getUserMetadata()) { mapCopy.put(entry.getKey().toString(), entry.getValue().toString()); } if (mapSetter != null) { setMethodValue(mapSetter, obj, mapCopy); } if (mapField != null) { setFieldValue(mapField, obj, mapCopy); } } } /** * @param The domain object type * @param obj the domain object * @return a {@link RiakIndexes} made of the values of the RiakIndex * annotated fields and methods. */ @SuppressWarnings("unchecked") public RiakIndexes getIndexes(RiakIndexes container, T obj) { for (RiakIndexField f : indexFields) { final Object val = getFieldValue(f.getField(), obj); switch (f.getFieldType()) { case SET_LONG: case LONG: // We want to create the index regardless LongIntIndex longIndex = container.getIndex(LongIntIndex.named(f.getIndexName())); if (val != null) { if (f.getFieldType() == RiakIndexField.FieldType.SET_LONG) { longIndex.add((Set) val); } else { longIndex.add((Long) val); } } break; case SET_STRING: case STRING: // We want to create the index regardless StringBinIndex stringBinIndex = container.getIndex(StringBinIndex.named(f.getIndexName())); if (val != null) { if (f.getFieldType() == RiakIndexField.FieldType.SET_STRING) { stringBinIndex.add((Set) val); } else { stringBinIndex.add((String) val); } } break; case SET_BIG_INT: case BIG_INT: BigIntIndex bigIntIndex = container.getIndex(BigIntIndex.named(f.getIndexName())); if (val != null) { if (f.getFieldType() == RiakIndexField.FieldType.SET_BIG_INT) { bigIntIndex.add((Set) val); } else { bigIntIndex.add((BigInteger) val); } } break; case SET_RAW: case RAW: { // We want to create the index regardless IndexType iType = IndexType.typeFromFullname(f.getIndexName()); RawIndex rawIndex = container.getIndex(RawIndex.named(f.getIndexName(), iType)); if (val != null) { if (f.getFieldType() == RiakIndexField.FieldType.SET_RAW) { for (byte[] bytes : (Set) val) { rawIndex.add(BinaryValue.create(bytes)); } } else { rawIndex.add(BinaryValue.create((byte[])val)); } } } default: break; } } for (RiakIndexMethod m : indexMethods) { Object val; switch (m.getMethodType()) { case SET_LONG_GETTER: case LONG_GETTER: val = getMethodValue(m.getMethod(), obj); // We want to create the index regardless LongIntIndex index = container.getIndex(LongIntIndex.named(m.getIndexName())); if (val != null) { if (m.getMethodType() == RiakIndexMethod.MethodType.SET_LONG_GETTER) { index.add((Set) val); } else { index.add((Long) val); } } break; case SET_STRING_GETTER: case STRING_GETTER: val = getMethodValue(m.getMethod(), obj); // We want to create the index regardless StringBinIndex stringBinIndex = container.getIndex(StringBinIndex.named(m.getIndexName())); if (val != null) { if (m.getMethodType() == RiakIndexMethod.MethodType.SET_STRING_GETTER) { stringBinIndex.add((Set) val); } else { stringBinIndex.add((String) val); } } break; case SET_BIG_INT_GETTER: case BIG_INT_GETTER: val = getMethodValue(m.getMethod(), obj); // We want to create the index regardless BigIntIndex bigIntIndex = container.getIndex(BigIntIndex.named(m.getIndexName())); if (val != null) { if (m.getMethodType() == RiakIndexMethod.MethodType.SET_BIG_INT_GETTER) { bigIntIndex.add((Set) val); } else { bigIntIndex.add((BigInteger) val); } } break; case SET_RAW_GETTER: case RAW_GETTER: val = getMethodValue(m.getMethod(), obj); IndexType iType = IndexType.typeFromFullname(m.getIndexName()); RawIndex rawIndex = container.getIndex(RawIndex.named(m.getIndexName(), iType)); if (val != null) { if (m.getMethodType() == RiakIndexMethod.MethodType.SET_RAW_GETTER) { for (byte[] bytes : (Set) val) { rawIndex.add(BinaryValue.create(bytes)); } } else { rawIndex.add(BinaryValue.create((byte[]) val)); } } default: break; } } return container; } /** * @param * @param indexes the RiakIndexes to copy to the domain object * @param obj the domain object to set indexes on */ public void setIndexes(RiakIndexes indexes, T obj) { // copy the index values to the correct fields for (RiakIndexField f : indexFields) { Set val = null; switch (f.getFieldType()) { case SET_LONG: case LONG: LongIntIndex longIndex = indexes.getIndex(LongIntIndex.named(f.getIndexName())); val = longIndex.values(); break; case SET_STRING: case STRING: StringBinIndex stringIndex = indexes.getIndex(StringBinIndex.named(f.getIndexName())); val = stringIndex.values(); break; case SET_BIG_INT: case BIG_INT: BigIntIndex bigIntIndex = indexes.getIndex(BigIntIndex.named(f.getIndexName())); val = bigIntIndex.values(); break; case SET_RAW: case RAW: IndexType iType = IndexType.typeFromFullname(f.getIndexName()); RawIndex rawIndex = indexes.getIndex((RawIndex.named(f.getIndexName(), iType))); // Convert from BinaryValue to bytes Set byteSet = new HashSet<>(); for (BinaryValue bv : rawIndex.values()) { byteSet.add(bv.unsafeGetValue()); } val = byteSet; break; default: break; } if (val != null) { if (f.getFieldType() == RiakIndexField.FieldType.LONG || f.getFieldType() == RiakIndexField.FieldType.STRING || f.getFieldType() == RiakIndexField.FieldType.BIG_INT || f.getFieldType() == RiakIndexField.FieldType.RAW) { if (!val.isEmpty()) { setFieldValue(f.getField(), obj, val.iterator().next()); // take the first value } } else { setFieldValue(f.getField(), obj, val); } } } for (RiakIndexMethod m : indexMethods) { Set val = null; switch (m.getMethodType()) { case SET_LONG_SETTER: case LONG_SETTER: LongIntIndex longIndex = indexes.getIndex(LongIntIndex.named(m.getIndexName())); val = longIndex.values(); break; case SET_STRING_SETTER: case STRING_SETTER: StringBinIndex stringIndex = indexes.getIndex(StringBinIndex.named(m.getIndexName())); val = stringIndex.values(); break; case SET_BIG_INT_SETTER: case BIG_INT_SETTER: BigIntIndex bigIntIndex = indexes.getIndex(BigIntIndex.named(m.getIndexName())); val = bigIntIndex.values(); break; case SET_RAW_SETTER: case RAW_SETTER: IndexType iType = IndexType.typeFromFullname(m.getIndexName()); RawIndex rawIndex = indexes.getIndex(RawIndex.named(m.getIndexName(), iType)); // Convert from BinaryValue to bytes Set byteSet = new HashSet<>(); for (BinaryValue bv : rawIndex.values()) { byteSet.add(bv.unsafeGetValue()); } val = byteSet; break; default: break; } if (val != null) { if (m.getMethodType() == RiakIndexMethod.MethodType.LONG_SETTER || m.getMethodType() == RiakIndexMethod.MethodType.STRING_SETTER || m.getMethodType() == RiakIndexMethod.MethodType.BIG_INT_SETTER || m.getMethodType() == RiakIndexMethod.MethodType.RAW_SETTER) { if (!val.isEmpty()) { setMethodValue(m.getMethod(), obj, val.iterator().next()); // take the first value } } else { setMethodValue(m.getMethod(), obj, val); } } } } @SuppressWarnings("unchecked") public RiakLinks getLinks(RiakLinks container, T obj) { Object o = null; if (riakLinksGetter != null) { o = getMethodValue(riakLinksGetter, obj); } else if (riakLinksField != null) { o = getFieldValue(riakLinksField, obj); } if (o != null) { container.addLinks((Collection) o); } return container; } public void setLinks(RiakLinks links, T obj) { if (riakLinksSetter != null) { setMethodValue(riakLinksSetter, obj, links.getLinks()); } else if (riakLinksField != null) { setFieldValue(riakLinksField, obj, links.getLinks()); } } public static class Builder { private Field riakKeyField; private Method riakKeySetter; private Method riakKeyGetter; private Field riakLinksField; private Method riakLinksGetter; private Method riakLinksSetter; private Field riakVClockField; private Method riakVClockSetter; private Method riakVClockGetter; private Field riakTombstoneField; private Method riakTombstoneSetter; private Method riakTombstoneGetter; private Field riakContentTypeField; private Method riakContentTypeGetter; private Method riakContentTypeSetter; private Field riakLastModifiedField; private Method riakLastModified; private Field riakVTagField; private Method riakVTagSetter; private Field riakBucketNameField; private Method riakBucketNameSetter; private Method riakBucketNameGetter; private Field riakBucketTypeField; private Method riakBucketTypeSetter; private Method riakBucketTypeGetter; private final List usermetaFields; private final List usermetaMethods; private final List indexFields; private final List indexMethods; /** * Constructs a builder for a new AnnotationInfo */ public Builder() { } { usermetaFields = new LinkedList<>(); usermetaMethods = new LinkedList<>(); indexFields = new LinkedList<>(); indexMethods = new LinkedList<>(); } /** * Set the @RiakKey annotated field. * * @param f the annotated field * @return a reference to this object */ public Builder withRiakKeyField(Field f) { validateStringOrByteField(f, "@RiakKey"); this.riakKeyField = ClassUtil.checkAndFixAccess(f); return this; } /** * Set the @RiakKey annotated getter. * * @param m the annotated method * @return a reference to this object */ public Builder withRiakKeyGetter(Method m) { validateStringOrByteMethod(m, "@RiakKey"); this.riakKeyGetter = ClassUtil.checkAndFixAccess(m); return this; } /** * Set the @RiakKey annotated setter. * * @param m the annotated setter * @return a reference to this object */ public Builder withRiakKeySetter(Method m) { validateStringOrByteMethod(m, "@RiakKey"); this.riakKeySetter = ClassUtil.checkAndFixAccess(m); return this; } /** * Set the @RiakLinks annotated field. * * @param f the annotated field * @return a reference to this object */ public Builder withRiakLinksField(Field f) { validateRiakLinksField(f); this.riakLinksField = ClassUtil.checkAndFixAccess(f); return this; } /** * Set the @RiakLinks annotated getter. * * @param m the annotated method * @return a reference to this object */ public Builder withRiakLinksGetter(Method m) { validateRiakLinksMethod(m); this.riakLinksGetter = ClassUtil.checkAndFixAccess(m); return this; } /** * Set the @RiakLinks annotated setter. * * @param m the annotated method * @return a reference to this object * */ public Builder withRiakLinksSetter(Method m) { validateRiakLinksMethod(m); this.riakLinksSetter = ClassUtil.checkAndFixAccess(m); return this; } /** * Add a @RiakUsermeta annotated field. * * @param f the annotated field. * @return a reference to this object. */ public Builder addRiakUsermetaField(Field f) { this.usermetaFields.add(new UsermetaField(ClassUtil.checkAndFixAccess(f))); return this; } /** * Add a @RiakUsermeta annotated method * * @param m the annotated method * @return a reference to this object */ public Builder addRiakUsermetaMethod(Method m) { this.usermetaMethods.add(new UsermetaMethod(ClassUtil.checkAndFixAccess(m))); return this; } /** * Add a @RiakIndex annotated method. * * @param m the annotated method * @return a reference to this object */ public Builder addRiakIndexMethod(Method m) { this.indexMethods.add(new RiakIndexMethod(ClassUtil.checkAndFixAccess(m))); return this; } /** * Add a @RiakIndex annotated field. * * @param f the annotated field * @return a reference to this object */ public Builder addRiakIndexField(Field f) { this.indexFields.add(new RiakIndexField(ClassUtil.checkAndFixAccess(f))); return this; } /** * Set the @RiakVClock annotated field. * * @param f the annotated field * @return a reference to this object */ public Builder withRiakVClockField(Field f) { validateVClockField(f); this.riakVClockField = ClassUtil.checkAndFixAccess(f); return this; } /** * Set the @RiakVClock annotated setter method. * * @param m the annotated method. * @return a reference to this object */ public Builder withRiakVClockSetter(Method m) { validateVClockMethod(m); this.riakVClockSetter = ClassUtil.checkAndFixAccess(m); return this; } /** * Set the @RiakVClock annotated getter method. * * @param m the annotated method * @return a reference to this object. */ public Builder withRiakVClockGetter(Method m) { validateVClockMethod(m); this.riakVClockGetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakTombstoneField(Field f) { validateTombstoneField(f); this.riakTombstoneField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakTombstoneSetter(Method m) { validateTombstoneMethod(m); this.riakTombstoneSetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakTombstoneGetter(Method m) { validateTombstoneMethod(m); this.riakTombstoneGetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakContentTypeField(Field f) { validateContentTypeField(f); this.riakContentTypeField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakContentTypeSetter(Method m) { validateContentTypeMethod(m); this.riakContentTypeSetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakContentTypeGetter(Method m) { validateContentTypeMethod(m); this.riakContentTypeGetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakLastModifiedField(Field f) { validateLastModifiedField(f); this.riakLastModifiedField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakLastModifiedSetter(Method m) { validateLastModifiedMethod(m); this.riakLastModified = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakVTagField(Field f) { validateVTagField(f); this.riakVTagField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakVTagSetter(Method m) { validateVTagMethod(m); this.riakVTagSetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakBucketNameField(Field f) { validateStringOrByteField(f, "@RiakBucketName"); this.riakBucketNameField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakBucketNameSetter(Method m) { validateStringOrByteMethod(m, "@RiakBucketName"); this.riakBucketNameSetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakBucketNameGetter(Method m) { validateStringOrByteMethod(m, "@RiakBucketName"); this.riakBucketNameGetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakBucketTypeField(Field f) { validateStringOrByteField(f, "@RiakBucketType"); this.riakBucketTypeField = ClassUtil.checkAndFixAccess(f); return this; } public Builder withRiakBucketTypeSetter(Method m) { validateStringOrByteMethod(m, "@RiakBucketType"); this.riakBucketTypeSetter = ClassUtil.checkAndFixAccess(m); return this; } public Builder withRiakBucketTypeGetter(Method m) { validateStringOrByteMethod(m, "@RiakBucketType"); this.riakBucketTypeGetter = ClassUtil.checkAndFixAccess(m); return this; } public AnnotationInfo build() { return new AnnotationInfo(this); } private void validateRiakLinksField(Field riakLinksField) { if (Collection.class.isAssignableFrom(riakLinksField.getType())) { Type t = riakLinksField.getGenericType(); if (t instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) t; if (type.getRawType().equals(Collection.class)) { Type[] genericParams = type.getActualTypeArguments(); if (genericParams.length == 1 && genericParams[0].equals(RiakLink.class)) { return; } } } } else if (riakLinksField.getType().equals(RiakLinks.class)) { return; } throw new IllegalArgumentException("@RiakLinks field must be Collection"); } private void validateRiakLinksMethod(Method m) { if (m.getParameterTypes().length == 1) { // it's a setter, check the arg type Type[] genericParameterTypes = m.getGenericParameterTypes(); Type t = genericParameterTypes[0]; if (t instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) t; if (pType.getRawType().equals(Collection.class)) { Class genericType = (Class) pType.getActualTypeArguments()[0]; if (RiakLink.class.equals(genericType)) { return; } } } throw new IllegalArgumentException("@RiakLinks setter must take Collection"); } else if (m.getParameterTypes().length == 0) { // it's a getter, check return type Type t = m.getGenericReturnType(); if (t instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) t; if (pType.getRawType().equals(Collection.class)) { Class genericType = (Class) pType.getActualTypeArguments()[0]; if (RiakLink.class.equals(genericType)) { return; } } } throw new IllegalArgumentException("@RiakLinks getter must return Collection"); } } private void validateVClockField(Field f) { if (!(f.getType().isArray() && f.getType().getComponentType().equals(byte.class)) && !f.getType().isAssignableFrom(VClock.class)) { throw new IllegalArgumentException("@RiakVClock field must be a VClock or byte[]"); } } private void validateVClockMethod(Method m) { if (m.getParameterTypes().length == 1) { // It's a setter Class pType = m.getParameterTypes()[0]; if (!(pType.isArray() && pType.getComponentType().equals(byte.class)) && !pType.isAssignableFrom(VClock.class)) { throw new IllegalArgumentException("@RiakVClock setter must take VClock or byte[]"); } } else if (m.getParameterTypes().length == 0) { Class rType = m.getReturnType(); if (!(rType.isArray() && rType.getComponentType().equals(byte.class)) && !rType.isAssignableFrom(VClock.class)) { throw new IllegalArgumentException("@RiakVClock getter must return VClock or byte[]"); } } } private void validateTombstoneField(Field f) { if (!f.getType().equals(Boolean.class) && !f.getType().equals(boolean.class)) { throw new IllegalArgumentException("@RiakTombstone field must be Boolean or boolean"); } } private void validateTombstoneMethod(Method m) { if (m.getParameterTypes().length == 1) { Class pType = m.getParameterTypes()[0]; if (!pType.equals(Boolean.class) && !pType.equals(boolean.class)) { throw new IllegalArgumentException("@RiakTombstone setter must take boolean or Boolean"); } } else if (m.getParameterTypes().length == 0) { Class rType = m.getReturnType(); if (!rType.equals(Boolean.class) && !rType.equals(boolean.class)) { throw new IllegalArgumentException("@RiakTombstone getter must return boolean or Boolean"); } } } private void validateContentTypeField(Field f) { if (!f.getType().equals(String.class)) { throw new IllegalArgumentException("@RiakContentType field must be a String."); } } private void validateContentTypeMethod(Method m) { if (m.getParameterTypes().length == 1) { if (!String.class.equals(m.getParameterTypes()[0])) { throw new IllegalArgumentException("@RiakContentType setter must take a String."); } } else if (m.getParameterTypes().length == 0) { if (!m.getReturnType().equals(String.class)) { throw new IllegalArgumentException("@RiakContentType getter must return a String."); } } } private void validateLastModifiedField(Field f) { if (!f.getType().equals(Long.class) && !f.getType().equals(long.class)) { throw new IllegalArgumentException("@RiakLastModified field must be a Long or long."); } } private void validateLastModifiedMethod(Method m) { if (m.getParameterTypes().length == 0) { throw new IllegalArgumentException("@RiakLastModified can only be applied to a setter method."); } else if (m.getParameterTypes().length == 1) { Class pType = m.getParameterTypes()[0]; if (!pType.equals(Long.class) && !pType.equals(long.class)) { throw new IllegalArgumentException("@RiakLastModified setter must take a long or Long."); } } } private void validateVTagField(Field f) { if (!f.getType().equals(String.class)) { throw new IllegalArgumentException("@RiakVTag field must be a String."); } } private void validateVTagMethod(Method m) { if (m.getParameterTypes().length == 0) { throw new IllegalArgumentException("@RiakVTag can only be applied to a setter method."); } else if (m.getParameterTypes().length == 1) { Class pType = m.getParameterTypes()[0]; if (!pType.equals(String.class)) { throw new IllegalArgumentException("@RiakVTag setter must take a String."); } } } private void validateStringOrByteField(Field f, String annotation) { if (!(f.getType().isArray() && f.getType().getComponentType().equals(byte.class)) && !f.getType().isAssignableFrom(String.class)) { throw new IllegalArgumentException(annotation + " field must be a String or byte[]."); } } private void validateStringOrByteMethod(Method m, String annotation) { if (m.getParameterTypes().length == 1) { // It's a setter Class pType = m.getParameterTypes()[0]; if (!(pType.isArray() && pType.getComponentType().equals(byte.class)) && !pType.isAssignableFrom(String.class)) { throw new IllegalArgumentException(annotation + " setter must take String or byte[]"); } } else if (m.getParameterTypes().length == 0) { Class rType = m.getReturnType(); if (!(rType.isArray() && rType.getComponentType().equals(byte.class)) && !rType.isAssignableFrom(String.class)) { throw new IllegalArgumentException(annotation + " getter must return String or byte[]"); } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy