Skip to content

Commit ba0b36e

Browse files
gitgabrioGabriele-Cardosi
andauthored
[7.67.x-incubator-kie-issues#1382] Backport (#6022)
Co-authored-by: Gabriele-Cardosi <[email protected]>
1 parent dbdfc71 commit ba0b36e

File tree

2 files changed

+125
-2
lines changed

2 files changed

+125
-2
lines changed

drools-core/src/main/java/org/drools/core/util/StringUtils.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,22 +976,40 @@ public static String extractFirstIdentifier(String string, int start) {
976976
return builder.toString();
977977
}
978978

979+
/**
980+
* Method that tries to extract <b>identifiers</b> from a Srting.
981+
* First, it tries to identify "quoted" part, that should be ignored.
982+
* Then, it tries to extract a String that is valid as java identifier.
983+
* If an identifier is found, returns the last index of the identifier itself, otherwise the length of the string itself
984+
*
985+
* {@link Character#isJavaIdentifierStart}
986+
* {@link Character#isJavaIdentifierPart}
987+
* @param string
988+
* @param builder
989+
* @param start
990+
* @return
991+
*/
979992
public static int extractFirstIdentifier(String string, StringBuilder builder, int start) {
980993
boolean isQuoted = false;
994+
boolean isDoubleQuoted = false;
995+
boolean isSingleQuoted = false;
981996
boolean started = false;
982997
int i = start;
983998
for (; i < string.length(); i++) {
984999
char ch = string.charAt(i);
9851000
if (!isQuoted && Character.isJavaIdentifierStart(ch)) {
9861001
builder.append(ch);
9871002
started = true;
988-
} else if (ch == '"' || ch == '\'') {
989-
isQuoted = !isQuoted;
1003+
} else if (ch == '"') {
1004+
isDoubleQuoted = !isQuoted && !isDoubleQuoted;
1005+
} else if (ch == '\'') {
1006+
isSingleQuoted = !isQuoted && !isSingleQuoted;
9901007
} else if (started && Character.isJavaIdentifierPart(ch)) {
9911008
builder.append(ch);
9921009
} else if (started) {
9931010
break;
9941011
}
1012+
isQuoted = isDoubleQuoted || isSingleQuoted;
9951013
}
9961014
return i;
9971015
}

drools-core/src/test/java/org/drools/core/util/StringUtilsTest.java

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,111 @@ public boolean isSnapshot() {
298298
}
299299
}
300300

301+
@Test
302+
public void testExtractFirstIdentifierWithStringBuilder() {
303+
// Not-quoted string, interpreted as identifier
304+
String string = "IDENTIFIER";
305+
String expected = string;
306+
StringBuilder builder = new StringBuilder();
307+
int start = 0;
308+
int retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
309+
assertThat(retrieved).isEqualTo(string.length()); // retrieved size is equals to the length of given string
310+
assertThat(builder.toString()).isEqualTo(expected);
311+
312+
// Quoted string, not interpreted as identifier
313+
string = "\"IDENTIFIER\"";
314+
expected = "";
315+
builder = new StringBuilder();
316+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
317+
assertThat(retrieved).isEqualTo(string.length());
318+
assertThat(builder.toString()).isEqualTo(expected);
319+
320+
// Only the not-quoted string, and its size, is returned
321+
string = "IDENTIFIER \"";
322+
expected = "IDENTIFIER";
323+
builder = new StringBuilder();
324+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
325+
assertThat(retrieved).isEqualTo(expected.length()); // it returns the index where the identifier ends
326+
assertThat(builder.toString()).isEqualTo(expected);
327+
328+
string = "IDENTIFIER \"the_identifier";
329+
expected = "IDENTIFIER";
330+
builder = new StringBuilder();
331+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
332+
assertThat(retrieved).isEqualTo(expected.length()); // it returns the index where the identifier ends
333+
assertThat(builder.toString()).isEqualTo(expected);
334+
335+
string = "\"the_identifier\" IDENTIFIER";
336+
expected = "IDENTIFIER";
337+
builder = new StringBuilder();
338+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
339+
assertThat(retrieved).isEqualTo(string.length()); // it returns the index where the identifier ends
340+
assertThat(builder.toString()).isEqualTo(expected);
341+
342+
// Quoted string, not interpreted as identifier, starting at arbitrary position
343+
string = "THIS IS BEFORE \"IDENTIFIER\"";
344+
expected = "";
345+
builder = new StringBuilder();
346+
start = 14;
347+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
348+
assertThat(retrieved).isEqualTo(string.length());
349+
assertThat(builder.toString()).isEqualTo(expected);
350+
351+
// Only the not-quoted string, and its size, is returned, starting at arbitrary position
352+
string = "THIS IS BEFORE IDENTIFIER \"";
353+
expected = "IDENTIFIER";
354+
builder = new StringBuilder();
355+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
356+
assertThat(retrieved).isEqualTo(25); // it returns the index where the identifier ends
357+
assertThat(builder.toString()).isEqualTo(expected);
358+
359+
string = "IDENTIFIER \"the_identifier";
360+
expected = "";
361+
builder = new StringBuilder();
362+
start = 10;
363+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
364+
assertThat(retrieved).isEqualTo(string.length()); // it returns the index where the identifier ends
365+
assertThat(builder.toString()).isEqualTo(expected);
366+
367+
string = "IDENTIFIER \"the_identifier";
368+
expected = "";
369+
builder = new StringBuilder();
370+
start = 10;
371+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
372+
assertThat(retrieved).isEqualTo(string.length()); // it returns the index where the identifier ends
373+
assertThat(builder.toString()).isEqualTo(expected);
374+
375+
string = "\"not an ' identifier\"";
376+
expected = "";
377+
builder = new StringBuilder();
378+
start = 0;
379+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
380+
assertThat(retrieved).isEqualTo(string.length()); // it returns the whole string length
381+
assertThat(builder.toString()).isEqualTo(expected);
382+
383+
string = "'not an \" identifier'";
384+
expected = "";
385+
builder = new StringBuilder();
386+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
387+
assertThat(retrieved).isEqualTo(string.length()); // it returns the whole string length
388+
assertThat(builder.toString()).isEqualTo(expected);
389+
390+
string = "'not an \" identifier\"'";
391+
expected = "";
392+
builder = new StringBuilder();
393+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
394+
assertThat(retrieved).isEqualTo(string.length()); // it returns the whole string length
395+
assertThat(builder.toString()).isEqualTo(expected);
396+
397+
string = "\"an \" IDENTIFIER";
398+
expected = "IDENTIFIER";
399+
builder = new StringBuilder();
400+
retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
401+
assertThat(retrieved).isEqualTo(string.length()); // it returns the index where the identifier ends
402+
assertThat(builder.toString()).isEqualTo(expected);
403+
404+
}
405+
301406
@Test
302407
public void testSplitStatements() {
303408
String text =

0 commit comments

Comments
 (0)