package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueString; class RegexNodeValue extends NodeValueString { private final boolean wildcard; private RegexNodeValue(final String str, final boolean wildcard) { super(str); this.wildcard = wildcard; } public boolean isWildcard() { return wildcard; } private final static String SLASH = "\\"; private final static String PATTERN = "[]^.?*+{}()|$_%" + SLASH; private final static Map<String, String> CONVERSION = new HashMap<String, String>(); static { for (int i = 0; i < PATTERN.length(); i++) { final String s = PATTERN.substring(i, i + 1); CONVERSION.put(s, SLASH + s); } CONVERSION.put("_", "."); CONVERSION.put("%", "(.+)"); } public static RegexNodeValue create(final String part) { final StringTokenizer tokenizer = new StringTokenizer(part, PATTERN, true); final StringBuilder sb = new StringBuilder().append("^"); final StringBuilder plainSb = new StringBuilder(); final StringBuilder workingToken = new StringBuilder(); int backslashCount = 0; int wildcard = 0; int escaping = 0; while (tokenizer.hasMoreTokens()) { final String candidate = tokenizer.nextToken(); plainSb.append(candidate); if ((candidate.length() == 1) && CONVERSION.keySet().contains(candidate)) { // token // an even number of backslashes means that we are just creating // backslashes. if ((backslashCount > 0) && ((backslashCount % 2) != 0)) { if (candidate.equals("%") || candidate.equals("_")) { sb.setCharAt(sb.length() - 2, candidate.charAt(0)); sb.setLength(sb.length() - 1); plainSb.setCharAt(sb.length() - 2, candidate.charAt(0)); plainSb.setLength(sb.length() - 1); escaping--; } else if (candidate.equals(SLASH)) { sb.append(CONVERSION.get(candidate)); escaping++; } else { sb.append(candidate); } } else { sb.append( workingToken.length() > 0 ? workingToken.toString() : "").append(CONVERSION.get(candidate)); escaping++; if (candidate.equals("%") || candidate.equals("_")) { wildcard++; } } if (candidate.equals(SLASH)) { backslashCount++; } else { backslashCount = 0; } workingToken.setLength(0); } else { workingToken.append(candidate); backslashCount = 0; } } // end of while if (workingToken.length() > 0) { sb.append(workingToken.toString()); } sb.append("$"); return new RegexNodeValue( (escaping > 0) && (wildcard > 0) ? sb.toString() : plainSb.toString(), wildcard > 0); } }