169 lines
5.5 KiB
Java
169 lines
5.5 KiB
Java
package net.sf.jasperreports.engine.util;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.StringTokenizer;
|
|
import net.sf.jasperreports.engine.JRQueryChunk;
|
|
import net.sf.jasperreports.engine.JRRuntimeException;
|
|
|
|
public class JRQueryParser {
|
|
private static final JRQueryParser singleton = new JRQueryParser();
|
|
|
|
public static JRQueryParser instance() {
|
|
return singleton;
|
|
}
|
|
|
|
public void parse(String text, JRQueryChunkHandler chunkHandler) {
|
|
if (text != null) {
|
|
StringBuffer textChunk = new StringBuffer();
|
|
StringTokenizer tkzer = new StringTokenizer(text, "$", true);
|
|
boolean wasDelim = false;
|
|
while (tkzer.hasMoreTokens()) {
|
|
String token = tkzer.nextToken();
|
|
if (token.equals("$")) {
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
wasDelim = true;
|
|
continue;
|
|
}
|
|
if (token.startsWith("P{") && wasDelim) {
|
|
int end = token.indexOf('}');
|
|
if (end > 0) {
|
|
if (textChunk.length() > 0)
|
|
chunkHandler.handleTextChunk(textChunk.toString());
|
|
String parameterChunk = token.substring(2, end);
|
|
chunkHandler.handleParameterChunk(parameterChunk);
|
|
textChunk = new StringBuffer(token.substring(end + 1));
|
|
} else {
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
textChunk.append(token);
|
|
}
|
|
} else if (token.startsWith("P!{") && wasDelim) {
|
|
int end = token.indexOf('}');
|
|
if (end > 0) {
|
|
if (textChunk.length() > 0)
|
|
chunkHandler.handleTextChunk(textChunk.toString());
|
|
String parameterClauseChunk = token.substring(3, end);
|
|
chunkHandler.handleParameterClauseChunk(parameterClauseChunk);
|
|
textChunk = new StringBuffer(token.substring(end + 1));
|
|
} else {
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
textChunk.append(token);
|
|
}
|
|
} else if (token.startsWith("X{") && wasDelim) {
|
|
int end = token.indexOf('}');
|
|
if (end > 0) {
|
|
if (textChunk.length() > 0)
|
|
chunkHandler.handleTextChunk(textChunk.toString());
|
|
String clauseChunk = token.substring(2, end);
|
|
String[] tokens = parseClause(clauseChunk);
|
|
chunkHandler.handleClauseChunk(tokens);
|
|
textChunk = new StringBuffer(token.substring(end + 1));
|
|
} else {
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
textChunk.append(token);
|
|
}
|
|
} else {
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
textChunk.append(token);
|
|
}
|
|
wasDelim = false;
|
|
}
|
|
if (wasDelim)
|
|
textChunk.append("$");
|
|
if (textChunk.length() > 0)
|
|
chunkHandler.handleTextChunk(textChunk.toString());
|
|
}
|
|
}
|
|
|
|
protected String[] parseClause(String clauseChunk) {
|
|
List tokens = new ArrayList();
|
|
boolean wasClauseToken = false;
|
|
String separator = determineClauseTokenSeparator(clauseChunk);
|
|
StringTokenizer tokenizer = new StringTokenizer(clauseChunk, separator, true);
|
|
while (tokenizer.hasMoreTokens()) {
|
|
String token = tokenizer.nextToken();
|
|
if (token.equals(separator)) {
|
|
if (!wasClauseToken)
|
|
tokens.add("");
|
|
wasClauseToken = false;
|
|
continue;
|
|
}
|
|
tokens.add(token);
|
|
wasClauseToken = true;
|
|
}
|
|
if (!wasClauseToken)
|
|
tokens.add("");
|
|
return tokens.<String>toArray(new String[tokens.size()]);
|
|
}
|
|
|
|
protected String determineClauseTokenSeparator(String clauseChunk) {
|
|
String allSeparators = getTokenSeparators();
|
|
if (allSeparators == null || allSeparators.length() == 0)
|
|
throw new JRRuntimeException("No token separators configured");
|
|
int firstSepIdx = 0;
|
|
int clauseLenght = clauseChunk.length();
|
|
for (int idx = 0; idx < clauseLenght; idx++) {
|
|
int sepIdx = allSeparators.indexOf(clauseChunk.charAt(idx));
|
|
if (sepIdx >= 0) {
|
|
firstSepIdx = sepIdx;
|
|
break;
|
|
}
|
|
}
|
|
return String.valueOf(allSeparators.charAt(firstSepIdx));
|
|
}
|
|
|
|
protected String getTokenSeparators() {
|
|
return JRProperties.getProperty("net.sf.jasperreports.query.chunk.token.separators");
|
|
}
|
|
|
|
public String asText(JRQueryChunk[] chunks) {
|
|
String text = "";
|
|
if (chunks != null && chunks.length > 0) {
|
|
StringBuffer sbuffer = new StringBuffer();
|
|
for (int i = 0; i < chunks.length; i++) {
|
|
JRQueryChunk queryChunk = chunks[i];
|
|
switch (queryChunk.getType()) {
|
|
case 2:
|
|
sbuffer.append("$P{");
|
|
sbuffer.append(queryChunk.getText());
|
|
sbuffer.append("}");
|
|
break;
|
|
case 3:
|
|
sbuffer.append("$P!{");
|
|
sbuffer.append(queryChunk.getText());
|
|
sbuffer.append("}");
|
|
break;
|
|
case 4:
|
|
sbuffer.append("$X{");
|
|
sbuffer.append(queryChunk.getText());
|
|
sbuffer.append("}");
|
|
break;
|
|
default:
|
|
sbuffer.append(queryChunk.getText());
|
|
break;
|
|
}
|
|
}
|
|
text = sbuffer.toString();
|
|
}
|
|
return text;
|
|
}
|
|
|
|
public String asClauseText(String[] tokens) {
|
|
StringBuffer sb = new StringBuffer();
|
|
if (tokens != null && tokens.length > 0)
|
|
for (int i = 0; i < tokens.length; i++) {
|
|
if (i > 0)
|
|
sb.append(',');
|
|
String token = tokens[i];
|
|
if (token != null)
|
|
sb.append(token);
|
|
}
|
|
return sb.toString();
|
|
}
|
|
}
|