working around Tuple22 limitation
Earlier this year I wrote about hitting some scala limitations:
Scala supports only up to
Tuple22
.
This means that Scala can define case classes only up to 22 parameters. I've implemented workarounds to use schema that includes complex types that has more than 22 particles within the sequence.
First, when a sequence contains more than MaxParticleSize
(20) particles, it will split up the sequence into chunks of ChunkParticleSize
(10). For example, a sequence that has 30 elements would be split into three chunks of 10 elements:
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element name="string1" type="xs:string"/>
<xs:element name="string2" type="xs:string"/>
<xs:element name="string3" type="xs:string"/>
...
<xs:element name="string30" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
scalaxb converts the above element into as the following:
case class Foo(arg1: FooSequence2, arg2: FooSequence3, arg3: FooSequence4) { def string1 = arg1.string1 def string2 = arg1.string2 def string3 = arg1.string3 def string4 = arg1.string4 def string5 = arg1.string5 def string6 = arg1.string6 def string7 = arg1.string7 def string8 = arg1.string8 def string9 = arg1.string9 def string10 = arg1.string10 def string11 = arg2.string11 def string12 = arg2.string12 def string13 = arg2.string13 def string14 = arg2.string14 def string15 = arg2.string15 def string16 = arg2.string16 def string17 = arg2.string17 def string18 = arg2.string18 def string19 = arg2.string19 def string20 = arg2.string20 def string21 = arg3.string21 def string22 = arg3.string22 def string23 = arg3.string23 def string24 = arg3.string24 def string25 = arg3.string25 def string26 = arg3.string26 def string27 = arg3.string27 def string28 = arg3.string28 def string29 = arg3.string29 def string30 = arg3.string30 } case class FooSequence2(string1: String, string2: String, string3: String, string4: String, string5: String, string6: String, string7: String, string8: String, string9: String, string10: String) case class FooSequence3(string11: String, string12: String, string13: String, string14: String, string15: String, string16: String, string17: String, string18: String, string19: String, string20: String) case class FooSequence4(string21: String, string22: String, string23: String, string24: String, string25: String, string26: String, string27: String, string28: String, string29: String, string30: String)
Another way a complex type can go over 22 particles is by extension. XML Schema allows complex types to be extended from another similar to inheritance in type systems. On the other hand, inheritance of case classes does not work.
<xs:complexType name="barOne">
<xs:sequence>
<xs:element name="int1" type="xs:int"/>
<xs:element name="int2" type="xs:int"/>
<xs:element name="int3" type="xs:int"/>
<xs:element name="int4" type="xs:int"/>
<xs:element name="int5" type="xs:int"/>
<xs:element name="int6" type="xs:int"/>
<xs:element name="int7" type="xs:int"/>
<xs:element name="int8" type="xs:int"/>
<xs:element name="int9" type="xs:int"/>
<xs:element name="int10" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="barTwo">
<xs:complexContent>
<xs:extension base="barOne">
<xs:sequence>
<xs:element name="int11" type="xs:int"/>
<xs:element name="int12" type="xs:int"/>
<xs:element name="int13" type="xs:int"/>
<xs:element name="int14" type="xs:int"/>
<xs:element name="int15" type="xs:int"/>
<xs:element name="int16" type="xs:int"/>
<xs:element name="int17" type="xs:int"/>
<xs:element name="int18" type="xs:int"/>
<xs:element name="int19" type="xs:int"/>
<xs:element name="int20" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="barThree">
<xs:complexContent>
<xs:extension base="barTwo">
<xs:sequence>
<xs:element name="int21" type="xs:int"/>
<xs:element name="int22" type="xs:int"/>
<xs:element name="int23" type="xs:int"/>
<xs:element name="int24" type="xs:int"/>
<xs:element name="int25" type="xs:int"/>
<xs:element name="int26" type="xs:int"/>
<xs:element name="int27" type="xs:int"/>
<xs:element name="int28" type="xs:int"/>
<xs:element name="int29" type="xs:int"/>
<xs:element name="int30" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Normally barThree
will produce illegal case class with 30 parameters. The way to work around it is to wrap one of the complex type into a separate case class, but scalaxb wouldn't know which one. This is where --wrap-contents
comes in. Using the option, we can specify which complex type to wrap using its name. The follow is generated by scalaxb with --wrap-contents BarOne
:
case class BarThree(arg1: BarOnableSequence2, int11: Int, int12: Int, int13: Int, int14: Int, int15: Int, int16: Int, int17: Int, int18: Int, int19: Int, int20: Int, int21: Int, int22: Int, int23: Int, int24: Int, int25: Int, int26: Int, int27: Int, int28: Int, int29: Int, int30: Int) extends BarTwoable { def int1 = arg1.int1 def int2 = arg1.int2 def int3 = arg1.int3 def int4 = arg1.int4 def int5 = arg1.int5 def int6 = arg1.int6 def int7 = arg1.int7 def int8 = arg1.int8 def int9 = arg1.int9 def int10 = arg1.int10 }