/*
* JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com)
*
* 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 jef.tools.string;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import jef.common.wrapper.IntRange;
import jef.tools.chinese.ChineseCharProvider;
import jef.tools.chinese.ChineseCharProvider.Type;
import jef.tools.reflect.BeanWrapper;
import jef.tools.reflect.ClassUtils;
import jef.tools.reflect.GenericUtils;
import jef.tools.reflect.UnsafeUtils;
/**
* 生成随机数据,以及由随机数据填充的复杂bean
* @author jiyi
*
*/
public class RandomData {
/**
* 复杂bean最大嵌套深度
*/
public static int MAX_LEVEL = 3;
private static Class<? extends Annotation> clz_generatred;
private static Class<? extends Annotation> clz_lob;
private static Class<? extends Annotation> clz_column;
private static Method length;
static{
try{
clz_generatred=Class.forName("javax.persistence.GeneratedValue").asSubclass(Annotation.class);
}catch(Exception e){
}
try{
clz_lob=Class.forName("javax.persistence.Lob").asSubclass(Annotation.class);
}catch(Exception e){
}
try{
clz_column=Class.forName("javax.persistence.Column").asSubclass(Annotation.class);
length=clz_column.getMethod("length");
}catch(Exception e){
}
}
private RandomData() {
}
private static Random rnd = new Random();
public static <T> T newInstance(Class<T> clz) {
return processBeanType(clz, 0); // 嵌套深度
}
public static void fill(Object bean) {
fillValues(BeanWrapper.wrap(bean), 0); // 嵌套深度
}
private static <T> T processBeanType(Class<T> clz, int level) {
if (level > MAX_LEVEL)
return null;
// 开始
T instance = null;
instance = UnsafeUtils.newInstance(clz);
BeanWrapper bw = BeanWrapper.wrap(instance, BeanWrapper.NORMAL);
fillValues(bw,level);
return instance;
}
private static void fillValues(BeanWrapper bw,int level) {
for (String name : bw.getRwPropertyNames()) {
if (isGeneratedVal(bw,name))
continue;
java.lang.reflect.Type genericType = bw.getPropertyType(name);// 泛型类型
Object value = newInstance(genericType, level, getEtaLength(bw,name));
if (value != null)
bw.setPropertyValue(name, value);
}
}
private static int getEtaLength(BeanWrapper bw, String name) {
if(clz_lob!=null){
if(bw.getAnnotationOnField(name, clz_lob)!=null){
return 85;
}
Object column=bw.getAnnotationOnField(name, clz_column);
if(column!=null){
try {
Integer result=(Integer)length.invoke(column);
return result==null?0:result.intValue()/2;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return 0;
}
private static boolean isGeneratedVal(BeanWrapper bw, String name) {
if(clz_generatred!=null){
return bw.getAnnotationOnField(name, clz_generatred)!=null;
}
return false;
}
private static Object newInstance(java.lang.reflect.Type type, int level, int etaColumnLength) {
if (type == Integer.class || type == Integer.TYPE) {
return randomInteger(1, 1000);
} else if (type == Short.class || type == Short.TYPE) {
return (short) randomInteger(1, 1000);
} else if (type == Long.class || type == Long.TYPE) {
return randomLong(1, 9999999999L);
} else if (type == Boolean.class || type == Boolean.TYPE) {
return randomInteger(0, 2) > 0;
} else if (type == Character.class || type == Character.TYPE) {
return (char) randomInteger(1, 128);
} else if (type == Byte.class || type == Byte.TYPE) {
return randomByte();
} else if (type == Double.class || type == Double.TYPE) {
return randomDouble(0, 100);
} else if (type == Float.class || type == Float.TYPE) {
return randomFloat(0, 100);
} else if (type == String.class) {
if (etaColumnLength > 199) {
return randomString(ChineseCharProvider.getInstance().get(Type.CHINESE_LAST_NAME), new IntRange(50, 200));
} else if (etaColumnLength == 0) {
return randomChineseName();
} else {
return randomString(CharUtils.ALPHA_NUM_UNDERLINE, new IntRange(1, etaColumnLength));
}
} else if (type == Date.class) {
long cur = System.currentTimeMillis();
return randomDate(new Date(cur - 300000), new Date(cur + 1000000));
}
Class<?> raw = GenericUtils.getRawClass(type);
if (raw.isArray()) {
return processArrayType(raw.getComponentType(), level + 1);
} else if (List.class.isAssignableFrom(raw)) {
return processListTypes(GenericUtils.getCollectionType(type), level + 1);
} else if (Map.class.isAssignableFrom(raw)) {
return processMapTypes(GenericUtils.getMapKeyAndValueTypes(type, Map.class), level + 1);
} else if (Set.class.isAssignableFrom(raw)) {
return processSetTypes(GenericUtils.getCollectionType(type), level + 1);
} else if (ClassUtils.hasConstructor(raw)) {// 有空构造的对象就构造
return processBeanType(raw, level + 1);
}
return null;
}
private static Object processArrayType(Class<?> componentType, int level) {
if (componentType == byte.class) {
return randomByteArray(1024);
} else {
Object obj = newInstance(componentType, level,0);
if (obj == null)
return null;
Object array = Array.newInstance(componentType, 1);
Array.set(array, 0, obj);
return array;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Object processSetTypes(java.lang.reflect.Type collectionType, int level) {
Object obj = newInstance(collectionType, level,0);
if (obj == null)
return null;
Set result = new HashSet();
result.add(obj);
return result;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Object processMapTypes(java.lang.reflect.Type[] mapKeyAndValueTypes, int level) {
Object key = newInstance(mapKeyAndValueTypes[0], level,0);
Object value = newInstance(mapKeyAndValueTypes[1], level,0);
if (key == null || value == null)
return null;
Map result = new HashMap();
result.put(key, value);
return result;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Object processListTypes(java.lang.reflect.Type collectionType, int level) {
Object obj = newInstance(collectionType, level,0);
if (obj == null)
return null;
List result = new ArrayList();
result.add(obj);
return result;
}
// 生成随机的日期
public static Date randomDate(Date startDate, Date endDate) {
long start = startDate.getTime()/1000;
long end = endDate.getTime()/1000;
return new Date(randomLong(start, end)*1000);
}
// 生成随机的整数
public static int randomInteger(int start, int end) {
return start + rnd.nextInt(end - start);
}
public static long randomLong(long start, long end) {
int i = (int) (end - start);
if(start+i!=end){
i=Integer.MAX_VALUE;
}else if (i < 0)
i = -i;
return start + rnd.nextInt(i);
}
public static float randomFloat(float start, float end) {
int n = (int) (end - start);
return start + rnd.nextFloat() + n > 0 ? rnd.nextInt(n) : 0;
}
public static double randomDouble(double start, double end) {
int n = (int) (end - start);
return start + rnd.nextFloat() + n > 0 ? rnd.nextInt(n) : 0;
}
// 生成中文数据
public static String randomChineseName(int min, int max) {
return randomString(ChineseCharProvider.getInstance().get(Type.CHINESE_LAST_NAME), new IntRange(min, max));
}
// 生成中文名称
public static String randomChineseName() {
return randomChineseName(2, 3);
}
public static String randomString(int maxLen) {
IntRange range=new IntRange(1, maxLen);
return randomString(CharUtils.ALPHA_NUM_UNDERLINE, range);
}
public static String randomString(int min,int maxLen) {
IntRange range=new IntRange(min, maxLen);
return randomString(CharUtils.ALPHA_NUM_UNDERLINE, range);
}
/**
* 生成随机的字符串
*
* @param range
* @param length
* @return
*/
public static String randomString(String range, IntRange length) {
return randomString(range.toCharArray(), length);
}
// 生成随机的字符串
public static String randomString(char[] range, IntRange length) {
StringBuilder sb = new StringBuilder();
int width = range.length;
int realLen = rnd.nextInt(length.getEnd() - length.getStart() + 1) + length.getLeastValue();
for (int n = 0; n <= realLen - 1; n++) {
sb.append(range[rnd.nextInt(width)]);
}
return sb.toString();
}
/**
* 生成随机的一个char
*
* @param length
* @return
*/
public static char randomChar(int length) {
return (char) randomInteger(1, 65536);
}
/**
* 生成随机的一个字节
*
* @return
*/
public static byte randomByte() {
return (byte) (rnd.nextInt(256) - 128);
}
/**
* 生成随机的字节组
*
* @param length
* @return
*/
public static byte[] randomByteArray(int length) {
byte[] b = new byte[length];
rnd.nextBytes(b);
return b;
}
public static String[] randomStringArray(int length,int stringLegth){
String[] ss=new String[length];
for(int i=0;i<length;i++){
ss[i]=randomString(stringLegth);
}
return ss;
}
// 生成枚举类的项目
public static <T extends Enum<T>> T randomEnum(Class<T> c) {
T[] enums = c.getEnumConstants();
int n = rnd.nextInt(enums.length);
return enums[n];
}
// 返回枚局的元素
public static <T> T randomElement(T[] enums) {
int n = rnd.nextInt(enums.length);
return enums[n];
}
/**
* 创建多个实例
*
* @param <T>
* @param class1
* @param i
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T[] newArrayInstance(Class<T> class1, int i) {
T[] array = (T[]) Array.newInstance(class1, i);
for (int n = 0; n < i; n++) {
array[n] = newInstance(class1);
}
return array;
}
public static boolean randomBoolean() {
return rnd.nextBoolean();
}
}