juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject [2/2] juneau git commit: Javadoc updates.
Date Wed, 10 Jan 2018 02:43:33 GMT
Javadoc updates.

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

Branch: refs/heads/master
Commit: 4e501d6a34145242fa13b8c8d576cfdb4ace0b63
Parents: 474a143
Author: JamesBognar <jamesbognar@apache.org>
Authored: Tue Jan 9 21:43:20 2018 -0500
Committer: JamesBognar <jamesbognar@apache.org>
Committed: Tue Jan 9 21:43:20 2018 -0500

----------------------------------------------------------------------
 .../java/org/apache/juneau/BeanConfigTest.java  |  18 +-
 .../juneau/a/rttests/RoundTripBeanMapsTest.java |  24 +-
 .../org/apache/juneau/BeanContextBuilder.java   |  32 +++
 .../main/java/org/apache/juneau/BeanMap.java    |   3 +-
 .../main/java/org/apache/juneau/Context.java    |   1 -
 .../main/java/org/apache/juneau/Session.java    |   2 -
 .../java/org/apache/juneau/annotation/Bean.java |  30 ++-
 .../juneau/annotation/BeanConstructor.java      |  36 +--
 .../apache/juneau/annotation/BeanIgnore.java    |   5 +
 .../org/apache/juneau/annotation/BeanParam.java |  26 --
 .../apache/juneau/annotation/BeanProperty.java  |  30 +--
 .../apache/juneau/annotation/NameProperty.java  |  28 +-
 .../apache/juneau/annotation/Overrideable.java  |  25 --
 .../juneau/annotation/ParentProperty.java       |  21 +-
 .../java/org/apache/juneau/annotation/Swap.java |  33 +--
 .../org/apache/juneau/annotation/Swaps.java     |   5 +
 .../apache/juneau/annotation/ThreadSafe.java    |  28 --
 .../java/org/apache/juneau/annotation/URI.java  |  51 +---
 .../org/apache/juneau/html/HtmlSerializer.java  |  96 +++----
 .../transform/AnnotationBeanFilterBuilder.java  |   9 +-
 .../org/apache/juneau/transform/BeanFilter.java |  37 ++-
 .../juneau/transform/BeanFilterBuilder.java     |  74 +++---
 .../transform/InterfaceBeanFilterBuilder.java   |  20 +-
 .../org/apache/juneau/transform/PojoSwap.java   | 261 ++-----------------
 .../apache/juneau/transform/PropertyFilter.java | 133 ++++++++++
 .../org/apache/juneau/utils/MessageBundle.java  |   7 +-
 juneau-doc/src/main/javadoc/overview.html       | 234 +++++++++++++----
 .../org/apache/juneau/rest/RestContext.java     |   8 +-
 28 files changed, 604 insertions(+), 673 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
index 90e2e58..8016c63 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -741,21 +741,9 @@ public class BeanConfigTest {
 	public static class DummyPojoSwapA extends MapSwap<A> {}
 	public static class DummyPojoSwapB extends MapSwap<B> {}
 	public static class DummyPojoSwapC extends MapSwap<C> {}
-	public static class DummyBeanFilterA extends BeanFilterBuilder {
-		public DummyBeanFilterA() {
-			super(A.class);
-		}
-	}
-	public static class DummyBeanFilterB extends BeanFilterBuilder {
-		public DummyBeanFilterB() {
-			super(B.class);
-		}
-	}
-	public static class DummyBeanFilterC extends BeanFilterBuilder {
-		public DummyBeanFilterC() {
-			super(C.class);
-		}
-	}
+	public static class DummyBeanFilterA extends BeanFilterBuilder<A> {}
+	public static class DummyBeanFilterB extends BeanFilterBuilder<B> {}
+	public static class DummyBeanFilterC extends BeanFilterBuilder<C> {}
 	public static class C {}
 
 	private void assertSameCache(ParserBuilder p1b, ParserBuilder p2b) {

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
index 3ae522b..982ec2c 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -351,9 +351,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 		}
 	}
 
-	public static class CFilter extends BeanFilterBuilder {
+	public static class CFilter extends BeanFilterBuilder<C> {
 		public CFilter() {
-			super(C.class);
 			beanDictionary(CFilterDictionaryMap.class);
 		}
 	}
@@ -446,9 +445,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 		public String f2;
 	}
 
-	public static class CAFilter extends BeanFilterBuilder {
+	public static class CAFilter extends BeanFilterBuilder<CA> {
 		public CAFilter() {
-			super(CA.class);
 			beanDictionary(CAFilterDictionaryMap.class);
 		}
 	}
@@ -520,9 +518,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 			return this;
 		}
 	}
-	public static class D2Filter extends BeanFilterBuilder {
+	public static class D2Filter extends BeanFilterBuilder<D2> {
 		public D2Filter() {
-			super(D2.class);
 			properties("f3,f2");
 		}
 	}
@@ -583,9 +580,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 			return this;
 		}
 	}
-	public static class E2Filter extends BeanFilterBuilder {
+	public static class E2Filter extends BeanFilterBuilder<E2> {
 		public E2Filter() {
-			super(E2.class);
 			excludeProperties("f2");
 		}
 	}
@@ -676,16 +672,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 			return this;
 		}
 	}
-	public static class FB1Filter extends InterfaceBeanFilterBuilder {
-		public FB1Filter() {
-			super(FB1.class);
-		}
-	}
-	public static class FB2Filter extends InterfaceBeanFilterBuilder {
-		public FB2Filter() {
-			super(FB1.class);
-		}
-	}
+	public static class FB1Filter extends InterfaceBeanFilterBuilder<FB1> {}
+	public static class FB2Filter extends InterfaceBeanFilterBuilder<FB1> {}
 
 	//====================================================================================================
 	// testMemberClass

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextBuilder.java
index 82287ba..25c496c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextBuilder.java
@@ -27,6 +27,38 @@ import org.apache.juneau.transform.*;
 
 /**
  * Builder class for building instances of serializers, parsers, and bean contexts.
+ * 
+ * <p>
+ * All serializers and parsers extend from this class.
+ * 
+ * <p>
+ * Provides a base set of common config property setters that allow you to build up serializers and parsers.
+ * 
+ * <p class='bcode'>
+ * 	WriterSerializer s = JsonSerializer
+ * 		.<jsm>create</jsm>()
+ * 		.set(<jsf>JSON_simpleMode</jsf>, <jk>true</jk>)
+ * 		.set(<jsf>SERIALIZER_useWhitespace</jsf>, <jk>true</jk>)
+ * 		.set(<jsf>SERIALIZER_quoteChar</jsf>, <js>"'"</js>)
+ * 		.build();
+ * </p>
+ * 
+ * <p>
+ * Additional convenience methods are provided for setting properties using reduced syntax.
+ * 
+ * <p class='bcode'>
+ * 	WriterSerializer s = JsonSerializer
+ * 		.<jsm>create</jsm>()  <jc>// Create a JsonSerializerBuilder</jc>
+ * 		.simple()  <jc>// Simple mode</jc>
+ * 		.ws()  <jc>// Use whitespace</jc>
+ * 		.sq()  <jc>// Use single quotes </jc>
+ * 		.build();  <jc>// Create a JsonSerializer</jc>
+ * </p>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.ConfigurableProperties">Overview &gt; Configurable Properties</a>
+ *	</ul>
  */
 public class BeanContextBuilder extends ContextBuilder {
 

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
index 2b714f3..ceca7bb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
@@ -227,8 +227,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 			throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
 		}
 		if (meta.beanFilter != null)
-			if (meta.beanFilter.writeProperty(this.bean, property, value))
-				return null;
+			value = meta.beanFilter.writeProperty(this.bean, property, value);
 		return p.set(this, property, value);
 	}
 

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 65d87e9..d13f740 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -447,7 +447,6 @@ public abstract class Context {
 	 *
 	 * @return A new map containing the properties defined on this context.
 	 */
-	@Overrideable
 	public ObjectMap asMap() {
 		return new ObjectMap();
 	}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
index 3806ef6..daaed58 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
@@ -18,7 +18,6 @@ import java.lang.reflect.*;
 import java.text.*;
 import java.util.*;
 
-import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.serializer.*;
@@ -288,7 +287,6 @@ public abstract class Session {
 	 *
 	 * @return A new map containing the properties defined on this context.
 	 */
-	@Overrideable
 	public ObjectMap asMap() {
 		return new ObjectMap();
 	}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java
index cabdde9..c550315 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java
@@ -25,18 +25,12 @@ import org.apache.juneau.transform.*;
  * Used to tailor how beans get interpreted by the framework.
  *
  * <p>
- * Can be used to do the following:
- * <ul class='spaced-list'>
- * 	<li>
- * 		Explicitly specify the set and order of properties on a bean.
- * 	<li>
- * 		Associate a {@link PropertyNamer} with a class.
- * 	<li>
- * 		Specify subtypes of a bean differentiated by a sub type property.
- * </ul>
- *
- * <p>
  * This annotation can be applied to classes and interfaces.
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanAnnotation">Overview &gt; @Bean Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target(TYPE)
@@ -285,7 +279,6 @@ public @interface Bean {
 	 */
 	Class<?> stopClass() default Object.class;
 
-
 	/**
 	 * Bean dictionary.
 	 *
@@ -298,4 +291,17 @@ public @interface Bean {
 	 * </ul>
 	 */
 	Class<?>[] beanDictionary() default {};
+	
+	/**
+	 * Property filter.
+	 * 
+	 * <p>
+	 * Property filters can be used to intercept calls to getters and setters and alter their values in transit. 
+	 * 
+	 * <h5 class='section'>See Also:</h5>
+	 * <ul>
+	 * 	<li class='jc'>{@link PropertyFilter}
+	 * </ul>
+	 */
+	Class<? extends PropertyFilter> propertyFilter() default PropertyFilter.class;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConstructor.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConstructor.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConstructor.java
index e4bf51c..ae4efe5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConstructor.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConstructor.java
@@ -29,36 +29,6 @@ import org.apache.juneau.*;
  * are available at runtime.
  *
  * <p>
- * The definition of a read-only bean is a bean with properties with only getters, like shown below...
- * <p class='bcode'>
- * 	<jk>public class</jk> Person {
- * 		<jk>private final</jk> String <jf>name</jf>;
- * 		<jk>private final int</jk> <jf>age</jf>;
- *
- * 		<ja>@BeanConstructor</ja>(properties=<js>"name,age"</js>})
- * 		<jk>public</jk> Person(String name, <jk>int</jk> age) {
- * 			<jk>this</jk>.<jf>name</jf> = name;
- * 			<jk>this</jk>.<jf>age</jf> = age;
- * 		}
- *
- * 		<jc>// Read only properties.</jc>
- *
- * 		<jk>public</jk> String getName() {
- * 			<jk>return</jk> <jf>name</jf>;
- * 		}
- *
- * 		<jk>public int</jk> getAge() {
- * 			<jk>return</jk> <jf>age</jf>;
- * 		}
- * 	}
- *
- * 	String json = <js>"{name:'John Smith',age:45}"</js>;
- * 	Person p = JsonParser.<jsf>DEFAULT</jsf>.parse(json);
- * 	String name = p.getName();  <jc>// "John Smith"</jc>
- * 	<jk>int</jk> age = p.getAge();   <jc>// 45</jc>
- * </p>
- *
- * <p>
  * This annotation can only be applied to constructors and can only be applied to one constructor per class.
  *
  * <p>
@@ -72,8 +42,10 @@ import org.apache.juneau.*;
  * will result in a {@link BeanRuntimeException} being thrown.
  * Multiple calls to {@link BeanMap#getBean()} will return the same bean instance.
  *
- * <p>
- * Beans can be defined with a combination of read-only and read-write properties.
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanConstructorAnnotation">Overview &gt; @BeanConstructor Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target(CONSTRUCTOR)

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnore.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnore.java
index efaa145..910ed00 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnore.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnore.java
@@ -30,6 +30,11 @@ import java.lang.annotation.*;
  *
  * <p>
  * Applies to getters or setters that should not be interpreted as bean property getters or setters.
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanIgnoreAnnotation">Overview &gt; @BeanIgnore Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target({FIELD,METHOD,TYPE})

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanParam.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanParam.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanParam.java
deleted file mode 100644
index 47137fe..0000000
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanParam.java
+++ /dev/null
@@ -1,26 +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.annotation;
-
-
-/**
- * Future support for defining bean properties on constructor args.
- */
-public @interface BeanParam {
-
-	/**
-	 * TODO
-	 */
-	String value() default "";
-
-}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index 9cf521f..b1567b1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -23,32 +23,12 @@ import org.apache.juneau.*;
  * Used tailor how bean properties get interpreted by the framework.
  *
  * <p>
- * Can be used to do the following:
- * <ul class='spaced-list'>
- * 	<li>
- * 		Override the name of a property.
- * 	<li>
- * 		Identify a getter or setter with a non-standard naming convention.
- * 	<li>
- * 		Identify a specific subclass for a property with a general class type.
- * 	<li>
- * 		Identify class types of elements in properties of type <code>Collection</code> or <code>Map</code>.
- * 	<li>
- * 		Hide properties during serialization.
- * 	<li>
- * 		Associate transforms with bean property values, such as a POJO swap to convert a <code>Calendar</code> field
- * 		to a string.
- * 	<li>
- * 		Override the list of properties during serialization on child elements of a property of type
- * 		<code>Collection</code> or <code>Map</code>.
- * 	<li>
- * 		Identify a property as the URL for a bean.
- * 	<li>
- * 		Identify a property as the ID for a bean.
- * </ul>
- *
- * <p>
  * This annotation is applied to public fields and public getter/setter methods of beans.
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanPropertyAnnotation">Overview &gt; @BeanProperty Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target({FIELD,METHOD})

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/NameProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/NameProperty.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/NameProperty.java
index 25ae00c..e48f870 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/NameProperty.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/NameProperty.java
@@ -20,33 +20,15 @@ import java.lang.annotation.*;
 /**
  * Identifies a setter as a method for setting the name of a POJO as it's known by its parent object.
  *
- * <p>
- * For example, the <code>Section</code> class must know the name it's known by it's parent <code>ConfigFileImpl</code> class,
- * so parsers will call this method with the section name using the <code>Section.setName(String)</code> method.
- * <p>
- * A commonly-used case is when you're parsing a JSON map containing beans where one of the bean properties is the key
- * used in the map.
- *
- * <p>
- * For example:
- * <p class='bcode'>
- * 	{
- * 		id1: {name: <js>'John Smith'</js>, sex:<js>'M'</js>},
- * 		id2: {name: <js>'Jane Doe'</js>, sex:<js>'F'</js>}
- * 	}
- * </p>
- * <p class='bcode'>
- * 	<jk>public class</jk> Person {
- * 		<ja>@NameProperty</ja> <jk>public</jk> String <jf>id</jf>;
- * 		<jk>public</jk> String <jf>name</jf>;
- * 		<jk>public char</jk> <jf>sex</jf>;
- * 	}
- * </p>
- *
  * <h5 class='section'>Notes:</h5>
  * <ul>
  * 	<li>The annotated field or method does not need to be public.
  * </ul>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.NamePropertyAnnotation">Overview &gt; @NameProperty Annotation</a>
+ *	</ul>
  */
 @Target({METHOD,FIELD})
 @Retention(RUNTIME)

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Overrideable.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Overrideable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Overrideable.java
deleted file mode 100644
index 4a9bec5..0000000
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Overrideable.java
+++ /dev/null
@@ -1,25 +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.annotation;
-
-import static java.lang.annotation.ElementType.*;
-
-import java.lang.annotation.*;
-
-/**
- * Identifies a method as specifically designed to be overridden and augmented.
- */
-@Documented
-@Target({METHOD})
-@Inherited
-public @interface Overrideable {}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ParentProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ParentProperty.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ParentProperty.java
index 778f1f8..9c3e1e6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ParentProperty.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ParentProperty.java
@@ -22,27 +22,16 @@ import java.lang.annotation.*;
  *
  * <p>
  * Used by the parsers to add references to parent objects in child objects.
- * For example, the <code>Section</code> class cannot exist outside the scope of a parent <code>ConfigFileImpl</code> class, so
- * parsers will add a reference to the config file using the <code>Section.setParent(ConfigFileImpl)</code> method.
- *
- * <p>
- * A commonly-used case is when you're parsing beans, and a child bean has a reference to a parent bean.
- * <p class='bcode'>
- * 	<jk>public class</jk> AddressBook {
- * 		<jk>public</jk> List&lt;Person&gt; <jf>people</jf>;
- * 	}
- *
- * 	<jk>public class</jk> Person {
- * 		<ja>@ParentProperty</ja> <jk>public</jk> AddressBook <jf>addressBook</jf>;
- * 		<jk>public</jk> String <jf>name</jf>;
- * 		<jk>public char</jk> <jf>sex</jf>;
- * 	}
- * </p>
  *
  * <h5 class='section'>Notes:</h5>
  * <ul>
  * 	<li>The annotated field or method does not need to be public.
  * </ul>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.NamePropertyAnnotation">Overview &gt; @NameProperty Annotation</a>
+ *	</ul>
  */
 @Target({METHOD,FIELD})
 @Retention(RUNTIME)

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
index 88ccb1d..bb27e8f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
@@ -16,7 +16,6 @@ import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
-import java.util.*;
 
 import org.apache.juneau.transform.*;
 
@@ -24,25 +23,17 @@ import org.apache.juneau.transform.*;
  * Associates {@link PojoSwap} and {@link Surrogate} classes with POJOs and bean properties.
  *
  * <p>
- * A typical example is for rendering {@link Date Dates} and {@link Calendar Calendars} as a formatted string:
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
- * 	<jk>public class</jk> MyClass {
- *
- * 		<jc>// During serialization, convert to ISO8601 date-time string.</jc>
- * 		<ja>@Swap</ja>(CalendarSwap.ISO8601DT.<jk>class</jk>)
- * 		<jk>public</jk> Calendar getTime();
- * 	}
- * </p>
- *
- * <p>
  * This annotation can be used in the following locations:
  * <ul>
  * 	<li>Classes.
  * 	<li>Bean getters/setters/fields.
  * 	<li>Inside the {@link Swaps @Swaps} annotation.
  * </ul>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.SwapAnnotation">Overview &gt; @Swap Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target({TYPE,ANNOTATION_TYPE,FIELD,METHOD})
@@ -80,8 +71,8 @@ public @interface Swap {
 	 * The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:
 	 *
 	 * <p class='bcode'>
-	 * 	<jc>// Our abstracted templated swap class.</jc>
-	 * 	<jk>public abstract class</jk> FreeMarkerSwap <jk>extends</jk> PojoSwap&lt;Object,Reader&gt; {
+	 * 	<jc>// Our templated swap class.</jc>
+	 * 	<jk>public class</jk> FreeMarkerSwap <jk>extends</jk> PojoSwap&lt;Object,Reader&gt; {
 	 *
 	 * 		<jk>public</jk> MediaType[] forMediaTypes() {
 	 * 			<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/html"</js>);
@@ -96,6 +87,11 @@ public @interface Swap {
 	 * 	<ja>@Swap</ja>(impl=FreeMarkerSwap.<jk>class</jk>, template=<js>"MyPojo.div.ftl"</js>)
 	 * 	<jk>public class</jk> MyPojo {}
 	 * </p>
+	 * 
+	 *	<h5 class='section'>Documentation:</h5>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.TemplatedSwaps">Overview &gt; Templated Swaps</a>
+	 *	</ul>
 	 */
 	String template() default "";
 
@@ -115,6 +111,11 @@ public @interface Swap {
 	 * 			}
 	 * 		}
 	 * </p>
+	 * 
+	 *	<h5 class='section'>Documentation:</h5>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.PerMediaTypePojoSwaps">Overview &gt; Per-media-type PojoSwaps</a>
+	 *	</ul>
 	 */
 	String[] mediaTypes() default {};
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
index d384c17..3ed934f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
@@ -30,6 +30,11 @@ import java.lang.annotation.*;
  * 	)
  * 	<jk>public class</jk> MyPojo {}
  * </p>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.SwapAnnotation">Overview &gt; @Swap Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target({TYPE})

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ThreadSafe.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ThreadSafe.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ThreadSafe.java
deleted file mode 100644
index fdda089..0000000
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/ThreadSafe.java
+++ /dev/null
@@ -1,28 +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.annotation;
-
-import static java.lang.annotation.ElementType.*;
-
-import java.lang.annotation.*;
-
-/**
- * Identifies a class as being thread-safe.
- *
- * <p>
- * Used for documentation purposes only.
- */
-@Documented
-@Target(TYPE)
-@Inherited
-public @interface ThreadSafe {}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/URI.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/URI.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/URI.java
index 8b73a65..985790b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/URI.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/URI.java
@@ -16,59 +16,18 @@ import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
-import java.net.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.serializer.*;
 
 /**
  * Used to identify a class or bean property as a URI.
  *
  * <p>
- * By default, instances of {@link URL} and {@link URI} are considered URIs during serialization, and are handled
- * differently depending on the serializer (e.g. <code>HtmlSerializer</code> creates a hyperlink,
- * <code>RdfXmlSerializer</code> creates an <code>rdf:resource</code> object, etc...).
- *
- * <p>
  * This annotation allows you to identify other classes that return URIs via <code>toString()</code> as URI objects.
  *
- * <p>
- * URIs are automatically resolved to absolute or root-relative form based on the serializer
- * {@link Serializer#SERIALIZER_uriResolution} and {@link Serializer#SERIALIZER_uriRelativity}
- * configuration settings, and the URI context defined by the {@link UriContext} that's part of the serializer
- * session.
- *
- * <p>
- * Refer to the {@link UriResolver} class for information about the types of URIs that can be resolved during
- * serialization.
- *
- * <p>
- * This annotation can be applied to classes, interfaces, or bean property methods for fields.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
- *
- * 	<jc>// Applied to a class whose toString() method returns a URI.</jc>
- * 	<ja>@URI</ja>
- * 	<jk>public class</jk> MyURI {
- * 		<ja>@Override</ja>
- * 		<jk>public</jk> String toString() {
- * 			<jk>return</jk> <js>"http://localhost:9080/foo/bar"</js>;
- * 		}
- * 	}
- *
- * 	<jc>// Applied to bean properties</jc>
- * 	<jk>public class</jk> MyBean {
- *
- * 		<ja>@URI</ja>
- * 		<jk>public</jk> String <jf>beanUri</jf>;
- *
- * 		<ja>@URI</ja>
- * 		<jk>public</jk> String getParentUri() {
- * 			...
- * 		}
- * 	}
- * </p>
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.URIAnnotation">Overview &gt; @URI Annotation</a>
+ *	</ul>
  */
 @Documented
 @Target({TYPE,FIELD,METHOD})

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index f876223..7b58514 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -66,61 +66,61 @@ import org.apache.juneau.xml.*;
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Use one of the default serializers to serialize a POJO</jc>
- * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(someObject);
+ * 	String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(someObject);
  *
- * 		<jc>// Create a custom serializer that doesn't use whitespace and newlines</jc>
- * 		HtmlSerializer serializer = <jk>new</jk> HtmlSerializerBuider().ws().build();
+ * 	<jc>// Create a custom serializer that doesn't use whitespace and newlines</jc>
+ * 	HtmlSerializer serializer = <jk>new</jk> HtmlSerializerBuider().ws().build();
  *
- * 		<jc>// Same as above, except uses cloning</jc>
- * 		HtmlSerializer serializer = HtmlSerializer.<jsf>DEFAULT</jsf>.builder().ws().build();
+ * 	<jc>// Same as above, except uses cloning</jc>
+ * 	HtmlSerializer serializer = HtmlSerializer.<jsf>DEFAULT</jsf>.builder().ws().build();
  *
- * 		<jc>// Serialize POJOs to HTML</jc>
+ * 	<jc>// Serialize POJOs to HTML</jc>
  *
- * 		<jc>// Produces: </jc>
- * 		<jc>// &lt;ul&gt;&lt;li&gt;1&lt;li&gt;2&lt;li&gt;3&lt;/ul&gt;</jc>
- * 		List l = new ObjectList(1, 2, 3);
- * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(l);
+ * 	<jc>// Produces: </jc>
+ * 	<jc>// &lt;ul&gt;&lt;li&gt;1&lt;li&gt;2&lt;li&gt;3&lt;/ul&gt;</jc>
+ * 	List l = new ObjectList(1, 2, 3);
+ * 	String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(l);
  *
- * 		<jc>// Produces: </jc>
- * 		<jc>//    &lt;table&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;th&gt;firstName&lt;/th&gt;&lt;th&gt;lastName&lt;/th&gt;&lt;/tr&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;td&gt;Bob&lt;/td&gt;&lt;td&gt;Costas&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;td&gt;Billy&lt;/td&gt;&lt;td&gt;TheKid&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;td&gt;Barney&lt;/td&gt;&lt;td&gt;Miller&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//    &lt;/table&gt; </jc>
- * 		l = <jk>new</jk> ObjectList();
- * 		l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Bob',lastName:'Costas'}"</js>));
- * 		l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Billy',lastName:'TheKid'}"</js>));
- * 		l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Barney',lastName:'Miller'}"</js>));
- * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(l);
+ * 	<jc>// Produces: </jc>
+ * 	<jc>//    &lt;table&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;th&gt;firstName&lt;/th&gt;&lt;th&gt;lastName&lt;/th&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;td&gt;Bob&lt;/td&gt;&lt;td&gt;Costas&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;td&gt;Billy&lt;/td&gt;&lt;td&gt;TheKid&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;td&gt;Barney&lt;/td&gt;&lt;td&gt;Miller&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//    &lt;/table&gt; </jc>
+ * 	l = <jk>new</jk> ObjectList();
+ * 	l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Bob',lastName:'Costas'}"</js>));
+ * 	l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Billy',lastName:'TheKid'}"</js>));
+ * 	l.add(<jk>new</jk> ObjectMap(<js>"{firstName:'Barney',lastName:'Miller'}"</js>));
+ * 	String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(l);
  *
- * 		<jc>// Produces: </jc>
- * 		<jc>//    &lt;table&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;td&gt;foo&lt;/td&gt;&lt;td&gt;bar&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//       &lt;tr&gt;&lt;td&gt;baz&lt;/td&gt;&lt;td&gt;123&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//    &lt;/table&gt; </jc>
- * 		Map m = <jk>new</jk> ObjectMap(<js>"{foo:'bar',baz:123}"</js>);
- * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(m);
+ * 	<jc>// Produces: </jc>
+ * 	<jc>//    &lt;table&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;td&gt;foo&lt;/td&gt;&lt;td&gt;bar&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//       &lt;tr&gt;&lt;td&gt;baz&lt;/td&gt;&lt;td&gt;123&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//    &lt;/table&gt; </jc>
+ * 	Map m = <jk>new</jk> ObjectMap(<js>"{foo:'bar',baz:123}"</js>);
+ * 	String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(m);
  *
- * 		<jc>// HTML elements can be nested arbitrarily deep</jc>
- * 		<jc>// Produces: </jc>
- * 		<jc>//	&lt;table&gt; </jc>
- * 		<jc>//		&lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
- * 		<jc>//		&lt;tr&gt;&lt;td&gt;foo&lt;/td&gt;&lt;td&gt;bar&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//		&lt;tr&gt;&lt;td&gt;baz&lt;/td&gt;&lt;td&gt;123&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//		&lt;tr&gt;&lt;td&gt;someNumbers&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;1&lt;li&gt;2&lt;li&gt;3&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//		&lt;tr&gt;&lt;td&gt;someSubMap&lt;/td&gt;&lt;td&gt; </jc>
- * 		<jc>//			&lt;table&gt; </jc>
- * 		<jc>//				&lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
- * 		<jc>//				&lt;tr&gt;&lt;td&gt;a&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//			&lt;/table&gt; </jc>
- * 		<jc>//		&lt;/td&gt;&lt;/tr&gt; </jc>
- * 		<jc>//	&lt;/table&gt; </jc>
- * 		Map m = <jk>new</jk> ObjectMap(<js>"{foo:'bar',baz:123}"</js>);
- * 		m.put("someNumbers", new ObjectList(1, 2, 3));
- * 		m.put(<js>"someSubMap"</js>, new ObjectMap(<js>"{a:'b'}"</js>));
- * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(m);
+ * 	<jc>// HTML elements can be nested arbitrarily deep</jc>
+ * 	<jc>// Produces: </jc>
+ * 	<jc>//	&lt;table&gt; </jc>
+ * 	<jc>//		&lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//		&lt;tr&gt;&lt;td&gt;foo&lt;/td&gt;&lt;td&gt;bar&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//		&lt;tr&gt;&lt;td&gt;baz&lt;/td&gt;&lt;td&gt;123&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//		&lt;tr&gt;&lt;td&gt;someNumbers&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;1&lt;li&gt;2&lt;li&gt;3&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//		&lt;tr&gt;&lt;td&gt;someSubMap&lt;/td&gt;&lt;td&gt; </jc>
+ * 	<jc>//			&lt;table&gt; </jc>
+ * 	<jc>//				&lt;tr&gt;&lt;th&gt;key&lt;/th&gt;&lt;th&gt;value&lt;/th&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//				&lt;tr&gt;&lt;td&gt;a&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//			&lt;/table&gt; </jc>
+ * 	<jc>//		&lt;/td&gt;&lt;/tr&gt; </jc>
+ * 	<jc>//	&lt;/table&gt; </jc>
+ * 	Map m = <jk>new</jk> ObjectMap(<js>"{foo:'bar',baz:123}"</js>);
+ * 	m.put("someNumbers", new ObjectList(1, 2, 3));
+ * 	m.put(<js>"someSubMap"</js>, new ObjectMap(<js>"{a:'b'}"</js>));
+ * 	String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(m);
  * </p>
  */
 public class HtmlSerializer extends XmlSerializer {

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
index f13ee99..b583756 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
@@ -24,8 +24,10 @@ import org.apache.juneau.annotation.*;
  *
  * <p>
  * <b>*** Internal class - Not intended for external use ***</b>
+ * 
+ * @param <T> Annotated bean class.
  */
-public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
+public final class AnnotationBeanFilterBuilder<T> extends BeanFilterBuilder<T> {
 
 	/**
 	 * Constructor.
@@ -35,7 +37,7 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
 	 * 	The {@link Bean @Bean} annotations found on the class and all parent classes in child-to-parent order.
 	 * @throws Exception Thrown from property namer constructor.
 	 */
-	public AnnotationBeanFilterBuilder(Class<?> annotatedClass, Map<Class<?>,Bean> annotations) throws Exception {
+	public AnnotationBeanFilterBuilder(Class<T> annotatedClass, Map<Class<?>,Bean> annotations) throws Exception {
 		super(annotatedClass);
 
 		ListIterator<Bean> li = new ArrayList<>(annotations.values()).listIterator(annotations.size());
@@ -65,6 +67,9 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
 
 			if (b.beanDictionary().length > 0)
 				beanDictionary(b.beanDictionary());
+			
+			if (b.propertyFilter() != PropertyFilter.class)
+				propertyFilter(b.propertyFilter());
 		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilter.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilter.java
index 2b2671a..6a2a9b3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilter.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilter.java
@@ -28,8 +28,13 @@ import org.apache.juneau.internal.*;
  * This class can be considered a programmatic equivalent to using the {@link Bean @Bean} annotation on bean classes.
  * Thus, it can be used to perform the same function as the <code>@Bean</code> annotation when you don't have
  * the ability to annotate those classes (e.g. you don't have access to the source code).
+ * 
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanFilters">Overview &gt; BeanFilters</a>
+ *	</ul>
  */
-public class BeanFilter {
+public final class BeanFilter {
 
 	private final Class<?> beanClass;
 	private final String[] properties, excludeProperties;
@@ -38,11 +43,12 @@ public class BeanFilter {
 	private final boolean sortProperties;
 	private final String typeName;
 	private final Class<?>[] beanDictionary;
+	private final PropertyFilter propertyFilter;
 
 	/**
 	 * Constructor.
 	 */
-	BeanFilter(BeanFilterBuilder builder) {
+	BeanFilter(BeanFilterBuilder<?> builder) {
 		this.beanClass = builder.beanClass;
 		this.typeName = builder.typeName;
 		this.properties = split(builder.properties, ',');
@@ -55,9 +61,23 @@ public class BeanFilter {
 			builder.beanDictionary == null
 			? null
 			: builder.beanDictionary.toArray(new Class<?>[builder.beanDictionary.size()]);
+		this.propertyFilter =
+			builder.propertyFilter == null
+			? PropertyFilter.DEFAULT
+			: ClassUtils.newInstance(PropertyFilter.class, builder.propertyFilter);
 	}
 
 	/**
+	 * Create a new bean filter builder.
+	 * 
+ 	 * @param beanClass The bean class that this filter applies to.
+	 * @return A new filter.
+	 */
+	public static <T> BeanFilterBuilder<T> create(Class<T> beanClass) {
+		return new BeanFilterBuilder<>(beanClass);
+	}
+	
+	/**
 	 * Returns the bean class that this filter applies to.
 	 *
 	 * @return The bean class that this filter applies to.
@@ -145,7 +165,7 @@ public class BeanFilter {
 	}
 
 	/**
-	 * Subclasses can override this property to convert property values to some other object just before serialization.
+	 * Calls the {@link PropertyFilter#readProperty(Object, String, Object)} method on the registered property filters.
 	 *
 	 * @param bean The bean from which the property was read.
 	 * @param name The property name.
@@ -153,19 +173,18 @@ public class BeanFilter {
 	 * @return The value to serialize.  Default is just to return the existing value.
 	 */
 	public Object readProperty(Object bean, String name, Object value) {
-		return value;
+		return propertyFilter.readProperty(bean, name, value);
 	}
 
 	/**
-	 * Subclasses can override this property to convert property values to some other object just before calling the
-	 * bean setter.
+	 * Calls the {@link PropertyFilter#writeProperty(Object, String, Object)} method on the registered property filters.
 	 *
 	 * @param bean The bean from which the property was read.
 	 * @param name The property name.
 	 * @param value The value just parsed.
-	 * @return <jk>true</jk> if we set the property, <jk>false</jk> if we should allow the framework to call the setter.
+	 * @return The value to serialize.  Default is just to return the existing value.
 	 */
-	public boolean writeProperty(Object bean, String name, Object value) {
-		return false;
+	public Object writeProperty(Object bean, String name, Object value) {
+		return propertyFilter.writeProperty(bean, name, value);
 	}
 }

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
index 54a8401..3f290c5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.transform;
 
+import static org.apache.juneau.internal.ClassUtils.*;
+
 import java.beans.*;
 import java.util.*;
 
@@ -24,27 +26,14 @@ import org.apache.juneau.*;
  * Bean filter builders must have a public no-arg constructor.
  * Builder settings should be set in the constructor using the provided setters on this class.
  *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
- * 	<jc>// Create our serializer with a bean filter.</jc>
- * 	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(AddressFilter.<jk>class</jk>).build();
- *
- * 	Address a = <jk>new</jk> Address();
- * 	String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc>
- *
- * 	<jc>// Filter class defined via setters</jc>
- * 	<jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilterBuilder {
- * 		<jk>public</jk> AddressFilter() {
- * 			super(Address.<jk>class</jk>);
- * 			setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>);
- * 		}
- * 	}
- * </p>
+ * <h6 class='topic'>Documentation</h6>
+ *	<ul>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanFilters">Overview &gt; BeanFilters</a>
+ *	</ul>
  *
- * <h5 class='section'>Additional information:</h5>
- * See <a class='doclink' href='package-summary.html#TOC'>org.apache.juneau.transform</a> for more information.
+ * @param <T> The bean type that this filter applies to. 
  */
-public abstract class BeanFilterBuilder {
+public class BeanFilterBuilder<T> {
 
 	Class<?> beanClass;
 	String typeName;
@@ -53,13 +42,24 @@ public abstract class BeanFilterBuilder {
 	boolean sortProperties;
 	Object propertyNamer;
 	List<Class<?>> beanDictionary;
+	Object propertyFilter;
+
+	/**
+	 * Constructor.
+	 * 
+	 * <p>
+	 * Bean class is determined through reflection of the parameter type.
+	 */
+	protected BeanFilterBuilder() {
+		beanClass = resolveParameterType(BeanFilterBuilder.class, 0, this.getClass());
+	}
 
 	/**
 	 * Constructor.
 	 *
 	 * @param beanClass The bean class that this filter applies to.
 	 */
-	public BeanFilterBuilder(Class<?> beanClass) {
+	protected BeanFilterBuilder(Class<?> beanClass) {
 		this.beanClass = beanClass;
 	}
 
@@ -69,7 +69,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder typeName(String value) {
+	public BeanFilterBuilder<T> typeName(String value) {
 		this.typeName = value;
 		return this;
 	}
@@ -85,7 +85,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder properties(String...value) {
+	public BeanFilterBuilder<T> properties(String...value) {
 		this.properties = value;
 		return this;
 	}
@@ -96,7 +96,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder excludeProperties(String...value) {
+	public BeanFilterBuilder<T> excludeProperties(String...value) {
 		this.excludeProperties = value;
 		return this;
 	}
@@ -120,9 +120,8 @@ public abstract class BeanFilterBuilder {
 	 * 	}
 	 *
 	 * 	<jc>// Filter class</jc>
-	 * 	<jk>public class</jk> AFilter <jk>extends</jk> BeanFilterBuilder {
+	 * 	<jk>public class</jk> AFilter <jk>extends</jk> BeanFilterBuilder&lt;A&gt; {
 	 * 		<jk>public</jk> AFilter() {
-	 * 			super(A.<jk>class</jk>);
 	 * 			setInterfaceClass(A.<jk>class</jk>);
 	 * 		}
 	 * 	}
@@ -140,7 +139,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder interfaceClass(Class<?> value) {
+	public BeanFilterBuilder<T> interfaceClass(Class<?> value) {
 		this.interfaceClass = value;
 		return this;
 	}
@@ -174,7 +173,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder stopClass(Class<?> value) {
+	public BeanFilterBuilder<T> stopClass(Class<?> value) {
 		this.stopClass = value;
 		return this;
 	}
@@ -185,7 +184,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder sortProperties(boolean value) {
+	public BeanFilterBuilder<T> sortProperties(boolean value) {
 		this.sortProperties = value;
 		return this;
 	}
@@ -196,7 +195,7 @@ public abstract class BeanFilterBuilder {
 	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder propertyNamer(PropertyNamer value) {
+	public BeanFilterBuilder<T> propertyNamer(PropertyNamer value) {
 		this.propertyNamer = value;
 		return this;
 	}
@@ -208,7 +207,7 @@ public abstract class BeanFilterBuilder {
 	 * @return This object (for method chaining).
 	 * @throws Exception Thrown from constructor method.
 	 */
-	public BeanFilterBuilder propertyNamer(Class<? extends PropertyNamer> value) throws Exception {
+	public BeanFilterBuilder<T> propertyNamer(Class<? extends PropertyNamer> value) throws Exception {
 		this.propertyNamer = value;
 		return this;
 	}
@@ -224,7 +223,7 @@ public abstract class BeanFilterBuilder {
 	 * @param values The values to add to this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder beanDictionary(Class<?>...values) {
+	public BeanFilterBuilder<T> beanDictionary(Class<?>...values) {
 		if (beanDictionary == null)
 			beanDictionary = new ArrayList<>(Arrays.asList(values));
 		else for (Class<?> cc : values)
@@ -245,13 +244,24 @@ public abstract class BeanFilterBuilder {
 	 * @param values The new values for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder beanDictionary(boolean append, Class<?>...values) {
+	public BeanFilterBuilder<T> beanDictionary(boolean append, Class<?>...values) {
 		if (append)
 			beanDictionary(values);
 		else
 			beanDictionary = new ArrayList<>(Arrays.asList(values));
 		return this;
 	}
+	
+	/**
+	 * The property filter to use for intercepting and altering getter and setter calls.
+	 *
+	 * @param value The new value for this setting.
+	 * @return This object (for method chaining).
+	 */
+	public BeanFilterBuilder<T> propertyFilter(Class<? extends PropertyFilter> value) {
+		this.propertyFilter = value;
+		return this;
+	}
 
 	/**
 	 * Creates a {@link BeanFilter} with settings in this builder class.

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
index de293cc..0b90a73 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
@@ -27,16 +27,32 @@ import org.apache.juneau.internal.*;
  * These objects are created when you pass in non-<code>BeanFilterBuilder</code> classes to
  * {@link BeanContextBuilder#beanFilters(Class...)}, and are equivalent to adding a
  * <code><ja>@Bean</ja>(interfaceClass=Foo.<jk>class</jk>)</code> annotation on the <code>Foo</code> class.
+ * 
+ * @param <T> The interface class.
  */
-public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
+public class InterfaceBeanFilterBuilder<T> extends BeanFilterBuilder<T> {
+
+	/**
+	 * Constructor.
+	 * 
+	 * <p>
+	 * Interface class is determined through reflection.
+	 */
+	public InterfaceBeanFilterBuilder() {
+		init(beanClass);
+	}
 
 	/**
 	 * Constructor.
 	 * 
 	 * @param interfaceClass The class to use as an interface on all child classes.
 	 */
-	public InterfaceBeanFilterBuilder(Class<?> interfaceClass) {
+	public InterfaceBeanFilterBuilder(Class<T> interfaceClass) {
 		super(interfaceClass);
+		init(interfaceClass);
+	}
+	
+	private void init(Class<?> interfaceClass) {
 		interfaceClass(interfaceClass);
 		Map<Class<?>,Bean> annotations = ReflectionUtils.findAnnotationsMap(Bean.class, interfaceClass);
 

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
index 58d9669..4c8cf3c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -42,8 +42,8 @@ import org.apache.juneau.serializer.*;
  * <p>
  * <code>PojoSwaps</code> are associated with serializers and parsers through the following:
  * <ul>
- * 	<li class='ja'>{@link Swap} 
- * 	<li class='ja'>{@link Swaps} 
+ * 	<li class='ja'>{@link Swap @Swap} 
+ * 	<li class='ja'>{@link Swaps @Swaps} 
  * 	<li class='jm'>{@link BeanContextBuilder#pojoSwaps(Object...)}
  * 	<li class='jm'>{@link BeanContextBuilder#pojoSwaps(Class...)}
  * 	<li class='jm'>{@link BeanContextBuilder#pojoSwaps(boolean, Object...)}
@@ -62,21 +62,13 @@ import org.apache.juneau.serializer.*;
  * {@link BeanMap#put(String,Object)}.
  *
  *
- * <h6 class='topic'>Subtypes</h6>
- *
- * The following abstract subclasses are provided for common swap types:
- * <ol>
- * 	<li class='jac'>{@link StringSwap} - Objects swapped with strings.
- * 	<li class='jac'>{@link MapSwap} - Objects swapped with {@link ObjectMap ObjectMaps}.
- * </ol>
- *
- *
  * <h6 class='topic'>Swap Class Type {@code <S>}</h6>
  *
+ * <p>
  * The swapped object representation of an object must be an object type that the serializers can natively convert to
  * JSON (or language-specific equivalent).
- * The list of valid transformed types are as follows...
- * <ul class='spaced-list'>
+ * <br>The list of valid transformed types are as follows...
+ * <ul>
  * 	<li>
  * 		{@link String}
  * 	<li>
@@ -96,236 +88,16 @@ import org.apache.juneau.serializer.*;
  *
  * <h6 class='topic'>Normal Class Type {@code <T>}</h6>
  *
- * The normal object representation of an object.
- *
- *
- * <h6 class='topic'>Overview</h6>
- * 
- * <p>
- * The following is an example of a swap that replaces byte arrays with BASE-64 encoded strings:
- * 
- * <p class='bcode'>
- * 	<jk>public class</jk> ByteArrayBase64Swap <jk>extends</jk> PojoSwap&lt;<jk>byte</jk>[],String&gt; {
- * 		
- * 		<ja>@Override</ja>
- * 		<jk>public</jk> String swap(BeanSession session, <jk>byte</jk>[] b) <jk>throws</jk> Exception {
- * 			<jk>return</jk> StringUtils.<jsm>base64Encode</jsm>(b);
- * 		}
- * 		
- * 		<ja>@Override</ja>
- * 		<jk>public byte</jk>[] unswap(BeanSession session, String s, ClassMeta&lt;?&gt; hint) <jk>throws</jk> Exception {
- * 			<jk>return</jk> StringUtils.<jsm>base64Decode</jsm>(s);
- * 		}
- * 	}
- * </p>
- *
- * <p class='bcode'>
- * 	WriterSerializer s = JsonSerializer.<jsm>create</jsm>().simple().pojoSwaps(ByteArrayBase64Swap.<jk>class</jk>).build();
- * 	String json = s.serialize(<jk>new byte</jk>[] {1,2,3});  <jc>// Produces "'AQID'"</jc>
- * </p>
- *
- *
- * <h6 class='topic'>Swap annotation</h6>
- *
- * <p>
- * Swap classes are often associated directly with POJOs using the {@link Swap @Swap} annotation.
- *
- * <p class='bcode'>
- * 	<jk>public class</jk> MyPojoSwap <jk>extends</jk> PojoSwap&lt;MyPojo,String&gt; { ... }
- *
- * 	<ja>@Swap</ja>(MyPojoSwap.<jk>class</jk>)
- * 	<jk>public class</jk> MyPojo { ... }
- * </p>
- *
- * <p>
- * The <ja>@Swap</ja> annotation is often simpler since you do not need to tell your serializers and parsers about them
- * leading to less code.
- *
- * <p>
- * Swaps can also be associated with getters and setters as well:
- *
- * <p class='bcode'>
- * 	<ja>@BeanProperty</ja>(swap=MyPojo.<jk>class</jk>)
- * 	<jk>public</jk> MyPojo getMyPojo();
- * </p>
- *
- *
- * <h6 class='topic'>One-way vs. Two-way Serialization</h6>
- *
- * Note that while there is a unified interface for handling swaps during both serialization and parsing,
- * in many cases only one of the {@link #swap(BeanSession, Object)} or {@link #unswap(BeanSession, Object, ClassMeta)}
- * methods will be defined because the swap is one-way.
- * <br>For example, a swap may be defined to convert an {@code Iterator} to a {@code ObjectList}, but
- * it's not possible to unswap an {@code Iterator}.
- * <br>In that case, the {@code swap(Object}} method would be implemented, but the {@code unswap(ObjectMap)} object would
- * not, and the swap would be associated on the serializer, but not the parser.
- * <br>Also, you may choose to serialize objects like {@code Dates} to readable {@code Strings}, in which case it's not
- * possible to re-parse it back into a {@code Date}, since there is no way for the {@code Parser} to know it's a
- * {@code Date} from just the JSON or XML text.
- *
- *
- * <h6 class='topic'>Per media-type swaps</h6>
- * <p>
- * The {@link #forMediaTypes()} method can be overridden to provide a set of media types that the swap is invoked on.
- * <br>It's also possible to define multiple swaps against the same POJO as long as they're differentiated by media type.
- * When multiple swaps are defined, the best-match media type is used.
- *
- * <p>
- * In the following example, we define 3 swaps against the same POJO.  One for JSON, one for XML, and one for all
- * other types.
- *
- * <p class='bcode'>
- * 	<jk>public class</jk> PojoSwapTest {
- *
- * 		<jk>public static class</jk> MyPojo {}
- *
- * 		<jk>public static class</jk> MyJsonSwap <jk>extends</jk> PojoSwap&lt;MyPojo,String&gt; {
- *
- * 			<jk>public</jk> MediaType[] forMediaTypes() {
- * 				<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/json"</js>);
- * 			}
- *
- * 			<jk>public</jk> String swap(BeanSession session, MyPojo o) <jk>throws</jk> Exception {
- * 				<jk>return</jk> <js>"It's JSON!"</js>;
- * 			}
- * 		}
- *
- * 		<jk>public static class</jk> MyXmlSwap <jk>extends</jk> PojoSwap&lt;MyPojo,String&gt; {
- *
- * 			<jk>public</jk> MediaType[] forMediaTypes() {
- * 				<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/xml"</js>);
- * 			}
- *
- * 			<jk>public</jk> String swap(BeanSession session, MyPojo o) <jk>throws</jk> Exception {
- * 				<jk>return</jk> <js>"It's XML!"</js>;
- * 			}
- * 		}
- *
- * 		<jk>public static class</jk> MyOtherSwap <jk>extends</jk> PojoSwap&lt;MyPojo,String&gt; {
- *
- * 			<jk>public</jk> MediaType[] forMediaTypes() {
- * 				<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/*"</js>);
- * 			}
- *
- * 			<jk>public</jk> String swap(BeanSession session, MyPojo o) <jk>throws</jk> Exception {
- * 				<jk>return</jk> <js>"It's something else!"</js>;
- * 			}
- * 		}
- *
- * 		<ja>@Test</ja>
- * 		<jk>public void</jk> doTest() <jk>throws</jk> Exception {
- *
- * 			SerializerGroup g = <jk>new</jk> SerializerGroupBuilder()
- * 				.append(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>, HtmlSerializer.<jk>class</jk>)
- * 				.sq()
- * 				.pojoSwaps(MyJsonSwap.<jk>class</jk>, MyXmlSwap.<jk>class</jk>, MyOtherSwap.<jk>class</jk>)
- * 				.build();
- *
- * 			MyPojo myPojo = <jk>new</jk> MyPojo();
- *
- * 			String json = g.getWriterSerializer(<js>"text/json"</js>).serialize(myPojo);
- * 			<jsm>assertEquals</jsm>(<js>"'It\\'s JSON!'"</js>, json);
- *
- * 			String xml = g.getWriterSerializer(<js>"text/xml"</js>).serialize(myPojo);
- * 			<jsm>assertEquals</jsm>(<js>"&lt;string&gt;It's XML!&lt;/string&gt;"</js>, xml);
- *
- * 			String html = g.getWriterSerializer(<js>"text/html"</js>).serialize(myPojo);
- * 			<jsm>assertEquals</jsm>(<js>"&lt;string&gt;It's something else!&lt;/string&gt;"</js>, html);
- * 		}
- * 	}
- * </p>
- *
- * <p>
- * Multiple swaps can be associated with a POJO by using the {@link Swaps @Swaps} annotation:
- *
- * <p class='bcode'>
- * 	<ja>@Swaps</ja>(
- * 		{
- * 			<ja>@Swap</ja>(MyJsonSwap.<jk>class</jk>),
- * 			<ja>@Swap</ja>(MyXmlSwap.<jk>class</jk>),
- * 			<ja>@Swap</ja>(MyOtherSwap.<jk>class</jk>)
- * 		}
- * 	)
- * 	<jk>public class</jk> MyPojo {}
- * </p>
- *
- * <p>
- * Note that since <code>Readers</code> get serialized directly to the output of a serializer, it's possible to
- * implement a swap that provides fully-customized output.
- *
- * <p class='bcode'>
- * 	<jk>public class</jk> MyJsonSwap <jk>extends</jk> PojoSwap&lt;MyPojo,Reader&gt; {
- *
- * 		<jk>public</jk> MediaType[] forMediaTypes() {
- * 			<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/json"</js>);
- * 		}
- *
- * 		<jk>public</jk> Reader swap(BeanSession session, MyPojo o) <jk>throws</jk> Exception {
- * 			<jk>return new</jk> StringReader(<js>"{message:'Custom JSON!'}"</js>);
- * 		}
- * 	}
- * </p>
- *
- *
- * <h6 class='topic'>Templates</h6>
- *
- * <p>
- * Template strings are arbitrary strings associated with swaps that help provide additional context information
- * for the swap class.
- * They're called 'templates' because their primary purpose is for providing template names, such as Apache FreeMarker
- * template names.
- *
- * <p>
- * The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:
- *
- * <p class='bcode'>
- * 	<jc>// Our abstracted templated swap class.</jc>
- * 	<jk>public abstract class</jk> FreeMarkerSwap <jk>extends</jk> PojoSwap&lt;Object,Reader&gt; {
- *
- * 		<jk>public</jk> MediaType[] forMediaTypes() {
- * 			<jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/html"</js>);
- * 		}
- *
- * 		<jk>public</jk> Reader swap(BeanSession session, Object o, String template) <jk>throws</jk> Exception {
- * 			<jk>return</jk> getFreeMarkerReader(template, o);  <jc>// Some method that creates raw HTML.</jc>
- * 		}
- * 	}
- *
- * 	<jc>// An implementation of our templated swap class.</jc>
- * 	<jk>public class</jk> MyPojoSwap <jk>extends</jk> FreeMarkerSwap {
- * 		<jk>public</jk> String withTemplate() {
- * 			<jk>return</jk> <js>"MyPojo.div.ftl"</js>;
- * 		}
- * 	}
- * </p>
- *
  * <p>
- * In practice however, the template is usually going to be defined on a <ja>@Swap</ja> annotation like the following
- * example:
- *
- * <p class='bcode'>
- * 	<ja>@Swap</ja>(impl=FreeMarkerSwap.<jk>class</jk>, template=<js>"MyPojo.div.ftl"</js>)
- * 	<jk>public class</jk> MyPojo {}
- * </p>
- *
- *
- * <h6 class='topic'>Localization</h6>
- *
- * Swaps have access to the session locale and timezone through the {@link BeanSession#getLocale()} and
- * {@link BeanSession#getTimeZone()} methods.
- * This allows you to specify localized swap values when needed.
- * If using the REST server API, the locale and timezone are set based on the <code>Accept-Language</code> and
- * <code>Time-Zone</code> headers on the request.
+ * The normal object representation of an object.
  *
  *
  * <h6 class='topic'>Documentation</h6>
  *	<ul>
  *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.PojoSwaps">Overview &gt; PojoSwaps</a>
- *		<li><a class="doclink" href="package-summary.html#PojoSwaps">org.apache.juneau.transform &gt; PojoSwap Class</a>
- *		<li><a class='doclink' href='org/apache/juneau/transform/package-summary.html#PojoSwaps_OneWay'>org.apache.juneau.transform &gt; One-Way PojoSwaps</a>
+ *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.SwapAnnotation">Overview &gt; @Swap Annotation</a>
  *	</ul>
  *
- *
  * @param <T> The normal form of the class.
  * @param <S> The swapped form of the class.
  */
@@ -379,6 +151,10 @@ public abstract class PojoSwap<T,S> {
 	 * <p>
 	 * This method is the programmatic equivalent to the {@link Swap#mediaTypes()} annotation.
 	 *
+	 * <h6 class='topic'>Documentation</h6>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.PerMediaTypePojoSwaps">Overview &gt; Per-media-type PojoSwaps</a>
+	 *	</ul>
 	 * @return The media types that this swap is applicable to, or <jk>null</jk> if it's applicable for all media types.
 	 */
 	public MediaType[] forMediaTypes() {
@@ -397,6 +173,11 @@ public abstract class PojoSwap<T,S> {
 	 * <p>
 	 * This method is the programmatic equivalent to the {@link Swap#template()} annotation.
 	 *
+	 *	<h5 class='section'>Documentation:</h5>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.TemplatedSwaps">Overview &gt; Templated Swaps</a>
+	 *	</ul>
+	 *
 	 * @return Additional context information, or <jk>null</jk> if not specified.
 	 */
 	public String withTemplate() {
@@ -406,6 +187,11 @@ public abstract class PojoSwap<T,S> {
 	/**
 	 * Sets the media types that this swap is associated with.
 	 *
+	 * <h6 class='topic'>Documentation</h6>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.PerMediaTypePojoSwaps">Overview &gt; Per-media-type PojoSwaps</a>
+	 *	</ul>
+	 *
 	 * @param mediaTypes The media types that this swap is associated with.
 	 * @return This object (for method chaining).
 	 */
@@ -417,6 +203,11 @@ public abstract class PojoSwap<T,S> {
 	/**
 	 * Sets the template string on this swap.
 	 *
+	 *	<h5 class='section'>Documentation:</h5>
+	 *	<ul>
+	 *		<li><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.TemplatedSwaps">Overview &gt; Templated Swaps</a>
+	 *	</ul>
+	 *
 	 * @param template The template string on this swap.
 	 * @return This object (for method chaining).
 	 */

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PropertyFilter.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PropertyFilter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PropertyFilter.java
new file mode 100644
index 0000000..52e5453
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PropertyFilter.java
@@ -0,0 +1,133 @@
+// ***************************************************************************************************************************
+// * 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.transform;
+
+/**
+ * Bean property filter.
+ * 
+ * <p>
+ * Registers a bean property filter with a bean class.
+ * 
+ * <p>
+ * Property filters can be used to intercept calls to getters and setters and alter their values in transit.
+ * 
+ *	<h5 class='section'>Example:</h5>
+ *	<p class='bcode'>
+ *		<jc>// Property filter that strips out sensitive information on Address beans.</jc>
+ *		<jk>public class</jk> AddressPropertyFilter <jk>extends</jk> PropertyFilter {
+ *
+ *			<ja>@Override</ja>
+ *			<jk>public</jk> Object readProperty(Object bean, String name, Object value) {
+ *				<jk>if</jk> (<js>"taxInfo"</js>.equals(name))
+ *					<jk>return</jk> <js>"redacted"</js>;
+ *				<jk>return</jk> value;
+ *			}
+ *
+ *			<ja>@Override</ja>
+ *			<jk>public</jk> Object writeProperty(Object bean, String name, Object value) {
+ *				AddressBook a = (Address)bean;
+ *				<jk>if</jk> (<js>"taxInfo"</js>.equals(name) && <js>"redacted"</js>.equals(value))
+ *					<jk>return</jk> TaxInfoUtils.<jsm>lookUpByName</jsm>(a.getStreet(), a.getCity(), a.getState());
+ *				<jk>return</jk> value;
+ *			}
+ *		}
+ *	</p>
+ *	
+ *	<p>
+ *	Property filters are registered in the following ways:
+ *	<ul>
+ *		<li class='ja'>{@link org.apache.juneau.annotation.Bean#propertyFilter() @Bean.propertyFilter()}
+ *		<li class='jm'>{@link org.apache.juneau.transform.BeanFilterBuilder#propertyFilter(Class)}
+ *	</ul>	
+ * 
+ *	<h5 class='section'>Example:</h5>
+ *	<p class='bcode'>
+ *		<jc>// Register filter on bean class.</jc>
+ *		<ja>@Bean</ja>(propertyFilter=AddressPropertyFilter.<jk>class</jk>)
+ *		<jk>public class Address {
+ *			<jk>public</jk> String getTaxInfo() {...}
+ *			<jk>public void</jk> setTaxInfo(String s) {...}
+ *		}
+ *
+ *		<jc>// Register filter on serializer or parser.</jc>
+ *		WriterSerializer s = JsonSerializer
+ *			.<jsm>create</jsm>()
+ *			.beanFilters(BeanFilter.<jsm>create</jsm>().propertyFilter(AddressPropertyFilter.<jk>class</jk>))
+ *			.build();
+ *	</p>
+ */
+public class PropertyFilter {
+	
+	/**
+	 * Default reusable property filter instance.
+	 */
+	public static final PropertyFilter DEFAULT = new PropertyFilter();
+	
+	/**
+	 * Property read interceptor.
+	 * 
+	 * <p>
+	 * Subclasses can override this property to convert property values to some other object just before serialization.
+	 * 
+	 *	<h5 class='section'>Example:</h5>
+	 *	<p class='bcode'>
+	 *		<jc>// Address filter that strips out sensitive information.</jc>
+	 *		<jk>public class</jk> AddressPropertyFilter <jk>extends</jk> PropertyFilter {
+	 *
+	 *			<jk>public</jk> Object readProperty(Object bean, String name, Object value) {
+	 *				<jk>if</jk> (<js>"taxInfo"</js>.equals(name))
+	 *					<jk>return</jk> <js>"redacted"</js>;
+	 *				<jk>return</jk> value;
+	 *			}
+	 *		}
+	 *	</p>	
+	 *
+	 * @param bean The bean from which the property was read.
+	 * @param name The property name.
+	 * @param value The value just extracted from calling the bean getter.
+	 * @return The value to serialize.  Default is just to return the existing value.
+	 */
+	public Object readProperty(Object bean, String name, Object value) {
+		return value;
+	}
+
+	/**
+	 * Property write interceptor.
+	 * 
+	 * <p>
+	 * Subclasses can override this property to convert property values to some other object just before calling the
+	 * bean setter.
+	 *
+	 *	<h5 class='section'>Example:</h5>
+	 *	<p class='bcode'>
+	 *		<jc>// Address filter that strips out sensitive information.</jc>
+	 *		<jk>public class</jk> AddressPropertyFilter <jk>extends</jk> PropertyFilter {
+	 *
+	 *			<jk>public</jk> Object writeProperty(Object bean, String name, Object value) {
+	 *				AddressBook a = (Address)bean;
+	 *				<jk>if</jk> (<js>"taxInfo"</js>.equals(name) && <js>"redacted"</js>.equals(value))
+	 *					<jk>return</jk> TaxInfoUtils.<jsm>lookUpByName</jsm>(a.getStreet(), a.getCity(), a.getState());
+	 *				<jk>return</jk> value;
+	 *			}
+	 *		}
+	 *	</p>	
+	 *
+	 * @param bean The bean from which the property was read.
+	 * @param name The property name.
+	 * @param value The value just parsed.
+	 * @return The value to serialize.  Default is just to return the existing value.
+	 */
+	public Object writeProperty(Object bean, String name, Object value) {
+		return value;
+	}
+}

http://git-wip-us.apache.org/repos/asf/juneau/blob/4e501d6a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MessageBundle.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MessageBundle.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MessageBundle.java
index de72e36..ce1f34d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MessageBundle.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MessageBundle.java
@@ -20,7 +20,6 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
 
 /**
  * Wraps a {@link ResourceBundle} to provide some useful additional functionality.
@@ -47,8 +46,12 @@ import org.apache.juneau.annotation.*;
  * 		For example, if the class is <code>MyClass</code> and the properties file contains <js>"MyClass.myMessage"</js>,
  * 		the message can be retrieved using <code>getString(<js>"myMessage"</js>)</code>.
  * </ul>
+ * 
+ *	<h5 class='section'>Notes:</h5>
+ *	<ul>
+ *		<li>This class is thread-safe.
+ *	</ul>
  */
-@ThreadSafe
 public class MessageBundle extends ResourceBundle {
 
 	private static final ThreadLocal<Locale> clientLocale = new ThreadLocal<>();


Mime
View raw message