From 59d0a5262bcd64b577cbdf815e530a3fdc67dac7 Mon Sep 17 00:00:00 2001 From: Heath Thomann Date: Wed, 4 Jan 2012 22:29:38 +0000 Subject: [PATCH] OPENJPA-2102: Added code to compare decoded URLs in AbstractCFMetaDataFactory. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1227364 13f79535-47bb-0310-9956-ffa450edef68 --- .../meta/AbstractCFMetaDataFactory.java | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java index da42de841..fe10b3abb 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java @@ -787,7 +787,8 @@ public abstract class AbstractCFMetaDataFactory if (log.isTraceEnabled()) log.trace(_loc.get("resource-url", urlString)); if (peMap != null) { - if (puUrlString != null && urlString.indexOf(puUrlString) != -1) + //OPENJPA-2102: decode the URL to remove such things a spaces (' ') encoded as '%20' + if (puUrlString != null && decode(urlString).indexOf(decode(puUrlString)) != -1) urls.add(url); if (mappingFileNames != null && mappingFileNames.size() != 0) { for (String mappingFileName : mappingFileNames) { @@ -865,6 +866,66 @@ public abstract class AbstractCFMetaDataFactory names.addAll(newNames); } } + + /** + * Decodes a URL-encoded path string. For example, an encoded + * space (%20) is decoded into a normal space (' ') character. + * Added via OPENJPA-2102. + * @param String encoded - the encoded URL string + * @return String decoded - the decoded string. + */ + public static String decode(String s) { + if (s == null) { + return null; + } + + int i = s.indexOf('%'); + if (i == -1) { + return s; + } + + StringBuilder builder = new StringBuilder(); + int begin = 0; + + do { + builder.append(s, begin, i); + begin = i + 3; + + char ch = (char) Integer.parseInt(s.substring(i + 1, begin), 16); + + if ((ch & 0x80) != 0) { + // Decode "modified UTF-8". + + if (s.charAt(begin++) != '%') { + throw new IllegalArgumentException(); + } + + char ch2 = (char) Integer.parseInt(s.substring(begin, begin + 2), 16); + begin += 2; + + if ((ch & 0xe0) == 0xc0) { + ch = (char) (((ch & 0x1f) << 6) | (ch2 & 0x3f)); + } else if ((ch & 0xf0) == 0xe0) { + if (s.charAt(begin++) != '%') { + throw new IllegalArgumentException(); + } + + char ch3 = (char) Integer.parseInt(s.substring(begin, begin + 2), 16); + begin += 2; + + ch = (char) (((ch & 0x0f) << 12) | ((ch2 & 0x3f) << 6) | (ch3 & 0x3f)); + } else { + throw new IllegalArgumentException(); + } + } + + builder.append(ch); + } while ((i = s.indexOf('%', begin)) != -1); + + builder.append(s, begin, s.length()); + + return builder.toString(); + } /** * Implement this method to map metadata resources to the persistent