S2Dxoで列挙さらに続き
id:koichikさんにコメント戴きまして。有難う御座居ます。
教わったとおり、こんな感じで。
public Object convert(Object source, Class destClass, ConversionContext context) { if(source ==null){ return null; } String srcStr = source.toString(); for(Object e: destClass.getEnumConstants()){ if(e.toString().equals(srcStr)){ return e; } } return null; }
わーできました!getEnumConstantsなんてメソッドがあったとは・・・これでEnum側でgetEnumFromなんてクラスメソッドを実装しないでいけますよ。
標準ではEnum#name()とEnum#toString()は戻り値同じだし、比較する文字列を変えたい時はtoString()をオーバーライドすると云う方針ならば、これはかなり汎用的に使えそうですね。
と思ったら、converterのgetDestClassの戻り値をEnum.classにして汎用的にしようと思ったら、ConverterFactoryImplのgetDistanceでBeanConverterよりランクが下になっちゃって、BeanConverterが優先されちゃいました。
getDistanceの中でisEnumとか使ってランキング(ってんですかね)のロジックをいじればよさそうな予感なんですが、うむむむ。
S2Dxoで列挙まだつづく
ConverterFactoryImplのgetDistance(Class, Class, double)の中で、列挙用にランク付けをしてみる。
private double getDistance(final Class assigner, final Class assignee, final double distance) { if (assignee.equals(assigner)) { return distance; } //これ追加 if(assigner.equals(Enum.class) && assignee.isEnum()){ return distance + 0.5; } if (isImplements(assigner, assignee)) { return distance + 0.5; } final Class superClass = assigner.getSuperclass(); if (superClass == null) { return distance + 1; } return getDistance(superClass, assignee, distance + 1); }
これで出来ました。
コンバータのgetDestClass()をEnum.classにしたものと、特定の列挙を指定した物と同時にテストしたんですが、distanceを +0.5にしたので、特定の列挙を決め打ちした奴に合致した場合はそっちが優先されました。
assignerをEnum.class限定にしたのは、全然違う列挙がgetDestClass()で指定された場合はもっと遠くに行って貰おうという事なんですが、考え方合ってるかな。
すぐ下のisImplements()の場合のポイントと同じ。距離感は一緒かなと思ったので。
ああ面白かった。