1515import com .github .javaparser .ast .body .ClassOrInterfaceDeclaration ;
1616import com .github .javaparser .ast .body .FieldDeclaration ;
1717import com .github .javaparser .ast .body .VariableDeclarator ;
18+ import com .github .javaparser .ast .expr .Expression ;
1819import com .github .javaparser .ast .expr .NameExpr ;
1920import com .github .javaparser .printer .lexicalpreservation .LexicalPreservingPrinter ;
2021import com .google .common .annotations .VisibleForTesting ;
3334import java .util .Objects ;
3435import java .util .Optional ;
3536import java .util .TreeMap ;
37+ import java .util .function .Function ;
3638import java .util .regex .Matcher ;
3739import java .util .regex .Pattern ;
3840import java .util .stream .Collectors ;
@@ -51,6 +53,8 @@ public class UpdateVersionsTask extends AbstractVersionsTask {
5153 private boolean setCurrent ;
5254 @ Nullable
5355 private Version removeVersion ;
56+ @ Nullable
57+ private String addTransportVersion ;
5458
5559 @ Inject
5660 public UpdateVersionsTask (BuildLayout layout ) {
@@ -62,6 +66,11 @@ public void addVersion(String version) {
6266 this .addVersion = Version .fromString (version );
6367 }
6468
69+ @ Option (option = "add-transport-version" , description = "Specifies transport version to add" )
70+ public void addTransportVersion (String transportVersion ) {
71+ this .addTransportVersion = transportVersion ;
72+ }
73+
6574 @ Option (option = "set-current" , description = "Set the 'current' constant to the new version" )
6675 public void setCurrent (boolean setCurrent ) {
6776 this .setCurrent = setCurrent ;
@@ -87,15 +96,18 @@ static Optional<Version> parseVersionField(CharSequence field) {
8796
8897 @ TaskAction
8998 public void executeTask () throws IOException {
90- if (addVersion == null && removeVersion == null ) {
99+ if (addVersion == null && removeVersion == null && addTransportVersion == null ) {
91100 throw new IllegalArgumentException ("No versions to add or remove specified" );
92101 }
93102 if (setCurrent && addVersion == null ) {
94103 throw new IllegalArgumentException ("No new version added to set as the current version" );
95104 }
96- if (Objects .equals (addVersion , removeVersion )) {
105+ if (addVersion != null && removeVersion != null && Objects .equals (addVersion , removeVersion )) {
97106 throw new IllegalArgumentException ("Same version specified to add and remove" );
98107 }
108+ if (addTransportVersion != null && addTransportVersion .split (":" ).length != 2 ) {
109+ throw new IllegalArgumentException ("Transport version specified must be in the format '<constant>:<version-id>'" );
110+ }
99111
100112 Path versionJava = rootDir .resolve (VERSION_FILE_PATH );
101113 CompilationUnit file = LexicalPreservingPrinter .setup (StaticJavaParser .parse (versionJava ));
@@ -115,6 +127,18 @@ public void executeTask() throws IOException {
115127 modifiedFile = removed ;
116128 }
117129 }
130+ if (addTransportVersion != null ) {
131+ var constant = addTransportVersion .split (":" )[0 ];
132+ var versionId = Integer .parseInt (addTransportVersion .split (":" )[1 ]);
133+ LOGGER .lifecycle ("Adding transport version constant [{}] with id [{}]" , constant , versionId );
134+
135+ var transportVersionsFile = rootDir .resolve (TRANSPORT_VERSIONS_FILE_PATH );
136+ var transportVersions = LexicalPreservingPrinter .setup (StaticJavaParser .parse (transportVersionsFile ));
137+ var modified = addTransportVersionConstant (transportVersions , constant , versionId );
138+ if (modified .isPresent ()) {
139+ writeOutNewContents (transportVersionsFile , modified .get ());
140+ }
141+ }
118142
119143 if (modifiedFile .isPresent ()) {
120144 writeOutNewContents (versionJava , modifiedFile .get ());
@@ -161,6 +185,51 @@ static Optional<CompilationUnit> addVersionConstant(CompilationUnit versionJava,
161185 return Optional .of (versionJava );
162186 }
163187
188+ @ VisibleForTesting
189+ static Optional <CompilationUnit > addTransportVersionConstant (CompilationUnit transportVersions , String constant , int versionId ) {
190+ ClassOrInterfaceDeclaration transportVersionsClass = transportVersions .getClassByName ("TransportVersions" ).get ();
191+ if (transportVersionsClass .getFieldByName (constant ).isPresent ()) {
192+ LOGGER .lifecycle ("New transport version constant [{}] already present, skipping" , constant );
193+ return Optional .empty ();
194+ }
195+
196+ TreeMap <Integer , FieldDeclaration > versions = transportVersionsClass .getFields ()
197+ .stream ()
198+ .filter (f -> f .getElementType ().asString ().equals ("TransportVersion" ))
199+ .filter (
200+ f -> f .getVariables ().stream ().limit (1 ).allMatch (v -> v .getInitializer ().filter (Expression ::isMethodCallExpr ).isPresent ())
201+ )
202+ .filter (f -> f .getVariable (0 ).getInitializer ().get ().asMethodCallExpr ().getNameAsString ().endsWith ("def" ))
203+ .collect (
204+ Collectors .toMap (
205+ f -> f .getVariable (0 )
206+ .getInitializer ()
207+ .get ()
208+ .asMethodCallExpr ()
209+ .getArgument (0 )
210+ .asIntegerLiteralExpr ()
211+ .asNumber ()
212+ .intValue (),
213+ Function .identity (),
214+ (f1 , f2 ) -> {
215+ throw new IllegalStateException ("Duplicate version constant " + f1 );
216+ },
217+ TreeMap ::new
218+ )
219+ );
220+
221+ // find the version this should be inserted after
222+ Map .Entry <Integer , FieldDeclaration > previousVersion = versions .lowerEntry (versionId );
223+ if (previousVersion == null ) {
224+ throw new IllegalStateException (String .format ("Could not find previous version to [%s]" , versionId ));
225+ }
226+
227+ FieldDeclaration newTransportVersion = createNewTransportVersionConstant (previousVersion .getValue (), constant , versionId );
228+ transportVersionsClass .getMembers ().addAfter (newTransportVersion , previousVersion .getValue ());
229+
230+ return Optional .of (transportVersions );
231+ }
232+
164233 private static FieldDeclaration createNewVersionConstant (FieldDeclaration lastVersion , String newName , String newExpr ) {
165234 return new FieldDeclaration (
166235 new NodeList <>(lastVersion .getModifiers ()),
@@ -172,6 +241,29 @@ private static FieldDeclaration createNewVersionConstant(FieldDeclaration lastVe
172241 );
173242 }
174243
244+ private static FieldDeclaration createNewTransportVersionConstant (FieldDeclaration lastVersion , String newName , int newId ) {
245+ return new FieldDeclaration (
246+ new NodeList <>(lastVersion .getModifiers ()),
247+ new VariableDeclarator (
248+ lastVersion .getCommonType (),
249+ newName ,
250+ StaticJavaParser .parseExpression (String .format ("def(%s)" , formatTransportVersionId (newId )))
251+ )
252+ );
253+ }
254+
255+ private static String formatTransportVersionId (int id ) {
256+ String idString = Integer .toString (id );
257+
258+ return new StringBuilder (idString .substring (idString .length () - 2 , idString .length ())).insert (0 , "_" )
259+ .insert (0 , idString .substring (idString .length () - 3 , idString .length () - 2 ))
260+ .insert (0 , "_" )
261+ .insert (0 , idString .substring (idString .length () - 6 , idString .length () - 3 ))
262+ .insert (0 , "_" )
263+ .insert (0 , idString .substring (0 , idString .length () - 6 ))
264+ .toString ();
265+ }
266+
175267 @ VisibleForTesting
176268 static Optional <CompilationUnit > removeVersionConstant (CompilationUnit versionJava , Version version ) {
177269 String removeFieldName = toVersionField (version );
0 commit comments