Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.cassite.daf4j.jpa.JPQLEntityDataParser Maven / Gradle / Ivy
Go to download
A library provides implementation of DAF4J DataAccess using JPA
package net.cassite.daf4j.jpa;
import net.cassite.daf4j.DataUtils;
import net.cassite.daf4j.IData;
import net.cassite.daf4j.PreResult;
import net.cassite.daf4j.QueryParameterTypes;
import net.cassite.daf4j.ds.DSUtils;
import net.cassite.daf4j.ds.EntityDataParser;
import net.cassite.daf4j.ds.ParserPacket;
import net.cassite.daf4j.types.*;
import net.cassite.daf4j.util.Location;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.*;
/**
* 将实体和IData实例转化为JPQL
*/
public class JPQLEntityDataParser implements EntityDataParser {
@Override
public String parseData(JPQLContext jpqlContext, IData> iData) {
return parseEntity(jpqlContext, iData.getEntity()) + "." + DataUtils.findFieldNameByIData(iData);
}
@Override
public String parseEntity(JPQLContext jpqlContext, Object o) {
Location loc = findEntity(o, jpqlContext);
return jpqlContext.aliasMap.get(loc);
}
@Override
public String parsePlain(JPQLContext jpqlContext, Object o) {
return "?" + jpqlContext.constantMap.add(o);
}
@Override
public String parseQuery(JPQLContext jpqlContext, PreResult> preResult, ParserPacket parserPacket) throws Exception {
JPQLContext cont = jpqlContext.copyForSubQuery(preResult.entity, preResult.parameter == null || !preResult.parameter.parameters.containsKey(QueryParameterTypes.distinct));
String res = DSUtils.listGenerationProcess(cont, preResult.whereClause, preResult.parameter, parserPacket).generalJPQL.toString();
jpqlContext.aliasMap.setAliasCount(cont.aliasMap.getAliasCount());
return res;
}
/**
* 获取实体的调用位置
* 使用广度优先搜索
* 找到时自动加入AliasMap
*
* @param entity 从该实体开始寻找
* @param toFind 要寻找的实体
* @param list 已经经过的路径
* @param args 上下文
* @param alreadySearched 已经寻找过的实体
* @return 找到的实体位置(Location对象), 没找到则返回null
*/
private static Location findEntity(Object entity, Object toFind, List list, JPQLContext args, Set alreadySearched, List> locationsMightBeJoined) {
Map objectStringMap = new LinkedHashMap();
try {
for (Field f : entity.getClass().getFields()) {
// is IData
if (IData.class.isAssignableFrom(f.getType())) {
// get 1st generic type
Class> cls;
try {
cls = ((Class>) ((ParameterizedType) f.getGenericType()).getActualTypeArguments()[0]);
} catch (ClassCastException e) {
// not generic type , maybe one of XTypes
Class> type = f.getType();
if (XInt.class.isAssignableFrom(type)) {
cls = Integer.class;
} else if (XLong.class.isAssignableFrom(type)) {
cls = Long.class;
} else if (XDouble.class.isAssignableFrom(type)) {
cls = Double.class;
} else if (XDate.class.isAssignableFrom(type)) {
cls = Date.class;
} else if (XString.class.isAssignableFrom(type)) {
cls = String.class;
} else if (XBool.class.isAssignableFrom(type)) {
cls = Boolean.class;
} else {
throw e;
}
}
// is not java. / javax.
if (!cls.getName().startsWith("java.") && !cls.getName().startsWith("javax.")) {
IData> data = (IData>) f.get(entity);
Object obj = data.get();
if (obj == null) continue;
if (obj instanceof Iterable) {
// is aggregate
Iterator> it = ((Iterable>) obj).iterator();
if (it.hasNext()) {
Object o = it.next();
List tmp = new ArrayList(list);
tmp.add(f.getName());
locationsMightBeJoined.add(new ArrayList(tmp));
if (o == toFind) {
list.add(f.getName());
if (toFind != args.entity) {
for (List locationList : locationsMightBeJoined) {
Location loc = DataUtils.generateLocationAndFillMap(locationList, args.aliasMap);
if (!args.toJoin.containsKey(loc)) {
args.toJoin.put(loc, args.aliasMap.get(loc));
}
}
}
return DataUtils.generateLocationAndFillMap(list, args.aliasMap);
} else {
if (!alreadySearched.contains(o)) {
alreadySearched.add(o);
objectStringMap.put(o, f.getName());
}
}
}
} else {
List tmp = new ArrayList(list);
tmp.add(f.getName());
locationsMightBeJoined.add(new ArrayList(tmp));
// is plain object
if (obj == toFind) {
list.add(f.getName());
if (toFind != args.entity) {
for (List locationList : locationsMightBeJoined) {
Location loc = DataUtils.generateLocationAndFillMap(locationList, args.aliasMap);
if (!args.toJoin.containsKey(loc)) {
args.toJoin.put(loc, args.aliasMap.get(loc));
}
}
}
return DataUtils.generateLocationAndFillMap(list, args.aliasMap);
} else {
if (!alreadySearched.contains(obj)) {
alreadySearched.add(obj);
objectStringMap.put(obj, f.getName());
}
}
}
}
}
}
// not found
for (Object obj : objectStringMap.keySet()) {
List nextList = new ArrayList(list);
nextList.add(objectStringMap.get(obj));
List> nextLocationsMightBeJoined = new ArrayList>(locationsMightBeJoined);
Location location = findEntity(obj, toFind, nextList, args, alreadySearched, nextLocationsMightBeJoined);
if (null != location) {
// found
return location;
}
}
return null;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 获取Entity位置,若没有找到则抛出异常
*
* @param toFind 要寻找的实体
* @param args 上下文
* @return 实体的位置(Location对象)
*/
static Location findEntity(Object toFind, JPQLContext args) {
if (toFind == args.entity) {
return new Location(null);
} else {
Location l = findEntity(args.entity, toFind, new ArrayList(), args, new HashSet(), new ArrayList>());
if (l == null) {
throw new IllegalArgumentException("Cannot find location of " + toFind);
}
return l;
}
}
}