@@ -115,41 +115,46 @@ private TopicName(String completeTopicName) {
115115 try {
116116 // The topic name can be in two different forms, one is fully qualified topic name,
117117 // the other one is short topic name
118- if (!completeTopicName .contains ("://" )) {
118+ int index = completeTopicName .indexOf ("://" );
119+ if (index < 0 ) {
119120 // The short topic name can be:
120121 // - <topic>
121122 // - <tenant>/<namespace>/<topic>
122- String [] parts = StringUtils .split (completeTopicName , '/' );
123- if (parts .length == 3 ) {
124- completeTopicName = TopicDomain .persistent .name () + "://" + completeTopicName ;
125- } else if (parts .length == 1 ) {
126- completeTopicName = TopicDomain .persistent .name () + "://"
127- + PUBLIC_TENANT + "/" + DEFAULT_NAMESPACE + "/" + parts [0 ];
123+ List <String > parts = splitBySlash (completeTopicName , 0 );
124+ this .domain = TopicDomain .persistent ;
125+ if (parts .size () == 3 ) {
126+ this .tenant = parts .get (0 );
127+ this .namespacePortion = parts .get (1 );
128+ this .localName = parts .get (2 );
129+ } else if (parts .size () == 1 ) {
130+ this .tenant = PUBLIC_TENANT ;
131+ this .namespacePortion = DEFAULT_NAMESPACE ;
132+ this .localName = parts .get (0 );
128133 } else {
129134 throw new IllegalArgumentException (
130135 "Invalid short topic name '" + completeTopicName + "', it should be in the format of "
131136 + "<tenant>/<namespace>/<topic> or <topic>" );
132137 }
133- }
134-
135- // Expected format: persistent ://tenant/namespace/topic
136- List < String > parts = Splitter . on ( "://" ). limit ( 2 ). splitToList ( completeTopicName );
137- this .domain = TopicDomain .getEnum (parts . get ( 0 ));
138-
139- String rest = parts . get ( 1 );
140-
141- // Scalable topic domains (topic://, segment://) only support the new format
142- // and local names may contain '/', so use limit(3) to keep the rest as localName.
143- boolean isScalableDomain = this . domain == TopicDomain . topic
144- || this . domain == TopicDomain . segment ;
145- int splitLimit = isScalableDomain ? 3 : 4 ;
146- parts = Splitter . on ( "/" ). limit ( splitLimit ). splitToList ( rest );
147- if ( parts . size () == 4 ) {
148- throw new IllegalArgumentException (
149- "V1 topic names (with cluster component) are no longer supported. "
150- + "Please use the V2 format: '<domain>://tenant/namespace/topic'. Got: "
151- + completeTopicName );
152- } else if ( parts . size () == 3 ) {
138+ this . segmentRange = null ;
139+ this . segmentId = - 1 ;
140+ this . completeTopicName = domain . name () + " ://" + tenant + "/" + namespacePortion + "/" + localName ;
141+ } else {
142+ this .domain = TopicDomain .getEnum (completeTopicName . substring ( 0 , index ));
143+ // Scalable topic domains (topic://, segment://) only support the new format
144+ // and local names may contain '/', so use limit(3) to keep the rest as localName.
145+ boolean isScalableDomain = this . domain == TopicDomain . topic
146+ || this . domain == TopicDomain . segment ;
147+ int splitLimit = isScalableDomain ? 3 : 4 ;
148+ List < String > parts = splitBySlash ( completeTopicName . substring ( index + "://" . length ()),
149+ splitLimit ) ;
150+ if ( parts . size () == 4 ) {
151+ throw new IllegalArgumentException (
152+ "V1 topic names (with cluster component) are no longer supported. "
153+ + "Please use the V2 format: '<domain>://tenant/namespace/topic'. Got: "
154+ + completeTopicName );
155+ } else if ( parts . size () != 3 ) {
156+ throw new IllegalArgumentException ( "Invalid topic name " + completeTopicName );
157+ }
153158 this .tenant = parts .get (0 );
154159 this .namespacePortion = parts .get (1 );
155160 String rawLocalName = parts .get (2 );
@@ -160,16 +165,16 @@ private TopicName(String completeTopicName) {
160165 if (lastSlash <= 0 ) {
161166 throw new IllegalArgumentException (
162167 "Invalid segment topic name: local name must contain"
163- + " '<parent-topic>/<hashStart>-<hashEnd>-<segmentId>'. Got: "
164- + completeTopicName );
168+ + " '<parent-topic>/<hashStart>-<hashEnd>-<segmentId>'. Got: "
169+ + completeTopicName );
165170 }
166171 this .localName = rawLocalName .substring (0 , lastSlash );
167172 String descriptor = rawLocalName .substring (lastSlash + 1 );
168173 String [] descParts = descriptor .split ("-" );
169174 if (descParts .length != 3 ) {
170175 throw new IllegalArgumentException (
171176 "Invalid segment descriptor: expected '<hexStart>-<hexEnd>-<segmentId>',"
172- + " got: '" + descriptor + "'" );
177+ + " got: '" + descriptor + "'" );
173178 }
174179 this .segmentRange = HashRange .of (
175180 Integer .parseInt (descParts [0 ], 16 ),
@@ -181,28 +186,24 @@ private TopicName(String completeTopicName) {
181186 this .segmentId = -1 ;
182187 }
183188
184- this .partitionIndex = getPartitionIndex (completeTopicName );
185- this .namespaceName = NamespaceName .get (tenant , namespacePortion );
186- } else {
187- throw new IllegalArgumentException ("Invalid topic name: " + completeTopicName );
189+ if (this .domain == TopicDomain .segment ) {
190+ this .completeTopicName = String .format ("%s://%s/%s/%s/%s" ,
191+ domain , tenant , namespacePortion , localName ,
192+ String .format ("%04x-%04x-%d" , segmentRange .start (), segmentRange .end (), segmentId ));
193+ } else {
194+ this .completeTopicName = completeTopicName ;
195+ }
188196 }
189197
190198 if (StringUtils .isBlank (localName )) {
191199 throw new IllegalArgumentException (String .format ("Invalid topic name: %s. Topic local name must not"
192200 + " be blank." , completeTopicName ));
193201 }
194-
202+ this .partitionIndex = getPartitionIndex (localName );
203+ this .namespaceName = NamespaceName .get (tenant , namespacePortion );
195204 } catch (NullPointerException e ) {
196205 throw new IllegalArgumentException ("Invalid topic name: " + completeTopicName , e );
197206 }
198- if (this .domain == TopicDomain .segment ) {
199- this .completeTopicName = String .format ("%s://%s/%s/%s/%s" ,
200- domain , tenant , namespacePortion , localName ,
201- String .format ("%04x-%04x-%d" , segmentRange .start (), segmentRange .end (), segmentId ));
202- } else {
203- this .completeTopicName = String .format ("%s://%s/%s/%s" ,
204- domain , tenant , namespacePortion , localName );
205- }
206207 }
207208
208209 public boolean isPersistent () {
0 commit comments