Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,68 @@ private String parseValue(String encodedJobParameter) {
if (tokens.length == 0) {
return "";
}
return tokens[0];
if (tokens.length == 1) {
return tokens[0];
}
// For 2+ tokens, figure out which part is the type
int typeIndex = -1;
if (tokens.length == 2) {
// Could be: value,type OR value,value (both parts of value)
if (looksLikeClassName(tokens[1])) {
typeIndex = 1;
}
}
else if (tokens.length >= 3) {
// Could be: value,type,identifying OR value,value,value (all parts of value)
// Check if second-to-last looks like a class
if (looksLikeClassName(tokens[tokens.length - 2])) {
typeIndex = tokens.length - 2;
}
}

if (typeIndex == -1) {
// No valid type found, all commas are part of the value
return encodedJobParameter;
}

// Reconstruct value from all tokens before the type
StringBuilder value = new StringBuilder(tokens[0]);
for (int i = 1; i < typeIndex; i++) {
value.append(",").append(tokens[i]);
}
return value.toString();
}

private Class<?> parseType(String encodedJobParameter) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(encodedJobParameter);
if (tokens.length <= 1) {
return String.class;
}
// For 2+ tokens, figure out which part is the type
int typeIndex = -1;
if (tokens.length == 2) {
// Could be: value,type OR value,value (both parts of value)
if (looksLikeClassName(tokens[1])) {
typeIndex = 1;
}
}
else if (tokens.length >= 3) {
// Could be: value,type,identifying OR value,value,value (all parts of value)
// Check if second-to-last looks like a class
if (looksLikeClassName(tokens[tokens.length - 2])) {
typeIndex = tokens.length - 2;
}
}

if (typeIndex == -1) {
return String.class;
}

try {
Class<?> type = Class.forName(tokens[1]);
return type;
return Class.forName(tokens[typeIndex]);
}
catch (ClassNotFoundException e) {
throw new JobParametersConversionException("Unable to parse job parameter " + encodedJobParameter, e);
return String.class;
}
}

Expand All @@ -197,7 +245,35 @@ private boolean parseIdentifying(String encodedJobParameter) {
if (tokens.length <= 2) {
return true;
}
return Boolean.parseBoolean(tokens[2]);
// Check if the last token is a boolean (identifying flag)
String lastToken = tokens[tokens.length - 1];
if ("true".equalsIgnoreCase(lastToken) || "false".equalsIgnoreCase(lastToken)) {
// And the second-to-last token looks like a class name
String potentialType = tokens[tokens.length - 2];
if (looksLikeClassName(potentialType)) {
return Boolean.parseBoolean(lastToken);
}
}
return true;
}

/**
* Simple heuristic to check if a string looks like a class name. Class names
* typically contain dots (package names) or are primitive types.
*/
private boolean looksLikeClassName(String className) {
if (className.isEmpty()) {
return false;
}
// Check for primitive types
if (className.matches("^(int|long|double|float|boolean|char|byte|short|void)$")) {
return true;
}
// Check for fully qualified class name (contains dots)
if (className.contains(".")) {
return true;
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,26 @@ void testRoundTripWithOffsetDateTime() {
props.getProperty("schedule.offsetDateTime"));
}

@Test
void testValueWithComma() {
// Test that values containing commas are handled correctly
String[] args = new String[] { "items=apple,banana,orange" };

JobParameters parameters = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
assertEquals("apple,banana,orange", parameters.getString("items"));
}

@Test
void testValueWithCommaRoundTrip() {
// Test round-trip encoding/decoding of values with commas
JobParametersBuilder builder = new JobParametersBuilder();
builder.addString("items", "apple,banana,orange");
JobParameters originalParameters = builder.toJobParameters();

Properties props = factory.getProperties(originalParameters);
JobParameters decodedParameters = factory.getJobParameters(props);

assertEquals("apple,banana,orange", decodedParameters.getString("items"));
}

}