/*
* 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.database.wrapper.populator;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import javax.persistence.PersistenceException;
import jef.accelerator.bean.BeanAccessor;
import jef.accelerator.bean.FastBeanWrapperImpl;
import jef.common.Entry;
import jef.database.DebugUtil;
import jef.database.Field;
import jef.database.IQueryableEntity;
import jef.database.LazyLoadProcessor;
import jef.database.LazyLoadTask;
import jef.database.LobLazyLoadTask;
import jef.database.Session;
import jef.database.Session.PopulateStrategy;
import jef.database.dialect.DatabaseDialect;
import jef.database.dialect.type.ColumnMapping;
import jef.database.dialect.type.ColumnMappings;
import jef.database.dialect.type.ResultSetAccessor;
import jef.database.innerpool.FieldPopulator;
import jef.database.innerpool.MultiplePopulator;
import jef.database.innerpool.NestedObjectPopulator;
import jef.database.jdbc.result.IResultSet;
import jef.database.meta.AbstractRefField;
import jef.database.meta.AliasProvider;
import jef.database.meta.EntityType;
import jef.database.meta.Feature;
import jef.database.meta.IReferenceAllTable;
import jef.database.meta.IReferenceColumn;
import jef.database.meta.ITableMetadata;
import jef.database.meta.MetaHolder;
import jef.database.meta.Reference;
import jef.database.query.EntityMappingProvider;
import jef.database.query.ISelectItemProvider;
import jef.database.query.Query;
import jef.script.javascript.Var;
import jef.tools.ArrayUtils;
import jef.tools.Assert;
import jef.tools.reflect.ArrayWrapper;
import jef.tools.reflect.BeanWrapper;
import jef.tools.reflect.UnsafeUtils;
public class ResultPopulatorImpl implements ResultSetPopulator{
public static final ResultSetPopulator instance=new ResultPopulatorImpl();
public <T> Iterator<T> iteratorSimple(IResultSet rs, Class<T> clz) {
return new SimpleRsIterator<T>(rs, clz);
}
public <T> Iterator<T> iteratorNormal(Session session, IResultSet rs,EntityMappingProvider context,Transformer transformers) {
return new NormalRsIterator<T>(rs, context, transformers, session);
}
public Iterator<Object[]> iteratorMultipie(IResultSet rs, EntityMappingProvider context,Transformer transformer) {
return new MultipleRsIterator(rs, context,transformer);
}
public <T> Iterator<T> iteratorPlain(IResultSet rs, Transformer transformers) {
return new PlainRsIterator<T>(rs, transformers);
}
public Iterator<Map<String, Object>> iteratorMap(IResultSet rs,Transformer transformers) {
return new VarRsIterator(rs, transformers);
}
/**
* Map模式拼装
*/
public List<Map<String, Object>> toVar(IResultSet rs, Transformer transformers) {
VarRsIterator rsVarIterator = new VarRsIterator(rs, transformers);
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(40);
while (rsVarIterator.hasNext()) {
Map<String, Object> v = rsVarIterator.next();
// v.remove("");
list.add((Var) v);
}
return list;
}
/**
* 简单模式拼装。限于对SIMPLE_CLASSES(如字符串、数字、日期等基本类型)
*
* @param rs
* @param clz
* @param strategies
* @return
*/
public <T> List<T> toSimpleObjects(IResultSet rs, Class<T> clz) {
List<T> list = new ArrayList<T>();
for (Iterator<T> iter = new SimpleRsIterator<T>(rs, clz); iter.hasNext();) {
list.add(iter.next());
}
return list;
}
/**
* 平面模式拼装
*/
public <T> List<T> toPlainJavaObject(IResultSet rs, Transformer transformers) {
List<T> list = new ArrayList<T>();
for (Iterator<T> iter = new PlainRsIterator<T>(rs, transformers); iter.hasNext();) {
list.add(iter.next());
}
return list;
}
/**
* 多重模式, 拼装成多个对象
*/
public List<Object[]> toDataObjectMap(IResultSet rs, EntityMappingProvider context,Transformer transformer) {
List<Object[]> list = new ArrayList<Object[]>();
for (Iterator<Object[]> iter = new MultipleRsIterator(rs, context,transformer); iter.hasNext();) {
list.add(iter.next());
}
return list;
}
/**
* 标准模式
*/
public <T> List<T> toJavaObject(Session session, IResultSet rs, EntityMappingProvider context, Transformer transformers) {
List<T> list = new ArrayList<T>();
for (Iterator<T> iter = new NormalRsIterator<T>(rs, context, transformers, session); iter.hasNext();) {
list.add(iter.next());
}
return list;
}
// /////////////////////////////////////////////////////////
@SuppressWarnings("all")
final static class VarRsIterator implements Iterator<Map<String, Object>> {
private IResultSet rs;
private boolean hasNext;
private List<Mapper<?>> mappers;
public VarRsIterator(IResultSet rs,Transformer transformers) {
this.rs = rs;
/*
* Eclipse或者findbugs或者checkStyle很有可能都对下面这句语句提出了警告。但事实上这是一个性能优化上的小技巧
*
* 如果把一句话拆成两句来写
* hasNext=rs.next();
* if(hasNext){
* 这样可以消除警告。但是从编译后的代码来看。两句话的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: putfield #62; //Field hasNext:Z
* 43: aload_0
* 44: getfield #62; //Field hasNext:Z
* 现在这种写法的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: dup_x1
* 41: putfield #62; //Field hasNext:Z
* 在栈内做一次 dup的开销要小于getfield的开销。(前者是栈访问后者是堆访问)
*
* 各种代码检查工具是针对写不好代码的人起到查漏补遗的作用的,但是不能因此在有能力控制代码逻辑正确性的前提下,不去追求性能更好的写法。
* 因此,此处就是要这么写,不管各种代码检查工具如何警告,不管省下的性能多么微不足道,我坚持用性能最优的写法。
*/
if (hasNext = rs.next()) { //请忽略代码检查工具的告警
initColumnAccessor(transformers);
}
}
private void initColumnAccessor(Transformer transformers) {
this.mappers=transformers.getMapper();
ColumnMeta cnames = rs.getColumns();
cnames.initSchemas(transformers);
for (String schema : cnames.getSchemas()) {
for (ColumnDescription s : cnames.getColumns(schema)) {
s.setAccessor(ColumnMappings.RAW);
}
}
}
public boolean hasNext() {
return hasNext;
}
public Var next() {
if (!hasNext)
throw new NoSuchElementException();
Var v = new Var();
ColumnMeta cnames = rs.getColumns();
for (String schema : cnames.getSchemas()) {
for (ColumnDescription s : cnames.getColumns(schema)) {
try {
v.putLowerKey(s.getSimpleName(), s.getValue(rs));
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
}
BeanWrapper wapper = BeanWrapper.wrap(v);
for(Mapper<?> mapp:mappers){
try {
mapp.process(wapper, rs);
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
hasNext = rs.next();
return v;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
final static class SimpleRsIterator<T> implements Iterator<T> {
private IResultSet rs;
private ResultSetAccessor accessor;
public SimpleRsIterator(IResultSet rs, Class<T> clz) {
this.rs = rs;
hasNext = rs.next();
if (hasNext) {
this.accessor = initColumnAccessor(clz,rs.getColumns().getN(0));
}
}
private ResultSetAccessor initColumnAccessor(Class<?> clz,ColumnDescription c) {
ResultSetAccessor accessor = ColumnMappings.getAccessor(clz, null, c, clz.isPrimitive());
if (accessor == null) {
throw new IllegalArgumentException(clz + "is not a known simple datetype.");
}
return accessor;
}
public boolean hasNext() {
return hasNext;
}
@SuppressWarnings("unchecked")
public T next() {
if (!hasNext)
throw new NoSuchElementException();
try {
return (T) accessor.jdbcGet(rs, 1);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
hasNext = rs.next();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
private boolean hasNext;
}
final static class PlainRsIterator<T> implements Iterator<T> {
private IResultSet rs;
private Class<T> clz;
private boolean skipAnnataion;
private ObjectPopulator populateMeta;
private List<Mapper<?>> extendPopulator;
@SuppressWarnings("all")
public PlainRsIterator(IResultSet rs, Transformer transformers) {
this.rs = rs;
/*
* Eclipse或者findbugs或者checkStyle很有可能都对下面这句语句提出了警告。但事实上这是一个性能优化上的小技巧
*
* 如果把一句话拆成两句来写
* hasNext=rs.next();
* if(hasNext){
* 这样可以消除警告。但是从编译后的代码来看。两句话的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: putfield #62; //Field hasNext:Z
* 43: aload_0
* 44: getfield #62; //Field hasNext:Z
* 现在这种写法的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: dup_x1
* 41: putfield #62; //Field hasNext:Z
* 在栈内做一次 dup的开销要小于getfield的开销。(前者是栈访问后者是堆访问)
*
* 各种代码检查工具是针对写不好代码的人起到查漏补遗的作用的,但是不能因此在有能力控制代码逻辑正确性的前提下,不去追求性能更好的写法。
* 因此,此处就是要这么写,不管各种代码检查工具如何警告,不管省下的性能多么微不足道,我坚持用性能最优的写法。
*/
if (hasNext = rs.next()) {//eclipse warning is not correct. here i'm attempt to set variable 'hasNext' and judge it as condition.
this.clz = (Class<T>) transformers.getResultClazz();
skipAnnataion = ArrayUtils.fastContains(transformers.getStrategy(), PopulateStrategy.SKIP_COLUMN_ANNOTATION);
ColumnMeta columnMeta = rs.getColumns();
columnMeta.initSchemas(transformers);
populateMeta = initColumnAccessor(columnMeta,transformers);
}
}
private ObjectPopulator initColumnAccessor(ColumnMeta columnMeta,Transformer transformers) {
extendPopulator=transformers.getMapper();
BeanAccessor ba = FastBeanWrapperImpl.getAccessorFor(clz);
return fillPlain(ba,skipAnnataion,columnMeta);
}
public boolean hasNext() {
return hasNext;
}
public T next() {
if (!hasNext)
throw new NoSuchElementException();
IResultSet rs=this.rs;
try {
T retObj = (T) UnsafeUtils.newInstance(clz);
BeanWrapper wrapper = BeanWrapper.wrap(retObj);
populateMeta.process(wrapper, rs);
for(Mapper<?> m:extendPopulator){
m.process(wrapper, rs);
}
endPopulate(retObj);
return retObj;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
hasNext = rs.next();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
private boolean hasNext;
}
final static private class RawArrayMapper extends Mapper<Object[]>{
private ResultSetAccessor[] accessor;
public RawArrayMapper(ResultSetAccessor[] accessor) {
this.accessor=accessor;
}
@Override
protected void transform(Object[] obj, IResultSet rs) throws SQLException {
int size=accessor.length;
for(int i=0;i<size;i++){
obj[i]=accessor[i].jdbcGet(rs, i+1);
}
}
}
final static class MultipleRsIterator implements Iterator<Object[]> {
private IResultSet rs;
private int size;
private List<Mapper<?>> populators;
private Class<?> componentType;
@SuppressWarnings("all")
public MultipleRsIterator(IResultSet rs, EntityMappingProvider context,Transformer transformer) {
this.componentType=transformer.getResultClazz().getComponentType();
Assert.isFalse(componentType.isPrimitive(),"Please use the complex type of "+componentType);
this.rs = rs;
/*
* Eclipse或者findbugs或者checkStyle很有可能都对下面这句语句提出了警告。但事实上这是一个性能优化上的小技巧
*
* 如果把一句话拆成两句来写
* hasNext=rs.next();
* if(hasNext){
* 这样可以消除警告。但是从编译后的代码来看。两句话的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: putfield #62; //Field hasNext:Z
* 43: aload_0
* 44: getfield #62; //Field hasNext:Z
* 现在这种写法的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: dup_x1
* 41: putfield #62; //Field hasNext:Z
* 在栈内做一次 dup的开销要小于getfield的开销。(前者是栈访问后者是堆访问)
*
* 各种代码检查工具是针对写不好代码的人起到查漏补遗的作用的,但是不能因此在有能力控制代码逻辑正确性的前提下,不去追求性能更好的写法。
* 因此,此处就是要这么写,不管各种代码检查工具如何警告,不管省下的性能多么微不足道,我坚持用性能最优的写法。
*/
if (hasNext = rs.next()) { //Please Ignore the warning of eclipse.
boolean noContext=context==null || transformer.hasStrategy(PopulateStrategy.COLUMN_TO_ARRAY);
if(!noContext){ //为了尽可能自动,当context中参与的表只有一个时,默认认为还是Column_To_Array模式的
noContext=context.getReference().size()<2;
}
if (noContext && transformer.getMapper().isEmpty()) {
initSimpleArrayPopulator();
}else{
initColumnAccessor(rs.getColumns(),context==null?null:context.getReference(),transformer);
}
}
}
private void initSimpleArrayPopulator() {
populators=new ArrayList<Mapper<?>>(1);
ColumnMeta meta=rs.getColumns();
this.size=meta.length();
ResultSetAccessor[] accessors=new ResultSetAccessor[size];
for(int i=0;i<size;i++){
accessors[i]=ColumnMappings.getAccessor(componentType, null, meta.getN(i), false);
}
populators.add(new RawArrayMapper(accessors));
}
private void initColumnAccessor(ColumnMeta columnNames,List<ISelectItemProvider> queries,Transformer transformer) {
if(transformer.getMapper().isEmpty()){
populators=new ArrayList<Mapper<?>>();
int i=0;
for (ISelectItemProvider prov : queries) {
Query<?> q = prov.getTableDef();
String schema = prov.getSchema();
Mapper<? extends IQueryableEntity> mapper=Mappers.toArrayElement(i++, q.getMeta(),schema);
mapper.prepare(columnNames.nameIndex);
populators.add(mapper);
}
this.size = populators.size();
}else{
this.populators=transformer.getMapper();
this.size=transformer.getMaxMapperIndex()+1;
}
columnNames.initSchemas(transformer);
}
public boolean hasNext() {
return hasNext;
}
public Object[] next() {
if (!hasNext)
throw new NoSuchElementException();
try {
Object[] map = (Object[]) Array.newInstance(componentType, size);
ArrayWrapper aw=new ArrayWrapper(map);
for (Mapper<?> prov : populators) {
prov.process(aw, rs);
}
return map;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
hasNext = rs.next();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
private boolean hasNext;
}
final static class NormalRsIterator<T> implements Iterator<T> {
private IResultSet rs;
private ITableMetadata meta;
private Class<T> retClz;
private String[] schemas;
private ISelectItemProvider[] subObjects;
private List<ObjectPopulator> directPopulator;
private List<IPopulator> extendPopulator;
private AliasProvider defaultField;
private ColumnMeta columnNames;
private Session session;
@SuppressWarnings("all")
public NormalRsIterator(IResultSet rs, EntityMappingProvider context, Transformer transformers, Session session) {
Class<T> resultObj=(Class<T>) transformers.getResultClazz();
this.rs = rs;
this.retClz = resultObj;
this.meta = transformers.getResultMeta();
this.session=session;
/*
* 如果把一句话拆成两句来写
* hasNext=rs.next();
* if(hasNext){
* 这样可以消除警告。但是从编译后的代码来看。编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: putfield #62; //Field hasNext:Z
* 43: aload_0
* 44: getfield #62; //Field hasNext:Z
* 现在这种写法的编译结果为——
* 35: invokeinterface #57, 1; //InterfaceMethod jef/database/wrapper/IResultSet.next:()Z
* 40: dup_x1
* 41: putfield #62; //Field hasNext:Z
* 在栈内做一次 dup的开销要小于getfield的开销。(前者是栈访问后者是堆访问)
*/
if (hasNext = rs.next()) {
columnNames = rs.getColumns();
subObjects = null;
defaultField = null;
if (context != null) {
Entry<String[], ISelectItemProvider[]> desc = context.getPopulationDesc();
schemas = desc.getKey();
subObjects = desc.getValue();
defaultField=context.isMultiTable()?AliasProvider.DEFAULT:null;
} else {
schemas = new String[] { "" };// 当引用查询时的基础表Schema
}
if (meta == null && IQueryableEntity.class.isAssignableFrom(resultObj)) {
this.meta = MetaHolder.getMeta(resultObj.asSubclass(IQueryableEntity.class));
}
initColumnAccessor(transformers);
}
}
private void initColumnAccessor(Transformer transformers) {
boolean skipAnnataion = transformers.hasStrategy(PopulateStrategy.SKIP_COLUMN_ANNOTATION);
BeanAccessor ba = FastBeanWrapperImpl.getAccessorFor(retClz);
directPopulator = new ArrayList<ObjectPopulator>(schemas.length);
for (String schema : schemas) {
if(!transformers.hasIgnoreSchema(schema)){
directPopulator.add(fill(schema, defaultField, rs, columnNames, meta, skipAnnataion));
}
}
if (subObjects != null) {// 主对象拼装完毕后,拼装JOIN对象中指出的其他引用字段
extendPopulator = new ArrayList<IPopulator>(subObjects.length);
for (ISelectItemProvider rp : subObjects) {
extendPopulator.add(fillReference(columnNames, ba, rs, rp, rs.getProfile()));
}
}
if(!transformers.getMapper().isEmpty()){
if(extendPopulator==null){
extendPopulator = new ArrayList<IPopulator>(transformers.getMapper());
}else{
extendPopulator.addAll(transformers.getMapper());
}
}
}
public boolean hasNext() {
return hasNext;
}
@SuppressWarnings("unchecked")
public T next() {
if (!hasNext)
throw new NoSuchElementException();
try {
T retObj;
BeanWrapper wrapper;
if(meta==null){
retObj=UnsafeUtils.newInstance(retClz);
wrapper = BeanWrapper.wrap(retObj, BeanWrapper.FAST);
}else{
IQueryableEntity e=meta.newInstance();
e.stopUpdate();
retObj=(T) e;
wrapper = new FastBeanWrapperImpl(retObj,meta.getContainerAccessor());
}
for (ObjectPopulator op : directPopulator) {
op.process(wrapper, rs);
}
if (extendPopulator != null) {// 主对象拼装完毕后,拼装JOIN对象中指出的其他引用字段
for (IPopulator rp : extendPopulator) {
rp.process(wrapper, rs);
}
}
endPopulate(retObj);
return retObj;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
hasNext = rs.next();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
private boolean hasNext;
private IPopulator fillReference(ColumnMeta columns, BeanAccessor ba, IResultSet rs, ISelectItemProvider rp, DatabaseDialect profile) {
List<IPopulator> result=new ArrayList<IPopulator>();
if (rp.getReferenceObj() != null) {
IReferenceAllTable allcolumns = rp.getReferenceObj();
String name = allcolumns.getName();
ITableMetadata targetType = allcolumns.getFullModeTargetType();
BeanAccessor targetAccessor=(name==null?ba:FastBeanWrapperImpl.getAccessorFor(targetType.getContainerType()));
ObjectPopulator op1;
List<LazyLoadTask> tasks = new ArrayList<LazyLoadTask>();
if(targetType.getType()!=EntityType.NATIVE || targetAccessor.getType()==targetType.getThisType()){
op1=fill(rp.getSchema(), allcolumns, rs, columns, targetType, false);
if (allcolumns.isLazyLob()) {
for (Field field : targetType.getLobFieldNames()) {
ColumnMapping mType=targetType.getColumnDef(field);
LobLazyLoadTask task = new LobLazyLoadTask(mType, rs.getProfile(), targetType.getTableName(true));
tasks.add(task);
}
}
}else{
op1=fillPlain(targetAccessor, false, columns);
}
if(rp.getStaticRef()!=null){//级联对象的级联任务作为延迟加载
Map<Reference, List<AbstractRefField>> map =targetType.getRefFieldsByRef();
for (Map.Entry<Reference, List<AbstractRefField>> entry : map.entrySet()) {
LazyLoadTask task=DebugUtil.getLazyTaskMarker(entry, rs.getFilters(), session);
tasks.add(task);
}
}
if(!tasks.isEmpty()){
LazyLoadProcessor lz = new LazyLoadProcessor(tasks, session);
op1.setProcessor(lz);
}
if (name == null) {
result.add(op1);
} else {
result.add(new NestedObjectPopulator(name, op1));
}
}
for (IReferenceColumn field : rp.getReferenceCol()) {
//TODO 修复关于引用单字段的LOB的延迟加载问题。
result.add(new FieldPopulator(field,profile,rp.getSchema(),columns,ba));
}
if(result.size()==1)return result.get(0);
return new MultiplePopulator(result.toArray(new IPopulator[result.size()]));
}
}
private static void endPopulate(Object retObj) {
if (retObj instanceof IQueryableEntity) {
((IQueryableEntity) retObj).startUpdate();
}
}
/*
* @ba拼装java模型
* schema schema
* fullRef 引用
* columns 数据库列
* meta
*/
private static ObjectPopulator fill(String schema, AliasProvider fullRef, IResultSet rs, ColumnMeta columns, ITableMetadata meta, boolean skipColumn) {
Map<String, ColumnDescription> data = new HashMap<String, ColumnDescription>();
DatabaseDialect profile = rs.getProfile();
// 这里要按照列名来拼装,不是默认全拼装
for (ColumnMapping ft : meta.getColumns()) {
String columnName;
Field f = ft.field();
if (fullRef == null) {
columnName = skipColumn ? f.name().toUpperCase() : ft.upperColumnName();
} else {
columnName = fullRef.getResultAliasOf(ft, schema);
}
if (columnName != null) {
ColumnDescription columnDesc = columns.getByUpperName(columnName);
if (columnDesc == null) {
// if (schema == "")
// System.err.println("Warnning: populating object " + meta.getThisType() + " error," + schema + ":" + columnName + " not found in the selected columns");
}else{
ResultSetAccessor accessor = ColumnMappings.getAccessor(ft.getFieldAccessor().getType(), ft, columnDesc, false);
columnDesc.setAccessor(accessor);
data.put(f.name(), columnDesc);
}
}
}
ObjectPopulator op = new ObjectPopulator(meta, data);
if (schema == "" || schema.length() < 2) {
if (profile.has(Feature.SELECT_ROW_NUM)) {
ColumnDescription columnDesc = columns.getByUpperName("ROWID_");
if (columnDesc != null) {
op.bindRowidForColumn = columnDesc.getN();
}
}
}
return op;
}
@SuppressWarnings({ "unchecked"})
private static <A extends Annotation> A getAnnotation(BeanAccessor ba, String fieldName, Class<A> class1) {
Map<Class<?>, Annotation> map = ba.getAnnotationOnField(fieldName);
return map == null ? null : (A) map.get(class1);
}
private static ObjectPopulator fillPlain(BeanAccessor ba,boolean skipAnnataion,ColumnMeta columnMeta){
Map<String, ColumnDescription> map = new HashMap<String, ColumnDescription>();
for (String fieldName : ba.getPropertyNames()) {
javax.persistence.Column columnAnnotation = skipAnnataion ? null : getAnnotation(ba, fieldName, javax.persistence.Column.class);
String columnName;
if (columnAnnotation != null && columnAnnotation.name().length()!=0) {
columnName = columnAnnotation.name();
} else {
columnName = fieldName;
}
ColumnDescription c = columnMeta.getByUpperName(columnName.toUpperCase());//findBySimpleName(columnName)
if (c != null) {
c.setAccessor(ColumnMappings.getAccessor(ba.getPropertyType(fieldName), null, c, true));
map.put(fieldName, c);
}
}
return new ObjectPopulator(null, map);
}
}