List<Expression> nonTextValues = Lists.newArrayList();
{
SourcePosition sbPos = null;
for (Expression value : values) {
if (value instanceof StringConstant) {
StringConstant stringConstant = (StringConstant) value;
sb.append(stringConstant.evaluate());
if (sbPos == null) {
sbPos = stringConstant.getSourcePosition();
}
} else {
textSegments.add(sb.toString());
sb.setLength(0);
textPositions.add(sbPos);
sbPos = null;
nonTextValues.add(value);
}
}
textSegments.add(sb.toString());
textPositions.add(sbPos);
}
List<Expression> result = Lists.newArrayList();
SpaceOperator interiorSpaceOperator =
spaceOperators.getInteriorSpaceOperator();
SpaceOperator exteriorSpaceOperator =
spaceOperators.getExteriorSpaceOperator();
int textSegmentCount = textSegments.size();
if (textSegmentCount > 0) {
// pull off leading spaces
Matcher m = LEADING_SPACES.matcher(textSegments.get(0));
String leadingSpaces = "";
if (m.matches()) {
leadingSpaces = exteriorSpaceOperator.apply(m.group(1));
textSegments.set(0, m.group(2));
}
// pull off trailing spaces
m = TRAILING_SPACES.matcher(textSegments.get(textSegmentCount - 1));
String trailingSpaces = "";
if (m.matches()) {
trailingSpaces = exteriorSpaceOperator.apply(m.group(2));
textSegments.set(textSegmentCount - 1, m.group(1));
}
// process interior spaces
for (int i = 0; i < textSegmentCount; i++) {
String text = textSegments.get(i);
if (text.length() > 0) {
sb.setLength(0);
m = SPACES.matcher(text);
int start = 0;
while (true) {
if (m.find(start)) {
sb.append(text, start, m.start());
start = m.end();
sb.append(interiorSpaceOperator.apply(m.group()));
} else {
sb.append(text, start, text.length());
break;
}
}
textSegments.set(i, sb.toString());
}
}
// re-attach leading and trailing spaces
textSegments.set(0, leadingSpaces + textSegments.get(0));
textSegments.set(textSegmentCount - 1,
textSegments.get(textSegmentCount - 1)
+ trailingSpaces);
for (int i = 0; i < textSegmentCount; i++) {
String text = textSegments.get(i);
if (text.length() > 0) {
result.add(new StringConstant(textPositions.get(i), schema, text));
}
if (i < (textSegmentCount - 1)) {
result.add(nonTextValues.get(i));
}
}