@@ -120,41 +120,46 @@ private TopicName(String completeTopicName) {
120120 try {
121121 // The topic name can be in two different forms, one is fully qualified topic name,
122122 // the other one is short topic name
123- if (!completeTopicName .contains ("://" )) {
123+ int index = completeTopicName .indexOf ("://" );
124+ if (index < 0 ) {
124125 // The short topic name can be:
125126 // - <topic>
126127 // - <tenant>/<namespace>/<topic>
127- String [] parts = StringUtils .split (completeTopicName , '/' );
128- if (parts .length == 3 ) {
129- completeTopicName = TopicDomain .persistent .name () + "://" + completeTopicName ;
130- } else if (parts .length == 1 ) {
131- completeTopicName = TopicDomain .persistent .name () + "://"
132- + PUBLIC_TENANT + "/" + DEFAULT_NAMESPACE + "/" + parts [0 ];
128+ List <String > parts = splitBySlash (completeTopicName , 0 );
129+ this .domain = TopicDomain .persistent ;
130+ if (parts .size () == 3 ) {
131+ this .tenant = parts .get (0 );
132+ this .namespacePortion = parts .get (1 );
133+ this .localName = parts .get (2 );
134+ } else if (parts .size () == 1 ) {
135+ this .tenant = PUBLIC_TENANT ;
136+ this .namespacePortion = DEFAULT_NAMESPACE ;
137+ this .localName = parts .get (0 );
133138 } else {
134139 throw new IllegalArgumentException (
135140 "Invalid short topic name '" + completeTopicName + "', it should be in the format of "
136141 + "<tenant>/<namespace>/<topic> or <topic>" );
137142 }
138- }
139-
140- // Expected format: persistent ://tenant/namespace/topic
141- List < String > parts = Splitter . on ( "://" ). limit ( 2 ). splitToList ( completeTopicName );
142- this .domain = TopicDomain .getEnum (parts . get ( 0 ));
143-
144- String rest = parts . get ( 1 );
145-
146- // Scalable topic domains (topic://, segment://) only support the new format
147- // and local names may contain '/', so use limit(3) to keep the rest as localName.
148- boolean isScalableDomain = this . domain == TopicDomain . topic
149- || this . domain == TopicDomain . segment ;
150- int splitLimit = isScalableDomain ? 3 : 4 ;
151- parts = Splitter . on ( "/" ). limit ( splitLimit ). splitToList ( rest );
152- if ( parts . size () == 4 ) {
153- throw new IllegalArgumentException (
154- "V1 topic names (with cluster component) are no longer supported. "
155- + "Please use the V2 format: '<domain>://tenant/namespace/topic'. Got: "
156- + completeTopicName );
157- } else if ( parts . size () == 3 ) {
143+ this . segmentRange = null ;
144+ this . segmentId = - 1 ;
145+ this . completeTopicName = domain . name () + " ://" + tenant + "/" + namespacePortion + "/" + localName ;
146+ } else {
147+ this .domain = TopicDomain .getEnum (completeTopicName . substring ( 0 , index ));
148+ // Scalable topic domains (topic://, segment://) only support the new format
149+ // and local names may contain '/', so use limit(3) to keep the rest as localName.
150+ boolean isScalableDomain = this . domain == TopicDomain . topic
151+ || this . domain == TopicDomain . segment ;
152+ int splitLimit = isScalableDomain ? 3 : 4 ;
153+ List < String > parts = splitBySlash ( completeTopicName . substring ( index + "://" . length ()),
154+ splitLimit ) ;
155+ if ( parts . size () == 4 ) {
156+ throw new IllegalArgumentException (
157+ "V1 topic names (with cluster component) are no longer supported. "
158+ + "Please use the V2 format: '<domain>://tenant/namespace/topic'. Got: "
159+ + completeTopicName );
160+ } else if ( parts . size () != 3 ) {
161+ throw new IllegalArgumentException ( "Invalid topic name " + completeTopicName );
162+ }
158163 this .tenant = parts .get (0 );
159164 this .namespacePortion = parts .get (1 );
160165 String rawLocalName = parts .get (2 );
@@ -165,16 +170,16 @@ private TopicName(String completeTopicName) {
165170 if (lastSlash <= 0 ) {
166171 throw new IllegalArgumentException (
167172 "Invalid segment topic name: local name must contain"
168- + " '<parent-topic>/<hashStart>-<hashEnd>-<segmentId>'. Got: "
169- + completeTopicName );
173+ + " '<parent-topic>/<hashStart>-<hashEnd>-<segmentId>'. Got: "
174+ + completeTopicName );
170175 }
171176 this .localName = rawLocalName .substring (0 , lastSlash );
172177 String descriptor = rawLocalName .substring (lastSlash + 1 );
173178 String [] descParts = descriptor .split ("-" );
174179 if (descParts .length != 3 ) {
175180 throw new IllegalArgumentException (
176181 "Invalid segment descriptor: expected '<hexStart>-<hexEnd>-<segmentId>',"
177- + " got: '" + descriptor + "'" );
182+ + " got: '" + descriptor + "'" );
178183 }
179184 this .segmentRange = HashRange .of (
180185 Integer .parseInt (descParts [0 ], 16 ),
@@ -186,28 +191,24 @@ private TopicName(String completeTopicName) {
186191 this .segmentId = -1 ;
187192 }
188193
189- this .partitionIndex = getPartitionIndex (completeTopicName );
190- this .namespaceName = NamespaceName .get (tenant , namespacePortion );
191- } else {
192- throw new IllegalArgumentException ("Invalid topic name: " + completeTopicName );
194+ if (this .domain == TopicDomain .segment ) {
195+ this .completeTopicName = String .format ("%s://%s/%s/%s/%s" ,
196+ domain , tenant , namespacePortion , localName ,
197+ String .format ("%04x-%04x-%d" , segmentRange .start (), segmentRange .end (), segmentId ));
198+ } else {
199+ this .completeTopicName = completeTopicName ;
200+ }
193201 }
194202
195203 if (StringUtils .isBlank (localName )) {
196204 throw new IllegalArgumentException (String .format ("Invalid topic name: %s. Topic local name must not"
197205 + " be blank." , completeTopicName ));
198206 }
199-
207+ this .partitionIndex = getPartitionIndex (localName );
208+ this .namespaceName = NamespaceName .get (tenant , namespacePortion );
200209 } catch (NullPointerException e ) {
201210 throw new IllegalArgumentException ("Invalid topic name: " + completeTopicName , e );
202211 }
203- if (this .domain == TopicDomain .segment ) {
204- this .completeTopicName = String .format ("%s://%s/%s/%s/%s" ,
205- domain , tenant , namespacePortion , localName ,
206- String .format ("%04x-%04x-%d" , segmentRange .start (), segmentRange .end (), segmentId ));
207- } else {
208- this .completeTopicName = String .format ("%s://%s/%s/%s" ,
209- domain , tenant , namespacePortion , localName );
210- }
211212 }
212213
213214 public boolean isPersistent () {
0 commit comments