GitLab Mirror pushed to branch 2.12 at cms-community / hippo-jackrabbit
Commits: 944e7e45 by Julian Reschke at 2016-11-25T11:28:25+00:00 JCR-4042: Adding Escape Character in GQL Adding support for escape sequence. Escape sequence character is backslash. Only double-quotes (as \"), backslash (as \\) and colon (as \:) characters can be escaped (ported to 2.12) git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/branches/2.12@1771290 13f79535-47bb-0310-9956-ffa450edef68 - - - - - 2 changed files: - jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/query/GQL.java - jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/query/GQLTest.java Changes: ===================================== jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/query/GQL.java ===================================== --- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/query/GQL.java +++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/query/GQL.java @@ -94,6 +94,12 @@ import org.apache.jackrabbit.util.Text; * property name and the value. This also means that a value that contains * a colon does not need to be enclosed in double quotes. * <p> + * <b>Escaping</b> + * <p> + * To imply double-quotes("), backslash(\), and colon(:) literally you can + * escape them with a backslash. E.g. similar to example above in quoting for colon, + * <code>"jcr:title":apache</code> is equiavalent to jcr\:title:apache. + * <p> * <b>Auto prefixes</b> * <p> * When a property, node or node type name does not have a namespace prefix GQL @@ -717,6 +723,7 @@ public final class GQL { StringBuffer property = new StringBuffer(); StringBuffer value = new StringBuffer(); boolean quoted = false; + boolean escaped = false; boolean optional = false; for (char c : stmt) { switch (c) { @@ -739,7 +746,7 @@ public final class GQL { } break; case ':': - if (quoted) { + if (quoted || escaped) { value.append(c); } else { if (property.length() == 0) { @@ -753,7 +760,17 @@ public final class GQL { } break; case '"': - quoted = !quoted; + if (escaped) { + value.append(c); + } else { + quoted = !quoted; + } + break; + case '\\': + if (escaped) { + value.append(c); + } + escaped = !escaped; break; // noise case '*': @@ -770,11 +787,13 @@ public final class GQL { case '{': case '}': case '!': - case '\\': break; default: value.append(c); } + if (c != '\\') { + escaped = false; + } } } ===================================== jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/query/GQLTest.java ===================================== --- a/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/query/GQLTest.java +++ b/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/query/GQLTest.java @@ -41,4 +41,54 @@ public class GQLTest extends TestCase { } + public void testEscaping() throws RepositoryException { + //simple things work + assertEquals("//*[jcr:contains(assets/@a, 'b')] order by @jcr:score descending", + GQL.translateToXPath("a:b", null, "assets")); + + //backslash is ignored (same as earlier) and only ", \ and : are escaped + assertEquals("//*[jcr:contains(assets/@a, 'b')] order by @jcr:score descending", + GQL.translateToXPath("a:b\\", null, "assets")); + assertEquals("//*[jcr:contains(assets, 'ab')] order by @jcr:score descending", + GQL.translateToXPath("a\\b", null, "assets")); + assertEquals("//*[jcr:contains(assets/@a, 'b')] order by @jcr:score descending", + GQL.translateToXPath("a:\\b", null, "assets")); + + //backward compatibility of quoted ":" + assertEquals("//*[jcr:contains(assets/@a, '1:1')] order by @jcr:score descending", + GQL.translateToXPath("a:\"1:1\"", null, "assets")); + + //escaping ":" + assertEquals("//*[jcr:contains(assets/@a, '1:1')] order by @jcr:score descending", + GQL.translateToXPath("a:\"1\\:1\"", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a, '1:1')] order by @jcr:score descending", + GQL.translateToXPath("a:1\\:1", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a:, '1')] order by @jcr:score descending", + GQL.translateToXPath("a\\::1", null, "assets")); + + //escaping \ + assertEquals("//*[jcr:contains(assets/@a, '1\\1')] order by @jcr:score descending", + GQL.translateToXPath("a:\"1\\\\1\"", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a, '1\\1')] order by @jcr:score descending", + GQL.translateToXPath("a:1\\\\1", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a_x005c_, '1')] order by @jcr:score descending", + GQL.translateToXPath("a\\\\:1", null, "assets")); + + + //escaping " + assertEquals("//*[jcr:contains(assets/@a, '1\"1')] order by @jcr:score descending", + GQL.translateToXPath("a:\"1\\\"1\"", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a, '1\"1')] order by @jcr:score descending", + GQL.translateToXPath("a:1\\\"1", null, "assets")); + + assertEquals("//*[jcr:contains(assets/@a_x0022_, '1')] order by @jcr:score descending", + GQL.translateToXPath("a\\\":1", null, "assets")); + + } + } View it on GitLab: https://code.onehippo.org/cms-community/hippo-jackrabbit/commit/944e7e4588e0251675f5b52b343f469811c93507
_______________________________________________ Hippocms-svn mailing list Hippocms-svn@lists.onehippo.org https://lists.onehippo.org/mailman/listinfo/hippocms-svn