Skip to content

Commit

Permalink
实现ORM模型层的compute prop
Browse files Browse the repository at this point in the history
  • Loading branch information
entropy-cloud committed Dec 30, 2023
1 parent cd8813f commit 8883293
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,24 @@
*/
package io.nop.orm.model;

import io.nop.core.lang.eval.IEvalAction;
import io.nop.core.type.IGenericType;

import java.util.List;
import java.util.Map;

public interface IComputePropModel extends IEntityPropModel {
List<? extends IComputedArgModel> getArgs();

IEvalAction getGetter();

IEvalAction getSetter();

IGenericType getType();

Object getValue(Object entity);

void setValue(Object entity, Object value);

Object computeValue(Object entity, Map<String, Object> args);
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ default IEntityPropModel getDisplayPropModel() {

IEntityPropModel getProp(String propName, boolean ignoreUnknown);

default IEntityPropModel requireProp(String propName) {
return getProp(propName, false);
}

Map<String, IEntityPropModel> getAllProps();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,24 @@
*/
package io.nop.orm.model;

import io.nop.api.core.exceptions.NopException;
import io.nop.commons.type.StdDataType;
import io.nop.core.lang.eval.IEvalAction;
import io.nop.core.lang.eval.IEvalScope;
import io.nop.core.reflect.bean.BeanTool;
import io.nop.core.type.IGenericType;
import io.nop.orm.model._gen._OrmComputePropModel;
import io.nop.xlang.api.XLang;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import static io.nop.orm.model.OrmModelErrors.ARG_ENTITY_NAME;
import static io.nop.orm.model.OrmModelErrors.ARG_PROP_NAME;
import static io.nop.orm.model.OrmModelErrors.ERR_ORM_COMPUTE_PROP_NO_GETTER;
import static io.nop.orm.model.OrmModelErrors.ERR_ORM_COMPUTE_PROP_NO_SETTER;
import static io.nop.orm.model.OrmModelErrors.ERR_ORM_UNKNOWN_COMPUTE_PROP_ARG;

public class OrmComputePropModel extends _OrmComputePropModel implements IComputePropModel {
private OrmEntityModel ownerEntityModel;
Expand All @@ -20,6 +33,61 @@ public OrmComputePropModel() {

}

@Override
public Object getValue(Object entity) {
IEvalAction getter = getGetter();
if (getter == null)
throw new NopException(ERR_ORM_COMPUTE_PROP_NO_GETTER)
.param(ARG_ENTITY_NAME, this.getOwnerEntityModel().getName())
.param(ARG_PROP_NAME, getName());

IEvalScope scope = XLang.newEvalScope();
scope.setLocalValue(OrmModelConstants.VAR_ENTITY, entity);
return getter.invoke(scope);
}

@Override
public void setValue(Object entity, Object value) {
IEvalAction setter = getSetter();
if (setter == null)
throw new NopException(ERR_ORM_COMPUTE_PROP_NO_SETTER)
.param(ARG_ENTITY_NAME, this.getOwnerEntityModel().getName())
.param(ARG_PROP_NAME, getName());

IEvalScope scope = XLang.newEvalScope();
scope.setLocalValue(OrmModelConstants.VAR_ENTITY, entity);
scope.setLocalValue(OrmModelConstants.VAR_VALUE, value);
setter.invoke(scope);
}

@Override
public Object computeValue(Object entity, Map<String, Object> args) {
IEvalAction getter = getGetter();
if (getter == null)
throw new NopException(ERR_ORM_COMPUTE_PROP_NO_GETTER)
.param(ARG_ENTITY_NAME, this.getOwnerEntityModel().getName())
.param(ARG_PROP_NAME, getName());

IEvalScope scope = XLang.newEvalScope();
scope.setLocalValue(OrmModelConstants.VAR_ENTITY, entity);
if (args == null)
args = Collections.emptyMap();

for (OrmComputeArgModel argModel : getArgs()) {
Object value = args.get(argModel.getName());
value = BeanTool.castBeanToType(value, argModel.getType());
scope.setLocalValue(argModel.getName(), value);
}

for (String argName : args.keySet()) {
if (getArg(argName) == null)
throw new NopException(ERR_ORM_UNKNOWN_COMPUTE_PROP_ARG)
.param(ARG_ENTITY_NAME, this.getOwnerEntityModel().getName())
.param(ARG_PROP_NAME, getName());
}
return getter.invoke(scope);
}

@Override
public String getJavaTypeName() {
IGenericType type = getType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,13 @@ public interface OrmModelConstants {

int MAX_PROP_ID = 2000;
String EXT_PROP_MIN_PROP_ID = "ext:minPropId";

String EXT_BASE_PACKAGE_NAME = "ext:basePackageName";
String EXT_MAVEN_GROUP_ID = "ext:mavenGroupId";

String EXT_MAVEN_ARTIFACT_ID = "ext:mavenArtifactId";

String VAR_ENTITY = "entity";

String VAR_VALUE = "value";
}
15 changes: 15 additions & 0 deletions nop-orm-model/src/main/java/io/nop/orm/model/OrmModelErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public interface OrmModelErrors {
String ARG_COLLECTION_NAME = "collectionName";
String ARG_TENANT_ID = "tenantId";

String ARG_ARG_NAME = "argName";

ErrorCode ERR_ORM_MODEL_DUPLICATE_PROP_ID = define("nop.err.orm.model.duplicate-prop-id",
"对象模型[{entityName}]的列[{propName}]和[{otherPropName}]的编号都是[{propId}]", ARG_ENTITY_NAME, ARG_PROP_NAME,
ARG_OTHER_PROP_NAME, ARG_PROP_ID);
Expand Down Expand Up @@ -169,4 +171,17 @@ public interface OrmModelErrors {
ErrorCode ERR_ORM_NO_COL_WITH_TAG =
define("nop.err.orm.model.no-col-with-tag", "实体[{entityName}]中没有定义具有标签[{tag}]的列",
ARG_ENTITY_NAME, ARG_TAG);

ErrorCode ERR_ORM_COMPUTE_PROP_NO_GETTER =
define("nop.err.orm.model.compute-prop-no-getter",
"实体[{entityName}]的计算属性[{propName}]没有定义getter,不支持获取值", ARG_ENTITY_NAME, ARG_PROP_NAME);

ErrorCode ERR_ORM_COMPUTE_PROP_NO_SETTER =
define("nop.err.orm.model.compute-prop-no-setter",
"实体[{entityName}]的计算属性[{propName}]没有定义setter,不支持设置值", ARG_ENTITY_NAME, ARG_PROP_NAME);

ErrorCode ERR_ORM_UNKNOWN_COMPUTE_PROP_ARG = define("nop.err.orm.unknown-compute-prop-arg",
"对象[{entityName}]的计算属性[{propName}]不支持参数[{argName}]", ARG_ENTITY_NAME, ARG_PROP_NAME, ARG_ARG_NAME);


}
2 changes: 2 additions & 0 deletions nop-orm/src/main/java/io/nop/orm/OrmErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public interface OrmErrors {
String ARG_ENTITY_ID = "entityId";
String ARG_PROP_NAME = "propName";

String ARG_ARG_NAME = "argName";

String ARG_ELM_OWNER = "elmOwner";

String ARG_TAG = "tag";
Expand Down
10 changes: 9 additions & 1 deletion nop-orm/src/main/java/io/nop/orm/session/OrmSessionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
import io.nop.orm.loader.IOrmBatchLoadQueueImplementor;
import io.nop.orm.loader.IQueryExecutor;
import io.nop.orm.loader.OrmBatchLoadQueueImpl;
import io.nop.orm.model.IComputePropModel;
import io.nop.orm.model.IEntityJoinConditionModel;
import io.nop.orm.model.IEntityModel;
import io.nop.orm.model.IEntityPropModel;
import io.nop.orm.model.IEntityRelationModel;
import io.nop.orm.persister.IBatchActionQueue;
import io.nop.orm.persister.ICollectionPersister;
Expand Down Expand Up @@ -1082,7 +1084,13 @@ public Object initEntityId(IOrmEntity entity) {

@Override
public Object internalCompute(IOrmEntity entity, String propName, Map<String, Object> args) {
throw newError(ERR_ORM_NOT_SUPPORT_COMPUTE, entity).param(ARG_PROP_NAME, propName);
IEntityModel entityModel = entity.orm_entityModel();
IEntityPropModel propModel = entityModel.getProp(propName, false);
if (!(propModel instanceof IComputePropModel))
throw newError(ERR_ORM_NOT_SUPPORT_COMPUTE, entity).param(ARG_PROP_NAME, propName);

IComputePropModel computeModel = (IComputePropModel) propModel;
return computeModel.computeValue(entity, args);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.nop.orm.IOrmEntitySet;
import io.nop.orm.IOrmObject;
import io.nop.orm.model.IColumnModel;
import io.nop.orm.model.IComputePropModel;
import io.nop.orm.model.IEntityComponentModel;
import io.nop.orm.model.IEntityJoinConditionModel;
import io.nop.orm.model.IEntityModel;
Expand Down Expand Up @@ -204,6 +205,9 @@ public Object prop_get(String propName) {
component.bindToEntity(this, compModel.getColumnPropIdMap());
}
return component;
} else if (propModel.isComputeModel()) {
IComputePropModel computeModel = (IComputePropModel) propModel;
return computeModel.getValue(this);
} else {
return defaultGetProp(propName);
}
Expand All @@ -220,6 +224,9 @@ public void prop_set(String propName, Object value) {
throw newError(ERR_ORM_ENTITY_PROP_NOT_ALLOW_SET).param(ARG_PROP_NAME, propName);
} else if (propModel.isAliasModel()) {
internalSetAliasValue(propModel.getAliasPropPath(), value);
} else if (propModel.isComputeModel()) {
IComputePropModel computeModel = (IComputePropModel) propModel;
computeModel.setValue(this, value);
} else {
defaultSetProp(propName, value);
}
Expand Down
23 changes: 23 additions & 0 deletions nop-orm/src/test/java/io/nop/orm/impl/TestOrmComputeProp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.nop.orm.impl;

import io.nop.app.SimsClass;
import io.nop.dao.api.IEntityDao;
import io.nop.orm.AbstractOrmTestCase;
import org.junit.jupiter.api.Test;

import static org.junit.Assert.assertEquals;

public class TestOrmComputeProp extends AbstractOrmTestCase {
@Test
public void testComputeProp() {
IEntityDao<SimsClass> dao = daoProvider().daoFor(SimsClass.class);

orm().runInSession(() -> {
SimsClass entity = dao.getEntityById("11");
assertEquals("CollegeAEx", entity.prop_get("collegeNameEx"));

entity.prop_set("collegeNameEx", "c2Ex");
assertEquals("c2", entity.getCollegeName());
});
}
}
12 changes: 12 additions & 0 deletions nop-orm/src/test/resources/_vfs/nop/test/orm/app.orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
<aliases>
<alias name="collegeName" propPath="simsCollege.collegeName" type="String"/>
</aliases>

<computes>
<compute name="collegeNameEx" type="String">
<getter>
return entity.collegeName + 'Ex';
</getter>

<setter>
entity.collegeName = value.$removeTail('Ex')
</setter>
</compute>
</computes>
<relations>
<to-one name="simsCollege" refEntityName="io.nop.app.SimsCollege" refPropName="simsClasses">
<join>
Expand Down

0 comments on commit 8883293

Please sign in to comment.