gpt4 book ai didi

java - 如何用三向转换覆盖 Tapestry 的双向 boolean 转换?

转载 作者:行者123 更新时间:2023-11-30 09:11:55 28 4
gpt4 key购买 nike

考虑这种情况。

您有一个无法以任何方式更改或扩展的类。

public class Foo {
...
private Boolean bar;
...
}

您需要通过 BeanEditor 编辑该类的字段, 但该类背后的逻辑允许并使用 Boolean 的事实可以说,可以有 3 种状态:nulltruefalse

但是,Tapestry 会给你一个只有 2 个选项的复选框,truefalse

所以,网上的人建议你转换你的Boolean将属性键入 BooleanExtendedEnum可以表示三向逻辑的类型属性。

public enum BooleanExtendedEnum {
UNDEFINED(null),
TRUE(Boolean.TRUE),
FALSE(Boolean.FALSE);

private Boolean booleanValue;

private static Map<Boolean, BooleanExtendedEnum> booleanToExtendedMap = new HashMap<Boolean, BooleanExtendedEnum>();


static {
for (BooleanExtendedEnum be : BooleanExtendedEnum.values()) {
booleanToExtendedMap.put(be.booleanValue, be);
}
}

private BooleanExtendedEnum(Boolean booleanValue) {
this.booleanValue = booleanValue;
}

public Boolean getBooleanValue() {
return booleanValue;
}

public static BooleanExtendedEnum getBooleanExtendedValue(Boolean booleanInput) {
return booleanToExtendedMap.get(booleanInput);
}

}

因为您无法更改您的 Foo类,你需要为 Boolean <=> BooleanExtendedEnum 创建一个强制器.

Coercion<Boolean, BooleanExtendedEnum> threeWayBooleanToExtended = new Coercion<Boolean, BooleanExtendedEnum>() {
@Override
public BooleanExtendedEnum coerce(Boolean input) {
if (input == null) {
return BooleanExtendedEnum.UNDEFINED;
} else {
return BooleanExtendedEnum.getBooleanExtendedEnumValue(input);
}
}
};

Coercion<BooleanExtendedEnum, Boolean> threeWayExtendedToBoolean = new Coercion<BooleanExtendedEnum, Boolean>() {
@Override
public Boolean coerce(BooleanExtendedEnum input) {
if (input == null) {
return null;
} else {
return input.getBooleanValue();
}
}
};

configuration.add(new CoercionTuple<Boolean, BooleanExtendedEnum>(Boolean.class, BooleanExtendedEnum.class, threeWayBooleanToExtended));
configuration.add(new CoercionTuple<BooleanExtendedEnum, Boolean>(BooleanExtendedEnum.class, Boolean.class, threeWayExtendedToBoolean));

假设您在 BeanEditor 中完成了像这样简单的操作在你的tml :

<p:bar>
<div class="t-beaneditor-row">
<label>Bar Value</label>
<t:select t:id="fooBar" t:value="foo.bar" t:model="booleanExtendedSelectModel" t:blankOption="NEVER"/>
</div>
</p:bar>

... 并提供了 SelectModel像这样:

public SelectModel getBooleanExtendedSelectModel() {
return new EnumSelectModel(BooleanExtendedEnum.class, messages);
}

Tapestry 将创建一个包含三个选项的下拉列表

  • Undefined
  • True
  • False

但是,它将强制这些显示值的真实 boolean 值将是

  • Undefined -> 正确
  • True -> 正确
  • False ->

如何才能达到预期的效果(Undefined -> null),限制是不更改类或将其包装在另一个具有 Boolean 的类中类型字段替换为 BooleanExtendedEnum输入或使用任何其他“hacky”解决方案?

最佳答案

BeanEditor 和支持 bean 之间的“粘合剂”是 BeanModel . BeanModels 由 BeanModelSource 创建,后者又使用 PropertyConduitSource .

装饰 PropertyConduitSource 以使用 Ternary 而不是 Boolean 非常简单。

例如

public class MyAppModule {
public PropertyConduitSource decoratePropertyConduitSource(final PropertyConduitSource old) {
return new PropertyConduitSource() {
public PropertyConduit create(Class rootType, String expression) {
PropertyConduit conduit = old.create(rootType, expression);

// you cound also check for conduit.getAnnotation(AllowNull.class)
// and then annotate your bean properties for a more granular approach
if (Boolean.class.equals(conduit.getPropertyType()) {
return new TernaryPropertyConduit(conduit);
}
return conduit;
}
}
}
}

public class TernaryPropertyConduit implements PropertyConduit {
private PropertyConduit delegate;

public getPropertyType() { return Ternary.class };

public set(Object instance, Object value) {
delegate.set(instance, ((Ternary) value).asBoolean());
}

public get(Object) {
Boolean bValue = (Boolean) delegate.get(instance);
return Ternary.valueOf(instance);
}
}

关于java - 如何用三向转换覆盖 Tapestry 的双向 boolean 转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21877476/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com