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