package org.radargun.stages.cache.generators;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.Random;
import org.radargun.config.DefinitionElement;
import org.radargun.config.Init;
import org.radargun.config.Property;
import org.radargun.logging.Log;
import org.radargun.logging.LogFactory;
/**
* @author Radim Vansa <rvansa@redhat.com>
*/
@DefinitionElement(name = "jpa", doc = "Instantiates JPA entities. The constructor for the entities must match to the generateValue() method.")
public class JpaValueGenerator implements ValueGenerator {
protected static Log log = LogFactory.getLog(JpaValueGenerator.class);
@Property(name = "class", doc = "Fully qualified name of the value class.", optional = false)
private String clazzName;
private Class<?> clazz;
private Class<? extends Annotation> entityClazz;
private Constructor<?> ctor;
@Init
public void init() {
try {
entityClazz = (Class<? extends Annotation>) Class.forName("javax.persistence.Entity");
clazz = Class.forName(clazzName);
if (!clazz.isAnnotationPresent(entityClazz)) {
throw new IllegalArgumentException("Class " + clazz.getName() + " is not an entity - no @Entity present");
}
ctor = clazz.getConstructor(Object.class, int.class, Random.class);
} catch (Exception e) {
// trace as this can happen on master node
log.trace("Could not initialize generator " + this, e);
}
}
@Override
public Object generateValue(Object key, int size, Random random) {
if (ctor == null) throw new IllegalStateException("The generator was not properly initialized");
try {
return ctor.newInstance(key, size, random);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
@Override
public int sizeOf(Object value) {
if (value instanceof JpaValue) {
return ((JpaValue) value).size();
} else {
throw new IllegalArgumentException();
}
}
@Override
public boolean checkValue(Object value, Object key, int expectedSize) {
if (clazz == null) throw new IllegalStateException("The generator was not properly initialized");
return clazz.isInstance(value) && ((JpaValue) value).check(expectedSize);
}
public static String getRandomString(int size, Random random) {
StringBuilder sb = new StringBuilder(size);
for (int i = 0; i < size; ++i) {
sb.append((char) (random.nextInt(26) + 'A'));
}
return sb.toString();
}
public abstract static class JpaValue implements Serializable {
public int size() {
throw new UnsupportedOperationException();
}
public boolean check(int expectedSize) {
return true;
}
}
}