Generic builder of (almost) identical 3rd party classes - scala

I have a bunch of 3rd party classes, these classes are autogenerated in java and do not have any hierarchy
Here is the RulesPropertyList
enum RulesPropertyType {...}
class RulesPropertyValue {...}
class RulesProperty {
public RulesPropertyType getPropertyTypeCode(){...}
public RulesPropertyValue getPropertyValue() {...}
}
class RulesPropertyList {
public void setNumProperties(int numProperties)
public void setProperties(RulesProperty[] properties)
}
And its Characs* sibling
enum CharacsPropertyType {...}
class CharacsPropertyValue {...}
class CharacsProperty {
public CharacsPropertyType getPropertyTypeCode(){...}
public CharacsPropertyValue getPropertyValue() {...}
}
class CharacsPropertyList {
public void setNumProperties(int numProperties)
public void setProperties(CharacsProperty[] properties)
}
There are more than just Rules* and Characs* families of classes, and classes actually have more fields and deeper structures.
All classes are completely identical except for the prefixes in the class names.
Currently, I have a separate builder method for each set of classes.
def buildRulesPropertyList(props: (RulesPropertyType, RulesPropertValue): RulesPropertyList = {
val properties = props.map { case (type, value) =>
RulesProperty(type, value)
}
val propList = RulesPropertyList
propList.setProperties(properties.toArray)
propList.setNumProperties(properties.length)
propList
}
I have to create such a builder for each family of classes.
Now I only see a possibility to make a generic builder using reflection.
Is there a way in Scala to make such a builder using generics in Scala language?

Is there a way in Scala to make such a builder using generics in Scala language?
yes, but I don't think it's going to be any less code. I think your best move here is to just write some simple code generation for each type. you would feed it a list of family names like Seq("Rules", "Characs", ...) and have it spit out your build${family}PropertyList methods.

Related

Mapping Hierarchy of Classes with Mapstruct

I have a hierarchy of classes: VehicleDTO is a base abstract class.
CarDTO, TruckDTO, VanDTO extend from it.
I have the same hierarchy on the other side of a mapper:
VehicleBO <- CarBO, TruckBO, VanBO.
I want to have all the mapping logic consolidated in one mapper. Period.
I have defined mappings for common attributes, but here is when it becomes interesting, I get this exception during compilation:
The return type ... is an abstract class or interface.
Provide a non abstract / non interface result type or a factory method.
So, how do I specify a factory method, that based on a value of a particular attribute or a class of the pojo, would create a target object for me? I would appreciate a good code snippet that actually does the trick.
Thanks!
You can use a method annotated with #ObjectFactory receiving a source parameter for what you need.
Let's assume that you have a mapper that looks like:
#Mapper
public interface VehicleMapper {
VehicleDTO map(VehicleBO vehicle);
// more
}
If you add a method looking like:
#ObjectFactory
default VehicleDTO createVehicleDto(VehicleBO vehicle) {
// your creation logic
}
Then MapStruct will use the createVehicleDto to create the VehicleDTO object.
NOTE when mapping hierarchies and when the mapping looks like the one in the answer then MapStruct will only map the properties which are in the VehicleDTO class and not in possible implementations of the class. The reason for that is that MapStruct generates the mapping code during compilation and not during runtime.
For mapping hierarchies like what you explained you can do something like the following:
public interface VehicleMapper {
default VehicleDTO map(VehicleBO vehicle) {
if (vehicle instanceOf CarBO) {
return map((CarBO) vehicle);
} else if (vehicle instanceOf TruckBO) {
return map((TruckBO) vehicle);
} else if (vehicle instanceOf VanBO) {
return map((VanBO) vehicle);
} else {
//TODO decide what you want to do
}
}
#Named("car")
CarDTO map(CarBO car);
#Named("truck")
TruckDTO map(TruckBO truck);
#Named("car")
VanDTO map(VanBO van);
// more
}
There is mapstruct/mapstruct#131 requesting for generating code like my example out of the box
Nowadays, maybe using Visitor pattern could be better choice instead of the instanceOf way, check below:
https://techlab.bol.com/en/blog/mapstruct-object-hierarchies
You need to set the subclassExhaustiveStrategy property in your #Mapper annotation to RUNTIME_EXCEPTION.
See Mapstruct documentation:
...
To allow mappings for abstract classes or interfaces you need to set the subclassExhaustiveStrategy to RUNTIME_EXCEPTION, you can do this at the #MapperConfig, #Mapper or #BeanMapping annotations. If you then pass a GrapeDto an IllegalArgumentException will be thrown because it is unknown how to map a GrapeDto. Adding the missing (#SubclassMapping) for it will fix that.
...

How can an abstract implement an interface?

I have a common interface that describes access to the output stream like this:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
And I have an abstract implementation of this interface based on standard haxe.io.BytesOutput class:
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
Though this abstract is truly implementing interface described above there's no direct reference to interface and when I'm trying to use it like this:
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output); // type error
}
}
Compiler throws an error: COutput should be IOutput. I can solve this problem only through using common class that wraps BytesOutput and implements IOutput.
My question is how to show the Haxe compiler that the abstract implements the interface.
Abstracts can't implement interfaces because they're a compile-time feature and don't exist at runtime. This conflicts with interfaces, they do exist at runtime and dynamic runtime checks like Std.is(something, IOutput) have to work.
Haxe also has a mechanism called structural subtyping that can be used as an alternative to interfaces. With this approach, there's no need for an explicit implements declaration, it's good enough if something unifies with a structure:
typedef IOutput = {
function writeInteger(aValue:Int):Void;
}
Unfortunately, abstracts aren't compatible with structural subtyping either due to the way they're implemented.
Have you considered using static extensions instead? At least for your simple example, that seems like the perfect solution for making a writeInteger() method available for any haxe.io.Output:
import haxe.io.Output;
import haxe.io.BytesOutput;
using Main.OutputExtensions;
class Main {
static function main() {
var output = new BytesOutput();
output.writeInteger(0);
}
}
class OutputExtensions {
public static function writeInteger(output:Output, value:Int):Void {
output.writeInt32(value);
}
}
You could even combine this with structural subtyping so writeInteger() becomes available on anything that has a writeInt32() method (try.haxe link):
typedef Int32Writable = {
function writeInt32(value:Int):Void;
}
As #Gama11 states, abstracts cannot implement interfaces. In Haxe, for type to implement an interface, it must be able to be compiled to something class-like that can be called using the interface’s methods without any magic happening. That is, to use a type as its interface, there needs to be a “real” class implementing that type. Abstracts in Haxe compile down to their base type—the abstract itself is entirely invisible after compilation happens. Thus, at runtime, there is no instance of a class with the methods defined in your abstract which implement the interface.
However, you can make your abstract appear to implement an interface by defining an implicit conversion to the interface you are trying to implement. For your example, the following might work:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
#:to()
public inline function toIOutput():IOutput {
return new COutputWrapper((cast this : COutput));
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
class COutputWrapper implements IOutput {
var cOutput(default, null):COutput;
public function new(cOutput) {
this.cOutput = cOutput;
}
public function writeInteger(aValue:Int) {
cOutput.writeInteger(aValue);
}
}
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output);
out(output);
}
}
Run on try.haxe.org
Note that, each time an implicit conversion happens, a new instance of the wrapper will be constructed. This may have performance implications. If you only access your value through its interface, consider setting the type of your variable to the interface rather than the abstract.
This is similar to “boxing” a primitive/value type in C#. In C#, value types, defined using the struct keyword, are allowed to implement interfaces. Like an abstract in Haxe, a value type in C# is compiled (by the JITter) into untyped code which simply directly accesses and manipulates the value for certain operations. However, C# allows structs to implement interfaces. The C# compiler will translate any attempt to implicitly cast a struct to an implemented interface into the construction of a wrapper class which stores a copy of the value and implements the interface—similar to our manually authored wrapper class (this wrapper class is actually generated by the runtime as part of JITing and is performed by the IL box instruction. See M() in this example). It is conceivable that Haxe could add a feature to automatically generate such a wrapper class for you like C# does for struct types, but that is not currently a feature. You may, however, do it yourself, as exemplified above.

PostSharp C# - How to Implement All Fields Required

PostSharp contracts make it easy to label individual fields as Required. But I want a class attribute that makes all of the class fields required. I'm guessing I would have to implement a custom aspect to support this.
It seems like it would be a common need for anyone passing around data containers. Can anyone direct me to some code that implements a custom "AllFieldsRequired" aspect in PostSharp?
You can implement PostSharp.Aspects.IAspectProvider:
public class AllFieldsRequiredAttribute : TypeLevelAspect, IAspectProvider
{
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
{
Type type = (Type)targetElement;
return type.GetFields().Select(
m => new AspectInstance(m, new ObjectConstruction(typeof(RequiredAttribute))));
}
}
[AllFieldsRequired]
public class Foo
{
public string Bar;
public object Baz;
}

How do I know when to use an enum or a sub-class?

Let's say I am making a game of chess. Would it be more effective to have a base class of Piece()? With sub-classes for each type of piece.
Or, an enum
enum Piece{
King,
Queen,
Knight,
etc;
}
It also brings me onto a common problem I have when refining data.
GameObjects
Piece extends GameObjects
Should I stop here and declare the objects with their individual properties?
Piece King = new Piece("King",5,10); //just made up values, no significance.
Or refine it further and have:
King extends Piece
and then handle King Pieces in a polymorphic way:
Piece king = new King("King,5,10);
thanks
Polymorphism
It depends on how you want to structure the logic of your game, but it probably makes sense to define common behavior (methods) and attributes (fields) in an abstract Piece class and then have each subtype implement abstract methods (or override default methods) and set values of inherited fields based on the ways that they vary. Maybe something like:
public abstract class Piece {
protected int value;
public int getValue() {
return value;
}
public abstract boolean isValidMove(String move);
public void move(String move) {
//common logic here
doMove(move);
}
protected abstract void doMove(String move);
}
public class King extends Piece {
public King() {
this.value = 20;
}
public boolean isValidMove(String move) {
//specific king logic here
}
protected void doMove(String move) {
//more specific king logic
}
}
This would allow you to use polymorphism to define various pieces with a common Piece API, while the important differences are handled by each concrete type.
Piece king = new King();
//...
if(king.isValidMove(move)) king.move(move);
Enums
Enums allow you to create a set of optimized singleton instances of a common type, which can also define behavior, but they don't support overriding/implementing type-specific behavior very well because you end up having to check which enum the current instance when implementing variations. You would also end up with a problem of only having a single KING or PAWN instance when you really need multiples of those for a game (one white king and one black king, 8 white pawns and 8 black pawns).
public enum Piece {
KING(20),
PAWN(1);
private int value;
private Piece(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public boolean isValidMove(String move) {
switch(this) {
case KING:
//king specific logic
break;
case PAWN:
//pawn specific logic
break;
}
}
public void move(String move) {
if(this == KING) {
//king specific logic
} else if(this == PAWN) {
//pawn specific logic
}
}
}
So an enum probably wouldn't work very well in this scenario.
Use an enum when there are a limited and defined number if instances.
In this case, clearly there are a defined number of pieces, so use an enum.
Note that enums can have methods just like a regular class, so enums don't have to be just "values", they can do stuff.
I would not try to cram too much into your enum, and in fact I would name it PieceType to make it clear what it represents, and perhaps have a class Piece which is an instance of a piece that has a PieceType, a location (board square) and a color.
The main distinction is that the set of sub-classes is open-ended: you or other people who use your code can create new sub-classes without breaking old code.
Enums are the opposite: other people cannot add new items to your enum and even you, the maintainer of the code, cannot add new enum constants without double-checking every single switch-case statement.
So, use enums if you do not expect new items to be added to the set. Use sub-classes otherwise. This does not mean that sub-classes are better: if you know the set of options to be closed-ended then you should NOT use sub-classes. If you do, you will find yourself writing if (... instanceof ...) chains!
If with enums you find yourself adding new cases to your switch statements (or you can anticipate that) then switch to sub-classes. And if with sub-classes, you find yourself writing instanceof chains, then switch to enums.

Cast class to base interface via reflection cause exception

I'm loading a .NET assembly dinamically via reflection and I'm getting all the classes that it contains (at the moment one). After this, I'm trying to cast the class to an interface that I'm 100% sure the class implements but I receive this exception: Unable to cast object of type System.RuntimeType to the type MyInterface
MyDLL.dll
public interface MyInterface
{
void MyMethod();
}
MyOtherDLL.dll
public class MyClass : MyInterface
{
public void MyMethod()
{
...
}
}
public class MyLoader
{
Assembly myAssembly = Assembly.LoadFile("MyDLL.dll");
IEnumerable<Type> types = extension.GetTypes().Where(x => x.IsClass);
foreach (Type type in types)
{
((MyInterface)type).MyMethod();
}
}
I have stripped out all the code that is not necessary. This is basically what I do. I saw in this question that Andi answered with a problem that seems the same mine but I cannot anyway fix it.
You are trying to cast a .NET framework object of type Type to an interface that you created. The Type object does not implement your interface, so it can't be cast. You should first create a specific instance of your object, such as through using an Activator like this:
// this goes inside your for loop
MyInterface myInterface = (MyInterface)Activator.CreateInstance(type, false);
myInterface.MyMethod();
The CreateInstance method has other overloades that may fit your needs.