Skip to content

Commit

Permalink
xbiz模型中定义的loader增加batchLoader支持
Browse files Browse the repository at this point in the history
  • Loading branch information
entropy-cloud committed Aug 27, 2024
1 parent 4af0e48 commit 7c96713
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import io.nop.biz.model.BizReturnModel;
import io.nop.core.context.action.IServiceAction;
import io.nop.core.lang.eval.IEvalAction;
import io.nop.core.lang.eval.IEvalScope;
import io.nop.core.type.IGenericType;
import io.nop.graphql.core.GraphQLConstants;
import io.nop.graphql.core.IDataFetcher;
import io.nop.graphql.core.IDataFetchingEnvironment;
import io.nop.graphql.core.IGraphQLExecutionContext;
import io.nop.graphql.core.ast.GraphQLArgumentDefinition;
import io.nop.graphql.core.ast.GraphQLDefinition;
import io.nop.graphql.core.ast.GraphQLFieldDefinition;
Expand All @@ -29,6 +31,7 @@
import io.nop.graphql.core.ast.GraphQLNamedType;
import io.nop.graphql.core.ast.GraphQLObjectDefinition;
import io.nop.graphql.core.ast.GraphQLType;
import io.nop.graphql.core.fetcher.BeanMethodBatchFetcher;
import io.nop.graphql.core.fetcher.ServiceActionFetcher;
import io.nop.graphql.core.reflection.ArgBuilders;
import io.nop.graphql.core.reflection.EvalGraphQLArgsNormalizer;
Expand All @@ -45,12 +48,17 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

import static io.nop.graphql.core.GraphQLErrors.ARG_ACTION_NAME;
import static io.nop.graphql.core.GraphQLErrors.ARG_ARG_NAME;
import static io.nop.graphql.core.GraphQLErrors.ARG_METHOD_NAME;
import static io.nop.graphql.core.GraphQLErrors.ARG_OBJ_NAME;
import static io.nop.graphql.core.GraphQLErrors.ARG_TYPE;
import static io.nop.graphql.core.GraphQLErrors.ERR_GRAPHQL_ACTION_ARG_TYPE_NOT_OBJ_TYPE;
import static io.nop.graphql.core.GraphQLErrors.ERR_GRAPHQL_BATCH_LOAD_METHOD_MUST_RETURN_LIST;

public class BizModelToGraphQLDefinition {
public static final BizModelToGraphQLDefinition INSTANCE = new BizModelToGraphQLDefinition();
Expand Down Expand Up @@ -104,7 +112,7 @@ public GraphQLFieldDefinition toBuilder(String thisObjName, BizLoaderModel loade
if (args != null)
field.setArguments(args);

IDataFetcher fetcher = buildFetcher(loaderModel, typeRegistry);
IDataFetcher fetcher = buildFetcher(thisObjName, loaderModel, typeRegistry);
field.setFetcher(fetcher);
field.setAutoCreate(loaderModel.isAutoCreateField());
return field;
Expand All @@ -125,20 +133,47 @@ public IServiceAction buildAction(BizActionModel actionModel, IServiceActionArgB
return new EvalServiceAction(source, argBuilders);
}

IDataFetcher buildFetcher(BizLoaderModel loaderModel, TypeRegistry typeRegistry) {
IDataFetcher buildFetcher(String bizObjName, BizLoaderModel loaderModel, TypeRegistry typeRegistry) {
IEvalAction source = loaderModel.getSource();
if (source == null)
source = ctx -> null;

Map<String, Function<IDataFetchingEnvironment, Object>> argBuilders = new LinkedHashMap<>();
BizActionArgModel contextSourceArg = null;
for (BizActionArgModel arg : loaderModel.getArgs()) {
if (arg.getKind() == BizActionArgKind.ContextSource)
contextSourceArg = arg;

Function<IDataFetchingEnvironment, Object> argBuilder = getFetcherArg(arg.getKind(), arg.getName(),
arg.getType());
argBuilders.put(arg.getName(), argBuilder);
}

if (contextSourceArg != null && contextSourceArg.getType() != null && contextSourceArg.getType().isCollectionLike()) {
// 如果是集合类型的参数,则表示这是一个BatchLoader
if (!loaderModel.isReturnList()) {
throw new NopException(ERR_GRAPHQL_BATCH_LOAD_METHOD_MUST_RETURN_LIST).source(loaderModel)
.param(ARG_OBJ_NAME, bizObjName).param(ARG_METHOD_NAME, loaderModel.getName());
}
int sourceIndex = loaderModel.getArgs().indexOf(contextSourceArg);
String loaderName = bizObjName + "@" + loaderModel.getName();

List<Function<IDataFetchingEnvironment, Object>> argsList = loaderModel.getArgs()
.stream().map(arg -> argBuilders.get(arg.getName()))
.collect(Collectors.toList());

return new BeanMethodBatchFetcher(loaderName, newFetcher(source, loaderModel), argsList, sourceIndex);
}
return new EvalActionDataFetcher(source, argBuilders);
}

private static BiFunction<Object[], IGraphQLExecutionContext, Object> newFetcher(IEvalAction source, BizLoaderModel loaderModel) {
return (args, ctx) -> {
IEvalScope scope = loaderModel.newEvalScope(args, ctx.getEvalScope());
return source.invoke(scope);
};
}

IServiceActionArgBuilder getArgBuilder(BizActionArgKind kind, String name, IGenericType type) {
if (kind == BizActionArgKind.RequestBean) {
return ArgBuilders.getActionRequest(type);
Expand Down
26 changes: 26 additions & 0 deletions nop-biz/src/main/java/io/nop/biz/model/BizLoaderModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,35 @@
package io.nop.biz.model;

import io.nop.biz.model._gen._BizLoaderModel;
import io.nop.core.context.IEvalContext;
import io.nop.core.lang.eval.IEvalScope;
import io.nop.core.type.IGenericType;

public class BizLoaderModel extends _BizLoaderModel {
public BizLoaderModel() {

}

public IEvalScope newEvalScope(Object[] args, IEvalContext ctx) {
IEvalScope scope = ctx.getEvalScope().newChildScope();
for (int i = 0, n = args.length; i < n; i++) {
String name = getArgs().get(i).getName();
scope.setLocalValue(null, name, args[i]);
}
return scope;
}

public IGenericType getReturnType() {
BizReturnModel returnModel = getReturn();
if (returnModel == null)
return null;
return returnModel.getType();
}

public boolean isReturnList() {
IGenericType returnType = getReturnType();
if (returnType == null)
return false;
return returnType.isListLike();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,8 @@
/nop/wf/pages/NopWfDefinition/NopWfDefinition.lib.xjs
/nop/wf/pages/NopWfDefinition/NopWfDefinition.view.xml
/nop/wf/pages/NopWfDefinition/_gen/_NopWfDefinition.view.xml
/nop/wf/pages/NopWfDefinition/designer.page.yaml
/nop/wf/pages/NopWfDefinition/flow.lib.js
/nop/wf/pages/NopWfDefinition/main.page.yaml
/nop/wf/pages/NopWfDefinition/ofd-models.lib.css
/nop/wf/pages/NopWfDefinition/ofd-models.lib.js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,27 @@
import org.dataloader.DataLoaderFactory;

import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

/**
* 第一个参数对应于source对象的列表
*/
public class BeanMethodBatchFetcher implements IDataFetcher {
private final String loaderName;
private final Object bean;
private final IFunctionModel function;
private final BiFunction<Object[], IGraphQLExecutionContext, Object> realFetcher;
private final List<Function<IDataFetchingEnvironment, Object>> argBuilders;
private final int sourceIndex;

public BeanMethodBatchFetcher(String loaderName, Object bean, IFunctionModel function,
List<Function<IDataFetchingEnvironment, Object>> argBuilders, int sourceIndex) {
this(loaderName, (args, context) -> function.invoke(bean, args, context.getEvalScope()), argBuilders, sourceIndex);
}

public BeanMethodBatchFetcher(String loaderName, BiFunction<Object[], IGraphQLExecutionContext, Object> realFetcher,
List<Function<IDataFetchingEnvironment, Object>> argBuilders, int sourceIndex) {
this.loaderName = loaderName;
this.bean = bean;
this.function = function;
this.realFetcher = realFetcher;
this.argBuilders = argBuilders;
this.sourceIndex = Guard.checkPositionIndex(sourceIndex, argBuilders.size(), "sourceIndex");
}
Expand All @@ -52,7 +56,7 @@ public Object get(IDataFetchingEnvironment env) {
}
BatchLoader<Object, Object> batchLoader = keys -> {
args[sourceIndex] = keys;
return FutureHelper.futureCall(() -> function.invoke(bean, args, context.getEvalScope()));
return FutureHelper.futureCall(() -> realFetcher.apply(args, context));
};
loader = DataLoaderFactory.newDataLoader(batchLoader);
context.registerDataLoader(loaderName, loader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
<schema stdDomain="xml-name"/>
</field>

<field name="ext:proxyModuleName" displayName="proxyModuleName" mandatory="true">
<schema stdDomain="xml-name"/>
</field>

<field name="ext:mavenGroupId" displayName="maven.groupId" mandatory="true">
<schema stdDomain="string"/>
</field>
Expand Down

0 comments on commit 7c96713

Please sign in to comment.