You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/06/11 00:41:55 UTC

incubator-juneau git commit: Add new PartParser interface.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master f57ec350f -> e92a7f6e3


Add new PartParser interface.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/e92a7f6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/e92a7f6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/e92a7f6e

Branch: refs/heads/master
Commit: e92a7f6e39170ba23ca6702075b68aec23d4cc63
Parents: f57ec35
Author: JamesBognar <ja...@apache.org>
Authored: Sat Jun 10 20:41:52 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Sat Jun 10 20:41:52 2017 -0400

----------------------------------------------------------------------
 .../urlencoding/UrlEncodingParserTest.java      | 113 ++++++++++---------
 .../urlencoding/UrlEncodingSerializerTest.java  |   2 +-
 .../main/java/org/apache/juneau/PartType.java   |  35 ++++++
 .../main/java/org/apache/juneau/dto/Link.java   |   2 +-
 .../org/apache/juneau/parser/PartParser.java    |  41 +++++++
 .../juneau/serializer/PartSerializer.java       |   1 +
 .../org/apache/juneau/serializer/PartType.java  |  31 -----
 .../juneau/urlencoding/UrlEncodingParser.java   |  46 +-------
 .../rest/client/SerializedNameValuePair.java    |   1 +
 .../juneau/rest/test/RequestBeanProxyTest.java  |   1 +
 .../juneau/rest/test/ThirdPartyProxyTest.java   |   1 +
 .../org/apache/juneau/rest/RequestFormData.java |   2 +-
 .../org/apache/juneau/rest/RequestHeaders.java  |   3 +-
 .../apache/juneau/rest/RequestPathMatch.java    |   2 +-
 .../org/apache/juneau/rest/RequestQuery.java    |   2 +-
 .../org/apache/juneau/rest/RestResponse.java    |   5 +-
 16 files changed, 150 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
index 3ae3679..1ad27b4 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
@@ -25,6 +25,7 @@ import org.junit.*;
 public class UrlEncodingParserTest {
 
 	static UrlEncodingParser p = UrlEncodingParser.DEFAULT;
+	static BeanSession bs = p.getBeanContext().createSession();
 
 	//====================================================================================================
 	// Basic test
@@ -48,13 +49,13 @@ public class UrlEncodingParserTest {
 		assertEquals("a", p.parse(t, String.class));
 
 		t = "a";
-		assertEquals("a", p.parsePart(t, Object.class));
-		assertEquals("a", p.parsePart(t, String.class));
+		assertEquals("a", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("a", p.parse(PartType.HEADER, t, bs.string()));
 		t = "'a'";
-		assertEquals("a", p.parsePart(t, String.class));
-		assertEquals("a", p.parsePart(t, Object.class));
+		assertEquals("a", p.parse(PartType.HEADER, t, bs.string()));
+		assertEquals("a", p.parse(PartType.HEADER, t, bs.object()));
 		t = " 'a' ";
-		assertEquals("a", p.parsePart(t, String.class));
+		assertEquals("a", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?a=a";
@@ -74,7 +75,7 @@ public class UrlEncodingParserTest {
 		assertNull(m.get("f"));
 
 		t = "(a=b,c=123,d=false,e=true,f=%00)";
-		m = p.parsePart(t, Map.class);
+		m = p.parse(PartType.HEADER, t, bs.getClassMeta(Map.class));
 		assertEquals("b", m.get("a"));
 		assertTrue(m.get("c") instanceof Number);
 		assertEquals(123, m.get("c"));
@@ -85,7 +86,7 @@ public class UrlEncodingParserTest {
 		assertEquals("%00", m.get("f"));
 
 		t = "(a=b,c=123,d=false,e=true,f=null)";
-		m = p.parsePart(t, Map.class);
+		m = p.parse(PartType.HEADER, t, bs.getClassMeta(Map.class));
 		assertTrue(m.containsKey("f"));
 		assertNull(m.get("f"));
 
@@ -99,7 +100,7 @@ public class UrlEncodingParserTest {
 		t = "_value=null";
 		assertNull(p.parse(t, Object.class));
 		t = "null";
-		assertNull(p.parsePart(t, Object.class));
+		assertNull(p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?null=null";
@@ -121,10 +122,10 @@ public class UrlEncodingParserTest {
 		// Empty array
 		// Top level
 		t = "@()";
-		l = (List)p.parsePart(t, Object.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.object());
 		assertTrue(l.isEmpty());
 		t = " @( ) ";
-		l = p.parsePart(t, List.class);
+		l = p.parse(PartType.HEADER, t, bs.getClassMeta(List.class));
 		assertTrue(l.isEmpty());
 
 		// 2nd level in map
@@ -152,12 +153,12 @@ public class UrlEncodingParserTest {
 		l = (List)l.get(0);
 		assertTrue(l.isEmpty());
 		t = "@(@())";
-		l = (List)p.parsePart(t, Object.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.object());
 		assertTrue(l.size() == 1);
 		l = (List)l.get(0);
 		assertTrue(l.isEmpty());
 		t = "@(@())";
-		l = (List)p.parsePart(t, LinkedList.class, List.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.getClassMeta(LinkedList.class, List.class));
 		assertTrue(l.size() == 1);
 		l = (List)l.get(0);
 		assertTrue(l.isEmpty());
@@ -173,11 +174,11 @@ public class UrlEncodingParserTest {
 		assertTrue(l.size() == 1);
 		assertEquals("", l.get(0));
 		t = "@('')";
-		l = (List)p.parsePart(t, Object.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.object());
 		assertTrue(l.size() == 1);
 		assertEquals("", l.get(0));
 		t = "@('')";
-		l = (List)p.parsePart(t, List.class, String.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.getClassMeta(List.class, String.class));
 		assertTrue(l.size() == 1);
 		assertEquals("", l.get(0));
 
@@ -203,13 +204,13 @@ public class UrlEncodingParserTest {
 		assertEquals("", l.get(1));
 		assertEquals("", l.get(2));
 		t = "@('','','')";
-		l = (List)p.parsePart(t, Object.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.object());
 		assertTrue(l.size() == 3);
 		assertEquals("", l.get(0));
 		assertEquals("", l.get(1));
 		assertEquals("", l.get(2));
 		t = "@('','','')";
-		l = (List)p.parsePart(t, List.class, Object.class);
+		l = (List)p.parse(PartType.HEADER, t, bs.getClassMeta(List.class, Object.class));
 		assertTrue(l.size() == 3);
 		assertEquals("", l.get(0));
 		assertEquals("", l.get(1));
@@ -223,10 +224,10 @@ public class UrlEncodingParserTest {
 		assertEquals("\u0000", p.parse(t, String.class));
 		assertEquals("\u0000", p.parse(t, Object.class));
 		t = "'\u0000'";
-		assertEquals("\u0000", p.parsePart(t, Object.class));
+		assertEquals("\u0000", p.parse(PartType.HEADER, t, bs.object()));
 		t = "'\u0000'";
-		assertEquals("\u0000", p.parsePart(t, String.class));
-		assertEquals("\u0000", p.parsePart(t, Object.class));
+		assertEquals("\u0000", p.parse(PartType.HEADER, t, bs.string()));
+		assertEquals("\u0000", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?'\u0000'='\u0000'";
@@ -248,12 +249,12 @@ public class UrlEncodingParserTest {
 		b = p.parse(t, Boolean.class);
 		assertEquals(Boolean.FALSE, b);
 		t = "false";
-		b = (Boolean)p.parsePart(t, Object.class);
+		b = (Boolean)p.parse(PartType.HEADER, t, bs.object());
 		assertEquals(Boolean.FALSE, b);
-		b = p.parsePart(t, Boolean.class);
+		b = p.parse(PartType.HEADER, t, bs.getClassMeta(Boolean.class));
 		assertEquals(Boolean.FALSE, b);
 		t = "false";
-		b = p.parsePart(t, Boolean.class);
+		b = p.parse(PartType.HEADER, t, bs.getClassMeta(Boolean.class));
 		assertEquals(Boolean.FALSE, b);
 
 		// 2nd level
@@ -279,16 +280,16 @@ public class UrlEncodingParserTest {
 		i = p.parse(t, Integer.class);
 		assertEquals(123, i.intValue());
 		t = "123";
-		i = (Integer)p.parsePart(t, Object.class);
+		i = (Integer)p.parse(PartType.HEADER, t, bs.object());
 		assertEquals(123, i.intValue());
-		i = p.parsePart(t, Integer.class);
+		i = p.parse(PartType.HEADER, t, bs.getClassMeta(Integer.class));
 		assertEquals(123, i.intValue());
-		d = p.parsePart(t, Double.class);
+		d = p.parse(PartType.HEADER, t, bs.getClassMeta(Double.class));
 		assertEquals(123, d.intValue());
-		f = p.parsePart(t, Float.class);
+		f = p.parse(PartType.HEADER, t, bs.getClassMeta(Float.class));
 		assertEquals(123, f.intValue());
 		t = "123";
-		i = p.parsePart(t, Integer.class);
+		i = p.parse(PartType.HEADER, t, bs.getClassMeta(Integer.class));
 		assertEquals(123, i.intValue());
 
 		// 2nd level
@@ -303,7 +304,7 @@ public class UrlEncodingParserTest {
 		t = "_value=x;/?:@-_.!*'";
 		assertEquals("x;/?:@-_.!*'", p.parse(t, Object.class));
 		t = "x;/?:@-_.!*'";
-		assertEquals("x;/?:@-_.!*'", p.parsePart(t, Object.class));
+		assertEquals("x;/?:@-_.!*'", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?x;/?:@-_.!*'=x;/?:@-_.!*'";
@@ -327,10 +328,10 @@ public class UrlEncodingParserTest {
 		assertEquals("x{}|\\^[]`<>#%\"&+", p.parse(t, Object.class));
 		assertEquals("x{}|\\^[]`<>#%\"&+", p.parse(t, String.class));
 		t = "x{}|\\^[]`<>#%\"&+";
-		assertEquals("x{}|\\^[]`<>#%\"&+", p.parsePart(t, Object.class));
+		assertEquals("x{}|\\^[]`<>#%\"&+", p.parse(PartType.HEADER, t, bs.object()));
 		t = "x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B";
-		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", p.parsePart(t, Object.class));
-		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", p.parsePart(t, String.class));
+		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?x{}|\\^[]`<>#%\"&+=x{}|\\^[]`<>#%\"&+";
@@ -350,11 +351,11 @@ public class UrlEncodingParserTest {
 		t = "_value='x$,()'";
 		assertEquals("x$,()", p.parse(t, Object.class));
 		t = "'x$,()'";
-		assertEquals("x$,()", p.parsePart(t, Object.class));
+		assertEquals("x$,()", p.parse(PartType.HEADER, t, bs.object()));
 		t = "_value='x~~$~~,~~(~~)'";
 		assertEquals("x~$~,~(~)", p.parse(t, Object.class));
 		t = "'x~~$~~,~~(~~)'";
-		assertEquals("x~$~,~(~)", p.parsePart(t, Object.class));
+		assertEquals("x~$~,~(~)", p.parse(PartType.HEADER, t, bs.object()));
 
 		// At secondary levels, these characters are escaped and not encoded.
 		// 2nd level
@@ -373,9 +374,9 @@ public class UrlEncodingParserTest {
 		t = "_value='x%3D'";
 		assertEquals("x=", p.parse(t, Object.class));
 		t = "'x='";
-		assertEquals("x=", p.parsePart(t, Object.class));
+		assertEquals("x=", p.parse(PartType.HEADER, t, bs.object()));
 		t = "'x%3D'";
-		assertEquals("x%3D", p.parsePart(t, Object.class));
+		assertEquals("x%3D", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?'x%3D'='x%3D'";
@@ -394,8 +395,8 @@ public class UrlEncodingParserTest {
 		assertEquals("()", p.parse(t, Object.class));
 		assertEquals("()", p.parse(t, String.class));
 		t = "'()'";
-		assertEquals("()", p.parsePart(t, Object.class));
-		assertEquals("()", p.parsePart(t, String.class));
+		assertEquals("()", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("()", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?'()'='()'";
@@ -412,9 +413,9 @@ public class UrlEncodingParserTest {
 		t = "_value=$a";
 		assertEquals("$a", p.parse(t, Object.class));
 		t = "$a";
-		assertEquals("$a", p.parsePart(t, Object.class));
+		assertEquals("$a", p.parse(PartType.HEADER, t, bs.object()));
 		t = "$a";
-		assertEquals("$a", p.parsePart(t, Object.class));
+		assertEquals("$a", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?$a=$a";
@@ -428,7 +429,7 @@ public class UrlEncodingParserTest {
 		t = "_value=";
 		assertEquals("", p.parse(t, Object.class));
 		t = "";
-		assertEquals("", p.parsePart(t, Object.class));
+		assertEquals("", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?=";
@@ -450,9 +451,9 @@ public class UrlEncodingParserTest {
 		t = "_value='%0A'";
 		assertEquals("\n", p.parse(t, Object.class));
 		t = "'%0A'";
-		assertEquals("%0A", p.parsePart(t, Object.class));
+		assertEquals("%0A", p.parse(PartType.HEADER, t, bs.object()));
 		t = "'\n'";
-		assertEquals("\n", p.parsePart(t, Object.class));
+		assertEquals("\n", p.parse(PartType.HEADER, t, bs.object()));
 
 		// 2nd level
 		t = "?'%0A'='%0A'";
@@ -482,11 +483,11 @@ public class UrlEncodingParserTest {
 		assertEquals("¢", p.parse(t, Object.class));
 		assertEquals("¢", p.parse(t, String.class));
 		t = "¢";
-		assertEquals("¢", p.parsePart(t, Object.class));
-		assertEquals("¢", p.parsePart(t, String.class));
+		assertEquals("¢", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("¢", p.parse(PartType.HEADER, t, bs.string()));
 		t = "%C2%A2";
-		assertEquals("%C2%A2", p.parsePart(t, Object.class));
-		assertEquals("%C2%A2", p.parsePart(t, String.class));
+		assertEquals("%C2%A2", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("%C2%A2", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?%C2%A2=%C2%A2";
@@ -507,11 +508,11 @@ public class UrlEncodingParserTest {
 		assertEquals("€", p.parse(t, Object.class));
 		assertEquals("€", p.parse(t, String.class));
 		t = "€";
-		assertEquals("€", p.parsePart(t, Object.class));
-		assertEquals("€", p.parsePart(t, String.class));
+		assertEquals("€", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("€", p.parse(PartType.HEADER, t, bs.string()));
 		t = "%E2%82%AC";
-		assertEquals("%E2%82%AC", p.parsePart(t, Object.class));
-		assertEquals("%E2%82%AC", p.parsePart(t, String.class));
+		assertEquals("%E2%82%AC", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("%E2%82%AC", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?%E2%82%AC=%E2%82%AC";
@@ -532,11 +533,11 @@ public class UrlEncodingParserTest {
 		assertEquals("𤭢", p.parse(t, Object.class));
 		assertEquals("𤭢", p.parse(t, String.class));
 		t = "𤭢";
-		assertEquals("𤭢", p.parsePart(t, Object.class));
-		assertEquals("𤭢", p.parsePart(t, String.class));
+		assertEquals("𤭢", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("𤭢", p.parse(PartType.HEADER, t, bs.string()));
 		t = "%F0%A4%AD%A2";
-		assertEquals("%F0%A4%AD%A2", p.parsePart(t, Object.class));
-		assertEquals("%F0%A4%AD%A2", p.parsePart(t, String.class));
+		assertEquals("%F0%A4%AD%A2", p.parse(PartType.HEADER, t, bs.object()));
+		assertEquals("%F0%A4%AD%A2", p.parse(PartType.HEADER, t, bs.string()));
 
 		// 2nd level
 		t = "?%F0%A4%AD%A2=%F0%A4%AD%A2";
@@ -563,12 +564,12 @@ public class UrlEncodingParserTest {
 		assertEquals(123, t.f2);
 
 		s = "(f1=foo,f2=123)";
-		t = p.parsePart(s, A.class);
+		t = p.parse(PartType.HEADER, s, bs.getClassMeta(A.class));
 		assertEquals("foo", t.f1);
 		assertEquals(123, t.f2);
 
 		s = "('f1'='foo','f2'=123)";
-		t = p.parsePart(s, A.class);
+		t = p.parse(PartType.HEADER, s, bs.getClassMeta(A.class));
 		assertEquals("foo", t.f1);
 		assertEquals(123, t.f2);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
index 07f3755..0872206 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
@@ -452,7 +452,7 @@ public class UrlEncodingSerializerTest {
 	public void testParseParameterObjectMap() throws Exception {
 		String in = "(name='foo bar')";
 		
-		ObjectMap r =  UrlEncodingParser.DEFAULT.parsePart(in, ObjectMap.class);
+		ObjectMap r =  UrlEncodingParser.DEFAULT.parse(PartType.QUERY, in, BeanContext.DEFAULT.createSession().getClassMeta(ObjectMap.class));
 	
 		assertEquals("{name:'foo bar'}", JsonSerializer.DEFAULT_LAX.toString(r));
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/PartType.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/PartType.java b/juneau-core/src/main/java/org/apache/juneau/PartType.java
new file mode 100644
index 0000000..2025179
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/PartType.java
@@ -0,0 +1,35 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Represents possible enum values that can be passed to the {@link PartSerializer#serialize(PartType, Object)}
+ * and {@link PartParser#parse(PartType, String, ClassMeta)} methods.
+ */
+public enum PartType {
+
+	/** A URI path variable */
+	PATH,
+
+	/** A URI query parameter */
+	QUERY,
+
+	/** A form-data parameter */
+	FORM_DATA,
+
+	/** An HTTP header */
+	HEADER
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/dto/Link.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/Link.java b/juneau-core/src/main/java/org/apache/juneau/dto/Link.java
index e1036c7..ce22d0d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/Link.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/Link.java
@@ -14,8 +14,8 @@ package org.apache.juneau.dto;
 
 import java.text.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.html.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.utils.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/parser/PartParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/PartParser.java b/juneau-core/src/main/java/org/apache/juneau/parser/PartParser.java
new file mode 100644
index 0000000..d50d62c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/PartParser.java
@@ -0,0 +1,41 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.parser;
+
+import org.apache.juneau.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Interface used to convert HTTP headers, query parameters, form-data parameters, and URI
+ * path variables to POJOs
+ * <p>
+ * By default, the {@link UrlEncodingParser} class implements this interface so that it can be used to parse
+ * these HTTP parts.
+ * However, the interface is provided to allow custom parsing of these objects by providing your own implementation
+ * class.
+ * <p>
+ * Implementations must include a no-arg constructor.
+ */
+public interface PartParser {
+
+	/**
+	 * Converts the specified input to the specified class type.
+	 *
+	 * @param partType The part type being parsed.
+	 * @param in The input being parsed.
+	 * @param type The category of value being parsed.
+	 * @return The parsed value.
+	 * @throws ParseException
+	 */
+	public <T> T parse(PartType partType, String in, ClassMeta<T> type) throws ParseException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
index 37d0fc5..9b5f21b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.serializer;
 
+import org.apache.juneau.*;
 import org.apache.juneau.remoteable.*;
 import org.apache.juneau.urlencoding.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/serializer/PartType.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/PartType.java b/juneau-core/src/main/java/org/apache/juneau/serializer/PartType.java
deleted file mode 100644
index 498c49f..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/PartType.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                                                              *
-// *                                                                                                                         *
-// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
-// *                                                                                                                         *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the License.                                              *
-// ***************************************************************************************************************************
-package org.apache.juneau.serializer;
-
-/**
- * Represents possible enum values that can be passed to the {@link PartSerializer#serialize(PartType, Object)} method.
- */
-public enum PartType {
-
-	/** A URI path variable */
-	PATH,
-
-	/** A URI query parameter */
-	QUERY,
-
-	/** A form-data parameter */
-	FORM_DATA,
-
-	/** An HTTP header */
-	HEADER
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index b19c1a6..de01c47 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -51,7 +51,7 @@ import org.apache.juneau.uon.*;
  */
 @SuppressWarnings({ "rawtypes", "unchecked", "hiding" })
 @Consumes("application/x-www-form-urlencoded")
-public class UrlEncodingParser extends UonParser {
+public class UrlEncodingParser extends UonParser implements PartParser {
 
 	/** Reusable instance of {@link UrlEncodingParser}. */
 	public static final UrlEncodingParser DEFAULT = new UrlEncodingParser(PropertyStore.create());
@@ -417,48 +417,8 @@ public class UrlEncodingParser extends UonParser {
 		}
 	}
 
-	/**
-	 * Parses a single query parameter or header value into the specified class type.
-	 *
-	 * @param in The input query string value.
-	 * @param type The object type to create.
-	 * 	<br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
-	 * @param args The type arguments of the class if it's a collection or map.
-	 * 	<br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
-	 * 	<br>Ignored if the main type is not a map or collection.
-	 * @return A new instance of the specified type.
-	 * @throws ParseException
-	 */
-	public <T> T parsePart(String in, Type type, Type...args) throws ParseException {
-		if (in == null)
-			return null;
-		return (T)parsePart(in, getBeanContext().getClassMeta(type, args));
-	}
-
-	/**
-	 * Parses a single query parameter or header value into the specified class type.
-	 *
-	 * @param in The input query string value.
-	 * @param type The class type of the object to create.
-	 * @return A new instance of the specified type.
-	 * @throws ParseException
-	 */
-	public <T> T parsePart(String in, Class<T> type) throws ParseException {
-		if (in == null)
-			return null;
-		return parsePart(in, getBeanContext().getClassMeta(type));
-	}
-
-	/**
-	 * Same as {@link #parsePart(String, Type, Type...)} except the type has already
-	 * been converted to a {@link ClassMeta} object.
-	 *
-	 * @param in The input query string value.
-	 * @param type The class type of the object to create.
-	 * @return A new instance of the specified type.
-	 * @throws ParseException
-	 */
-	public <T> T parsePart(String in, ClassMeta<T> type) throws ParseException {
+	@Override /* PartParser */
+	public <T> T parse(PartType partType, String in, ClassMeta<T> type) throws ParseException {
 		if (in == null)
 			return null;
 		if (type.isString() && in.length() > 0) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
index 0e6be73..c73dfa4 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.rest.client;
 
 import org.apache.http.*;
+import org.apache.juneau.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.urlencoding.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
index a604066..7d9ae86 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
@@ -19,6 +19,7 @@ import static org.junit.Assert.*;
 import java.io.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.remoteable.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ThirdPartyProxyTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ThirdPartyProxyTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ThirdPartyProxyTest.java
index 6cc497d..fe02c60 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ThirdPartyProxyTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ThirdPartyProxyTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.*;
 
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.jena.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
index df0b1ab..5a2ed4d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
@@ -287,7 +287,7 @@ public class RequestFormData extends LinkedHashMap<String,String[]> {
 	}
 
 	private <T> T parseValue(String val, ClassMeta<T> c) throws ParseException {
-		return parser.parsePart(val, c);
+		return parser.parse(PartType.FORM_DATA, val, c);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index 1094160..87fbb23 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -202,9 +202,10 @@ public class RequestHeaders extends TreeMap<String,String[]> {
 	 * @return The parameter value converted to the specified class type.
 	 * @throws ParseException If the header could not be converted to the specified type.
 	 */
+	@SuppressWarnings("unchecked")
 	public <T> T get(String name, Type type, Type...args) throws ParseException {
 		String h = getFirst(name);
-		return parser.parsePart(h, type, args);
+		return (T)parser.parse(PartType.HEADER, h, beanSession.getClassMeta(type, args));
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java
index de40e53..7712a3d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java
@@ -138,7 +138,7 @@ public class RequestPathMatch extends TreeMap<String,String> {
 		Object attr = get(name);
 		T t = null;
 		if (attr != null)
-			t = parser.parsePart(attr.toString(), cm);
+			t = parser.parse(PartType.PATH, attr.toString(), cm);
 		if (t == null && cm.isPrimitive())
 			return cm.getPrimitiveDefault();
 		return t;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
index 366fc1c..e97169e 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
@@ -305,7 +305,7 @@ public final class RequestQuery extends LinkedHashMap<String,String[]> {
 	}
 
 	private <T> T parseValue(String val, ClassMeta<T> c) throws ParseException {
-		return parser.parsePart(val, c);
+		return parser.parse(PartType.QUERY, val, c);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e92a7f6e/juneau-rest/src/main/java/org/apache/juneau/rest/RestResponse.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestResponse.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestResponse.java
index 94ec328..34b3cc0 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestResponse.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -25,6 +25,7 @@ import org.apache.juneau.html.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.jena.*;
 import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.urlencoding.*;
@@ -76,8 +77,8 @@ public final class RestResponse extends HttpServletResponseWrapper {
 		try {
 			String passThroughHeaders = req.getHeader("x-response-headers");
 			if (passThroughHeaders != null) {
-				UrlEncodingParser p = context.getUrlEncodingParser();
-				ObjectMap m = p.parsePart(passThroughHeaders, p.getBeanContext().getClassMeta(ObjectMap.class));
+				PartParser p = context.getUrlEncodingParser();
+				ObjectMap m = p.parse(PartType.HEADER, passThroughHeaders, context.getBeanContext().getClassMeta(ObjectMap.class));
 				for (Map.Entry<String,Object> e : m.entrySet())
 					setHeader(e.getKey(), e.getValue().toString());
 			}