24
24
import uk .co .real_logic .sbe .ir .Token ;
25
25
import org .agrona .LangUtil ;
26
26
import org .agrona .Verify ;
27
- import org .agrona .generation .OutputManager ;
27
+ import org .agrona .generation .DynamicPackageOutputManager ;
28
28
29
29
import java .io .IOException ;
30
30
import java .io .Writer ;
31
31
import java .util .ArrayList ;
32
+ import java .util .HashSet ;
32
33
import java .util .List ;
34
+ import java .util .Set ;
33
35
import java .util .function .Predicate ;
34
36
35
37
import static uk .co .real_logic .sbe .generation .Generators .toLowerFirstChar ;
@@ -49,23 +51,48 @@ public class JavaDtoGenerator implements CodeGenerator
49
51
private static final String BASE_INDENT = "" ;
50
52
51
53
private final Ir ir ;
52
- private final OutputManager outputManager ;
54
+ private final DynamicPackageOutputManager outputManager ;
55
+ private final boolean shouldSupportTypesPackageNames ;
56
+ private final Set <String > packageNameByTypes = new HashSet <>();
53
57
54
58
/**
55
- * Create a new C# DTO {@link CodeGenerator}.
59
+ * Create a new Java DTO {@link CodeGenerator}.
56
60
*
57
- * @param ir for the messages and types.
58
- * @param outputManager for generating the DTOs to.
61
+ * @param ir for the messages and types.
62
+ * @param shouldSupportTypesPackageNames generator support for types in their own package.
63
+ * @param outputManager for generating the DTOs to.
59
64
*/
60
- public JavaDtoGenerator (final Ir ir , final OutputManager outputManager )
65
+ public JavaDtoGenerator (
66
+ final Ir ir ,
67
+ final boolean shouldSupportTypesPackageNames ,
68
+ final DynamicPackageOutputManager outputManager )
61
69
{
70
+ this .shouldSupportTypesPackageNames = shouldSupportTypesPackageNames ;
62
71
Verify .notNull (ir , "ir" );
63
72
Verify .notNull (outputManager , "outputManager" );
64
73
65
74
this .ir = ir ;
66
75
this .outputManager = outputManager ;
67
76
}
68
77
78
+ /**
79
+ * Fetch the type's explicit package - if set and should be supported.
80
+ *
81
+ * @param token the 0-th token of the type.
82
+ * @param ir the intermediate representation.
83
+ * @return the overridden package name of the type if set and supported, or {@link Ir#applicableNamespace()}.
84
+ */
85
+ private String fetchTypesPackageName (final Token token , final Ir ir )
86
+ {
87
+ if (shouldSupportTypesPackageNames && token .packageName () != null )
88
+ {
89
+ outputManager .setPackageName (token .packageName ());
90
+ return token .packageName ();
91
+ }
92
+
93
+ return ir .applicableNamespace ();
94
+ }
95
+
69
96
/**
70
97
* {@inheritDoc}
71
98
*/
@@ -110,9 +137,10 @@ public void generate() throws IOException
110
137
generateDisplay (classBuilder , encoderClassName , "computeEncodedLength()" ,
111
138
BASE_INDENT + INDENT );
112
139
140
+ final String packageName = fetchTypesPackageName (msgToken , ir );
113
141
try (Writer out = outputManager .createOutput (dtoClassName ))
114
142
{
115
- out .append (generateDtoFileHeader (ir . applicableNamespace () ));
143
+ out .append (generateDtoFileHeader (packageName ));
116
144
out .append ("import org.agrona.DirectBuffer;\n " );
117
145
out .append ("import org.agrona.MutableDirectBuffer;\n " );
118
146
out .append ("import org.agrona.concurrent.UnsafeBuffer;\n \n " );
@@ -1582,6 +1610,19 @@ private static String formatDtoClassName(final String name)
1582
1610
1583
1611
private void generateDtosForTypes () throws IOException
1584
1612
{
1613
+ if (shouldSupportTypesPackageNames )
1614
+ {
1615
+ for (final List <Token > tokens : ir .types ())
1616
+ {
1617
+ final String packageName = tokens .get (0 ).packageName ();
1618
+
1619
+ if (packageName != null )
1620
+ {
1621
+ packageNameByTypes .add (packageName );
1622
+ }
1623
+ }
1624
+ }
1625
+
1585
1626
for (final List <Token > tokens : ir .types ())
1586
1627
{
1587
1628
switch (tokens .get (0 ).signal ())
@@ -1607,10 +1648,11 @@ private void generateComposite(final List<Token> tokens) throws IOException
1607
1648
final String encoderClassName = encoderName (name );
1608
1649
final String decoderClassName = decoderName (name );
1609
1650
1651
+ final String packageName = fetchTypesPackageName (tokens .get (0 ), ir );
1610
1652
try (Writer out = outputManager .createOutput (className ))
1611
1653
{
1612
1654
final List <Token > compositeTokens = tokens .subList (1 , tokens .size () - 1 );
1613
- out .append (generateDtoFileHeader (ir . applicableNamespace () ));
1655
+ out .append (generateDtoFileHeader (packageName ));
1614
1656
out .append ("import org.agrona.DirectBuffer;\n " );
1615
1657
out .append ("import org.agrona.MutableDirectBuffer;\n " );
1616
1658
out .append ("import org.agrona.concurrent.UnsafeBuffer;\n \n " );
@@ -1638,10 +1680,11 @@ private void generateChoiceSet(final List<Token> tokens) throws IOException
1638
1680
final String encoderClassName = encoderName (name );
1639
1681
final String decoderClassName = decoderName (name );
1640
1682
1683
+ final String packageName = fetchTypesPackageName (tokens .get (0 ), ir );
1641
1684
try (Writer out = outputManager .createOutput (className ))
1642
1685
{
1643
1686
final List <Token > setTokens = tokens .subList (1 , tokens .size () - 1 );
1644
- out .append (generateDtoFileHeader (ir . applicableNamespace () ));
1687
+ out .append (generateDtoFileHeader (packageName ));
1645
1688
out .append (generateDocumentation (BASE_INDENT , tokens .get (0 )));
1646
1689
1647
1690
final ClassBuilder classBuilder = new ClassBuilder (className , BASE_INDENT , "public final" );
@@ -1795,13 +1838,35 @@ private void generateCompositePropertyElements(
1795
1838
}
1796
1839
}
1797
1840
1798
- private static CharSequence generateDtoFileHeader (final String packageName )
1841
+ private static StringBuilder generateImportStatements (final Set <String > packages , final String currentPackage )
1842
+ {
1843
+ final StringBuilder importStatements = new StringBuilder ();
1844
+
1845
+ for (final String candidatePackage : packages )
1846
+ {
1847
+ if (!candidatePackage .equals (currentPackage ))
1848
+ {
1849
+ importStatements .append ("import " ).append (candidatePackage ).append (".*;\n " );
1850
+ }
1851
+ }
1852
+
1853
+ if (!importStatements .isEmpty ())
1854
+ {
1855
+ importStatements .append ("\n \n " );
1856
+ }
1857
+
1858
+ return importStatements ;
1859
+ }
1860
+
1861
+ private CharSequence generateDtoFileHeader (final String packageName )
1799
1862
{
1800
1863
final StringBuilder sb = new StringBuilder ();
1801
1864
1802
1865
sb .append ("/* Generated SBE (Simple Binary Encoding) message DTO */\n " );
1803
1866
sb .append ("package " ).append (packageName ).append (";\n \n " );
1804
1867
1868
+ sb .append (generateImportStatements (packageNameByTypes , packageName ));
1869
+
1805
1870
return sb ;
1806
1871
}
1807
1872
0 commit comments