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/03/31 22:42:52 UTC

[1/3] incubator-juneau git commit: Add @RestResource.pageTitle/pageText/pageLinks annotations.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master a0580074c -> 703cadd2d


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
index 2fb2560..8125cdc 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
@@ -31,6 +31,7 @@ import javax.servlet.http.*;
 import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.encoders.*;
+import org.apache.juneau.html.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
@@ -67,6 +68,7 @@ class CallMethod implements Comparable<CallMethod>  {
 	private final org.apache.juneau.rest.annotation.Parameter[] parameters;
 	private final Response[] responses;
 	private final RestContext context;
+	private final String pageTitle, pageText, pageLinks;
 
 	CallMethod(Object servlet, java.lang.reflect.Method method, RestContext context) throws RestServletException {
 		Builder b = new Builder(servlet, method, context);
@@ -95,10 +97,13 @@ class CallMethod implements Comparable<CallMethod>  {
 		this.priority = b.priority;
 		this.parameters = b.parameters;
 		this.responses = b.responses;
+		this.pageTitle = b.pageTitle;
+		this.pageText = b.pageText;
+		this.pageLinks = b.pageLinks;
 	}
 
 	private static class Builder  {
-		private String httpMethod, defaultCharset, description, tags, summary, externalDocs;
+		private String httpMethod, defaultCharset, description, tags, summary, externalDocs, pageTitle, pageText, pageLinks;
 		private UrlPathPattern pathPattern;
 		private CallMethod.MethodParam[] params;
 		private RestGuard[] guards;
@@ -141,6 +146,10 @@ class CallMethod implements Comparable<CallMethod>  {
 				encoders = context.getEncoders();
 				properties = context.getProperties();
 
+				pageTitle = m.pageTitle().isEmpty() ? context.getPageTitle() : m.pageTitle();
+				pageText = m.pageText().isEmpty() ? context.getPageText() : m.pageText();
+				pageLinks = m.pageLinks().isEmpty() ? context.getPageLinks() : m.pageLinks();
+
 				List<Inherit> si = Arrays.asList(m.serializersInherit());
 				List<Inherit> pi = Arrays.asList(m.parsersInherit());
 
@@ -164,7 +173,7 @@ class CallMethod implements Comparable<CallMethod>  {
 				if (httpMethod.equals("") && method.getName().startsWith("do"))
 					httpMethod = method.getName().substring(2).toUpperCase(Locale.ENGLISH);
 				if (httpMethod.equals(""))
-					throw new RestServletException("@RestMethod name not specified on method ''{0}.{1}''", method.getDeclaringClass().getName(), method.getName());
+					httpMethod = "GET";
 				if (httpMethod.equals("METHOD"))
 					httpMethod = "*";
 
@@ -287,6 +296,8 @@ class CallMethod implements Comparable<CallMethod>  {
 
 				// Need this to access methods in anonymous inner classes.
 				method.setAccessible(true);
+			} catch (RestServletException e) {
+				throw e;
 			} catch (Exception e) {
 				throw new RestServletException("Exception occurred while initializing method ''{0}''", method.getName()).initCause(e);
 			}
@@ -808,8 +819,9 @@ class CallMethod implements Comparable<CallMethod>  {
 		for (int i = 0; i < pathPattern.getVars().length; i++)
 			req.setPathParameter(pathPattern.getVars()[i], patternVals[i]);
 
-		req.init(method, remainder, createRequestProperties(properties, req), defaultRequestHeaders, defaultCharset, serializers, parsers, urlEncodingParser, encoders);
-		res.init(req.getProperties(), defaultCharset, serializers, urlEncodingSerializer, encoders);
+		ObjectMap requestProperties = createRequestProperties(properties, req);
+		req.init(method, remainder, requestProperties, defaultRequestHeaders, defaultCharset, serializers, parsers, urlEncodingParser, encoders, pageTitle, pageText, pageLinks);
+		res.init(requestProperties, defaultCharset, serializers, urlEncodingSerializer, encoders);
 
 		// Class-level guards
 		for (RestGuard guard : context.getGuards())
@@ -888,7 +900,7 @@ class CallMethod implements Comparable<CallMethod>  {
 	/**
 	 * This method creates all the request-time properties.
 	 */
-	static ObjectMap createRequestProperties(final ObjectMap methodProperties, final RestRequest req) {
+	ObjectMap createRequestProperties(final ObjectMap methodProperties, final RestRequest req) {
 		@SuppressWarnings("serial")
 		ObjectMap m = new ObjectMap() {
 			@Override /* Map */
@@ -933,6 +945,12 @@ class CallMethod implements Comparable<CallMethod>  {
 						return req.getMethodSummary();
 					if (k.equals(REST_methodDescription))
 						return req.getMethodDescription();
+					if (k.equals(HtmlDocSerializerContext.HTMLDOC_title))
+						return req.getPageTitle();
+					if (k.equals(HtmlDocSerializerContext.HTMLDOC_text))
+						return req.getPageText();
+					if (k.equals(HtmlDocSerializerContext.HTMLDOC_links))
+						return req.getPageLinks();
 					o = req.getPathParameter(k);
 					if (o == null)
 						o = req.getHeader(k);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java b/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
index 5fd0268..7556006 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
@@ -67,13 +67,13 @@ public class ReaderResource implements Writable {
 	 *	</ul>
 	 * @throws IOException
 	 */
-	public ReaderResource(MediaType mediaType, Map<String,Object> headers, VarResolverSession varSession, Object...contents) throws IOException {
+	public ReaderResource(MediaType mediaType, Map<String,String> headers, VarResolverSession varSession, Object...contents) throws IOException {
 		this.mediaType = mediaType;
 		this.varSession = varSession;
 
 		Map<String,String> m = new LinkedHashMap<String,String>();
 		if (headers != null)
-			for (Map.Entry<String,Object> e : headers.entrySet())
+			for (Map.Entry<String,String> e : headers.entrySet())
 				m.put(e.getKey(), StringUtils.toString(e.getValue()));
 		this.headers = Collections.unmodifiableMap(m);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
index 7eebe50..0197cbc 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
@@ -100,7 +100,7 @@ public class RestConfig implements ServletConfig {
 	Object favIcon;
 	List<Object> staticFiles;
 	RestContext parentContext;
-	String path;
+	String path, pageTitle, pageText, pageLinks;
 	String clientVersionHeader = "X-Client-Version";
 
 	Object resourceResolver = RestResourceResolver.class;
@@ -193,6 +193,12 @@ public class RestConfig implements ServletConfig {
 					setPath(r.path());
 				if (! r.clientVersionHeader().isEmpty())
 					setClientVersionHeader(r.clientVersionHeader());
+				if (! r.pageTitle().isEmpty())
+					setPageTitle(r.pageTitle());
+				if (! r.pageText().isEmpty())
+					setPageText(r.pageText());
+				if (! r.pageLinks().isEmpty())
+					setPageLinks(r.pageLinks());
 				if (r.resourceResolver() != RestResourceResolver.class)
 					setResourceResolver(r.resourceResolver());
 				if (r.logger() != RestLogger.Normal.class)
@@ -969,6 +975,45 @@ public class RestConfig implements ServletConfig {
 	}
 
 	/**
+	 * Sets the page title to use on HTML views of pages.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageTitle() @RestResource.pageTitle()} annotation.
+	 *
+	 * @param pageTitle The page title text.
+	 * @return This object (for method chaining).
+	 */
+	public RestConfig setPageTitle(String pageTitle) {
+		this.pageTitle = pageTitle;
+		return this;
+	}
+
+	/**
+	 * Sets the page text to use on HTML views of pages.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageText() @RestResource.pageText()} annotation.
+	 *
+	 * @param pageText The page text.
+	 * @return This object (for method chaining).
+	 */
+	public RestConfig setPageText(String pageText) {
+		this.pageText = pageText;
+		return this;
+	}
+
+	/**
+	 * Sets the page links to use on HTML views of pages.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageLinks() @RestResource.pageLinks()} annotation.
+	 *
+	 * @param pageLinks The page links.
+	 * @return This object (for method chaining).
+	 */
+	public RestConfig setPageLinks(String pageLinks) {
+		this.pageLinks = pageLinks;
+		return this;
+	}
+
+	/**
 	 * Overrides the logger for the resource.
 	 * <p>
 	 * This is the programmatic equivalent to the {@link RestResource#logger() @RestResource.logger()} annotation.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
index ae3aa22..2e39b74 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -277,6 +277,7 @@ public final class RestContext extends Context {
 	 */
 	public static final String REST_methodDescription = "RestServlet.methodDescription";
 
+
 	private final Object resource;
 	private final RestConfig config;
 	private final boolean
@@ -288,7 +289,8 @@ public final class RestContext extends Context {
 		defaultCharset,
 		paramFormat,
 		clientVersionHeader,
-		fullPath;
+		fullPath,
+		pageTitle, pageText, pageLinks;
 	private final Set<String> allowMethodParams;
 
 	private final ObjectMap properties;
@@ -382,6 +384,9 @@ public final class RestContext extends Context {
 			this.childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());  // Not unmodifiable on purpose so that children can be replaced.
 			this.logger = b.logger;
 			this.fullPath = b.fullPath;
+			this.pageTitle = b.pageTitle;
+			this.pageText = b.pageText;
+			this.pageLinks = b.pageLinks;
 
 			//----------------------------------------------------------------------------------------------------
 			// Initialize the child resources.
@@ -559,7 +564,7 @@ public final class RestContext extends Context {
 		UrlEncodingSerializer urlEncodingSerializer;
 		UrlEncodingParser urlEncodingParser;
 		EncoderGroup encoders;
-		String clientVersionHeader = "", defaultCharset, paramFormat;
+		String clientVersionHeader = "", defaultCharset, paramFormat, pageTitle, pageText, pageLinks;
 		List<MediaType> supportedContentTypes, supportedAcceptTypes;
 		Map<String,String> defaultRequestHeaders = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
 		Map<String,Object> defaultResponseHeaders;
@@ -696,6 +701,10 @@ public final class RestContext extends Context {
 			logger = sc.logger == null ? new RestLogger.NoOp() : resolve(RestLogger.class, sc.logger);
 
 			fullPath = (sc.parentContext == null ? "" : (sc.parentContext.fullPath + '/')) + sc.path;
+
+			pageTitle = sc.pageTitle;
+			pageText = sc.pageText;
+			pageLinks = sc.pageLinks;
 		}
 	}
 
@@ -728,7 +737,7 @@ public final class RestContext extends Context {
 	 * 		properties={
 	 * 			<ja>@Property</ja>(
 	 * 				name=<jsf>HTMLDOC_links</jsf>,
-	 * 				value=<js>"{up:'$R{requestParentURI}', options:'?method=OPTIONS', editLevel:'$R{servletURI}/editLevel?logger=$R{attribute.name}'}"</js>
+	 * 				value=<js>"{up:'$R{requestParentURI}', options:'?method=OPTIONS', editLevel:'editLevel?logger=$R{attribute.name}'}"</js>
 	 * 			)
 	 * 		}
 	 * 	)
@@ -917,6 +926,33 @@ public final class RestContext extends Context {
 	}
 
 	/**
+	 * Returns the page title as defined by the {@link RestResource#pageTitle()} annotation or {@link RestConfig#setPageTitle(String)} method.
+	 *
+	 * @return The page title.
+	 */
+	public String getPageTitle() {
+		return pageTitle;
+	}
+
+	/**
+	 * Returns the page text as defined by the {@link RestResource#pageText()} annotation or {@link RestConfig#setPageText(String)} method.
+	 *
+	 * @return The page text.
+	 */
+	public String getPageText() {
+		return pageText;
+	}
+
+	/**
+	 * Returns the page links as defined by the {@link RestResource#pageLinks()} annotation or {@link RestConfig#setPageLinks(String)} method.
+	 *
+	 * @return The page links.
+	 */
+	public String getPageLinks() {
+		return pageLinks;
+	}
+
+	/**
 	 * Returns the logger to use for this resource.
 	 * <p>
 	 * The logger for a resource is defined via one of the following:

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/RestLogger.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestLogger.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestLogger.java
index da266de..aa713b3 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestLogger.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestLogger.java
@@ -194,7 +194,7 @@ public abstract class RestLogger {
 	}
 
 	private static boolean isNoTrace(HttpServletRequest req) {
-		return "true".equals(req.getHeader("No-Trace")) || req.getQueryString().contains("noTrace=true");
+		return "true".equals(req.getHeader("No-Trace")) || (req.getQueryString() != null && req.getQueryString().contains("noTrace=true"));
 	}
 
 	private static boolean isDebug(HttpServletRequest req) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
index e9d5936..28bfb2a 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -89,6 +89,7 @@ public final class RestRequest extends HttpServletRequestWrapper {
 	private ObjectMap headers;
 	private ConfigFile cf;
 	private Swagger swagger, fileSwagger;
+	private String pageTitle, pageText, pageLinks;
 
 	/**
 	 * Constructor.
@@ -141,7 +142,7 @@ public final class RestRequest extends HttpServletRequestWrapper {
 	 * Called from RestServlet after a match has been made but before the guard or method invocation.
 	 */
 	@SuppressWarnings("hiding")
-	final void init(Method javaMethod, String pathRemainder, ObjectMap properties, Map<String,String> mDefaultRequestHeaders, String defaultCharset, SerializerGroup mSerializers, ParserGroup mParsers, UrlEncodingParser mUrlEncodingParser, EncoderGroup encoders) {
+	final void init(Method javaMethod, String pathRemainder, ObjectMap properties, Map<String,String> mDefaultRequestHeaders, String defaultCharset, SerializerGroup mSerializers, ParserGroup mParsers, UrlEncodingParser mUrlEncodingParser, EncoderGroup encoders, String pageTitle, String pageText, String pageLinks) {
 		this.javaMethod = javaMethod;
 		this.pathRemainder = pathRemainder;
 		this.properties = properties;
@@ -152,6 +153,9 @@ public final class RestRequest extends HttpServletRequestWrapper {
 		this.beanSession = urlEncodingParser.getBeanContext().createSession();
 		this.defaultCharset = defaultCharset;
 		this.encoders = encoders;
+		this.pageTitle = pageTitle;
+		this.pageText = pageText;
+		this.pageLinks = pageLinks;
 
 		if (debug) {
 			String msg = ""
@@ -1621,6 +1625,56 @@ public final class RestRequest extends HttpServletRequestWrapper {
 		return context.getInfoProvider().getMethodDescription(javaMethod.getName(), this);
 	}
 
+	/**
+	 * Returns the localized page title for HTML views.
+	 *
+	 * @return The localized page title for HTML views.
+	 */
+	protected String getPageTitle() {
+		String s = pageTitle;
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), javaMethod.getName() + ".pageTitle");
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), "pageTitle");
+		if (! StringUtils.isEmpty(s))
+			return resolveVars(s);
+		s = getServletTitle();
+		return s;
+	}
+
+	/**
+	 * Returns the localized page text for HTML views.
+	 *
+	 * @return The localized page text for HTML views.
+	 */
+	protected String getPageText() {
+		String s = pageText;
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), javaMethod.getName() + ".pageText");
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), "pageText");
+		if (! StringUtils.isEmpty(s))
+			return resolveVars(s);
+		s = getMethodSummary();
+		if (StringUtils.isEmpty(s))
+			s = getServletDescription();
+		return s;
+	}
+
+	/**
+	 * Returns the localized page links for HTML views.
+	 *
+	 * @return The localized page links for HTML views.
+	 */
+	protected String getPageLinks() {
+		String s = pageLinks;
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), javaMethod.getName() + ".pageLinks");
+		if (StringUtils.isEmpty(s))
+			s = context.getMessages().findFirstString(getLocale(), "pageLinks");
+		return resolveVars(s);
+	}
+
 
 	//--------------------------------------------------------------------------------
 	// Other methods

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/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 637dc7e..2d50376 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
@@ -21,10 +21,13 @@ import javax.servlet.http.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.encoders.*;
+import org.apache.juneau.html.*;
 import org.apache.juneau.jena.*;
 import org.apache.juneau.json.*;
+import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -40,7 +43,7 @@ import org.apache.juneau.xml.*;
  * <p class='bcode'>
  * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>)
  * 	<jk>public void</jk> doGet(RestRequest req, RestResponse res) {
- * 		res.setProperty(HtmlSerializerContext.<jsf>HTMLDOC_title</jsf>, <js>"My title"</js>)
+ * 		res.setPageTitle(<js>"My title"</js>)
  * 			.setOutput(<js>"Simple string response"</js>);
  * 	}
  * </p>
@@ -413,4 +416,63 @@ public final class RestResponse extends HttpServletResponseWrapper {
 		else
 			super.setHeader(name, value);
 	}
-}
+
+	/**
+	 * Sets the page title for HTML views.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageTitle() @RestResource#pageTitle()}/
+	 * {@link RestMethod#pageTitle() @RestMethod#pageTitle()} annotations.
+	 * <p>
+	 * This is a shortcut for calling <code>setProperty(<jsf>HTMLDOC_title</jsf>, title);</code>
+	 * <p class='info'>
+	 * 	<b>Tip:</b>  Use {@link StringMessage} to generate a page title with delayed serialization so as not to
+	 * 	waste string concatenation cycles on non-HTML views.
+	 * </p>
+	 *
+	 * @param title The localized page title to render on the page.
+	 * Object will be converted to a string using {@link Object#toString()}.
+	 * @return This object (for method chaining).
+	 */
+	public RestResponse setPageTitle(Object title) {
+		return setProperty(HtmlDocSerializerContext.HTMLDOC_title, title);
+	}
+
+	/**
+	 * Sets the page text for HTML views.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageText() @RestResource#pageText()}/
+	 * {@link RestMethod#pageText() @RestMethod#pageText()} annotations.
+	 * <p>
+	 * This is a shortcut for calling <code>setProperty(<jsf>HTMLDOC_text</jsf>, text);</code>
+	 * <p class='info'>
+	 * 	<b>Tip:</b>  Use {@link StringMessage} to generate page text with delayed serialization so as not to
+	 * 	waste string concatenation cycles on non-HTML views.
+	 * </p>
+	 *
+	 * @param text The localized page text to render on the page.
+	 * @return This object (for method chaining).
+	 */
+	public RestResponse setPageText(Object text) {
+		return setProperty(HtmlDocSerializerContext.HTMLDOC_text, text);
+	}
+
+	/**
+	 * Sets the page text for HTML views.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#pageLinks() @RestResource#pageLinks()}/
+	 * {@link RestMethod#pageLinks() @RestMethod#pageLinks()} annotations.
+	 * <p>
+	 * This is a shortcut for calling <code>setProperty(<jsf>HTMLDOC_links</jsf>, links);</code>
+	 * <p class='info'>
+	 * 	<b>Tip:</b>  Use {@link StringMessage} to generate page links with delayed serialization so as not to
+	 * 	waste string concatenation cycles on non-HTML views.
+	 * </p>
+	 *
+	 * @param links The localized page links render on the page.
+	 * @return This object (for method chaining).
+	 */
+	public RestResponse setPageLinks(Object links) {
+		properties.put(HtmlDocSerializerContext.HTMLDOC_links, links);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
index 8117108..51252b2 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.rest.RestContext.*;
 
 import org.apache.juneau.dto.swagger.*;
@@ -183,10 +182,6 @@ import org.apache.juneau.xml.*;
 	properties={
 		// Allow &method parameter on safe HTTP methods.
 		@Property(name=REST_allowMethodParam, value="OPTIONS"),
-		// Provide a default title on HTML pages.
-		@Property(name=HTMLDOC_title, value="$R{servletTitle}"),
-		// Provide a default description on HTML pages.
-		@Property(name=HTMLDOC_description, value="$R{servletDescription}")
 	},
 	stylesheet="styles/juneau.css",
 	favicon="juneau.png",
@@ -202,11 +197,9 @@ public abstract class RestServletDefault extends RestServlet {
 	 * @return A bean containing the contents for the OPTIONS page.
 	 */
 	@RestMethod(name="OPTIONS", path="/*",
-		properties={
-			@Property(name=HTMLDOC_links, value="{back:'$R{servletURI}'}"),
-			@Property(name=HTMLDOC_description, value="Resource options")
-		},
-		description="Resource options"
+		pageLinks="{back:'$R{servletURI}'}",
+		summary="Resource options",
+		description="Description of this resource"
 	)
 	public Swagger getOptions(RestRequest req) {
 		return req.getSwagger();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index 4270a38..986aa74 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -50,6 +50,7 @@ public @interface RestMethod {
 	 * 	<li><js>""</js> - Auto-detect.
 	 * 		<br>The method name is determined based on the Java method name.
 	 * 		<br>For example, if the method is <code>doPost(...)</code>, then the method name is automatically detected as <js>"POST"</js>.
+	 * 		<br>Otherwise, defaults to <js>"GET"</js>.
 	 * 	<li><js>"PROXY"</js> - Remote-proxy interface.
 	 * 		<br>This denotes a Java method that returns an object (usually an interface, often annotated with the {@link Remoteable @Remoteable} annotation)
 	 * 		to be used as a remote proxy using <code>RestClient.getRemoteableProxy(Class<T> interfaceClass, String url)</code>.
@@ -518,7 +519,17 @@ public @interface RestMethod {
 	String clientVersion() default "";
 
 	/**
-	 * TODO
+	 * Overrides the HTML page title defined on the servlet via the {@link RestResource#pageTitle() @RestResource.pageTitle()} annotation.
 	 */
-	String[] links() default "";
+	String pageTitle() default "";
+
+	/**
+	 * Overrides the HTML page text defined on the servlet via the {@link RestResource#pageText() @RestResource.pageText()} annotation.
+	 */
+	String pageText() default "";
+
+	/**
+	 * Overrides the HTML page links defined on the servlet via the {@link RestResource#pageLinks() @RestResource.pageLinks()} annotation.
+	 */
+	String pageLinks() default "";
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index b49bdd3..8492770 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -21,6 +21,7 @@ import javax.servlet.http.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.encoders.Encoder;
+import org.apache.juneau.html.*;
 import org.apache.juneau.ini.*;
 import org.apache.juneau.jena.*;
 import org.apache.juneau.json.*;
@@ -315,7 +316,7 @@ public @interface RestResource {
 	/**
 	 * Optional servlet title.
 	 * <p>
-	 * It is used to populate the Swagger title field and to display on HTML pages.
+	 * It is used to populate the Swagger title field and as a default value for the {@link #pageTitle()} value.
 	 * This value can be retrieved programmatically through the {@link RestRequest#getServletTitle()} method.
 	 * <p>
 	 * The default value pulls the label from the <code>label</code> entry in the servlet resource bundle.
@@ -332,7 +333,7 @@ public @interface RestResource {
 	/**
 	 * Optional servlet description.
 	 * <p>
-	 * It is used to populate the Swagger description field and to display on HTML pages.
+	 * It is used to populate the Swagger description field and as a default value for the {@link #pageText()} value.
 	 * This value can be retrieved programmatically through the {@link RestRequest#getServletDescription()} method.
 	 * <p>
 	 * The default value pulls the description from the <code>description</code> entry in the servlet resource bundle.
@@ -695,7 +696,103 @@ public @interface RestResource {
 	Class<? extends RestInfoProvider> infoProvider() default RestInfoProvider.class;
 
 	/**
-	 * TODO
+	 * Specifies the page title to use on the HTML view of all pages produced by this resource.
+	 * <p>
+	 * This annotation has no effect on any serializers other than {@link HtmlDocSerializer} and is a shorthand method
+	 * for setting the {@link HtmlDocSerializerContext#HTMLDOC_title} property:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		properties={
+	 * 			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"My Resource Page"</js>)
+	 * 		}
+	 * 	)
+	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault {
+	 * </p>
+	 * <p>
+	 * If not specified, the page title is pulled from one of the following locations:
+	 * <ol>
+	 * 	<li><code>{servletClass}.{methodName}.pageTitle</code> resource bundle value.
+	 * 	<li><code>{servletClass}.pageTitle</code> resource bundle value.
+	 * 	<li><code><ja>@RestResource</ja>(title)</code> annotation.
+	 * 	<li><code>{servletClass}.title</code> resource bundle value.
+	 * 	<li><code>info/title</code> entry in swagger file.
+	 * <ol>
+	 * <p>
+	 * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>).
+	 * <p>
+	 * The programmatic equivalent to this annotation are the {@link RestConfig#setPageTitle(String)}/{@link RestResponse#setPageTitle(Object)} methods.
+	 * <p class='info'>
+	 * 	In most cases, you'll simply want to use the <code>@RestResource(title)</code> annotation to specify the page title.
+	 * 	However, this annotation is provided in cases where you want the page title to be different that the one
+	 * 	shown in the swagger document.
+	 * </p>
+	 * <b>Note:</b> - In most cases, you can
+	 */
+	String pageTitle() default "";
+
+	/**
+	 * Specifies the page text to use on the HTML view of all pages produced by this resource.
+	 * <p>
+	 * The page text is portion of the page immediately under the title and above the links.
+	 * <p>
+	 * This annotation has no effect on any serializers other than {@link HtmlDocSerializer} and is a shorthand method
+	 * for setting the {@link HtmlDocSerializerContext#HTMLDOC_text} property:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		properties={
+	 * 			<ja>@Property</ja>(name=<jsf>HTMLDOC_text</jsf>, value=<js>"This is my awesome resource page"</js>)
+	 * 		}
+	 * 	)
+	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault {
+	 * </p>
+	 * If not specified, the page title is pulled from one of the following locations:
+	 * <ol>
+	 * 	<li><code>{servletClass}.{methodName}.pageText</code> resource bundle value.
+	 * 	<li><code>{servletClass}.pageText</code> resource bundle value.
+	 * 	<li><code><ja>@RestMethod</ja>(summary)</code> annotation.
+	 * 	<li><code>{servletClass}.{methodName}.summary</code> resource bundle value.
+	 * 	<li><code>summary</code> entry in swagger file for method.
+	 * 	<li><code>{servletClass}.description</code> resource bundle value.
+	 * 	<li><code>info/description</code> entry in swagger file.
+	 * <ol>
+	 * <p>
+	 * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>).
+	 * <p>
+	 * The programmatic equivalent to this annotation are the {@link RestConfig#setPageText(String)}/{@link RestResponse#setPageText(Object)} methods.
+	 * <p class='info'>
+	 * 	In most cases, you'll simply want to use the <code>@RestResource(description)</code> or <code>@RestMethod(summary)</code> annotations to specify the page text.
+	 * 	However, this annotation is provided in cases where you want the text to be different that the values shown in the swagger document.
+	 * </p>
+	 */
+	String pageText() default "";
+
+	/**
+	 * Specifies the page hyperlinks to use on the HTML view of all pages produced by this resource.
+	 * <p>
+	 * The page links is positioned immediately under the title and text.
+	 * <p>
+	 * This annotation has no effect on any serializers other than {@link HtmlDocSerializer} and is a shorthand method
+	 * for setting the {@link HtmlDocSerializerContext#HTMLDOC_text} property:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		properties={
+	 * 			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>)
+	 * 		}
+	 * 	)
+	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault {
+	 * </p>
+	 * <p>
+	 * The format of this value is a lax-JSON string of key/value pairs where the keys are the link text and the values are relative (to the servlet) or
+	 * absolute URLs.
+	 * If not specified, the page title is pulled from one of the following locations:
+	 * <ol>
+	 * 	<li><code>{servletClass}.{methodName}.pageLinks</code> resource bundle value.
+	 * 	<li><code>{servletClass}.pageLinks</code> resource bundle value.
+	 * <ol>
+	 * <p>
+	 * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>).
+	 * <p>
+	 * The programmatic equivalent to this annotation are the {@link RestConfig#setPageLinks(String)}/{@link RestResponse#setPageLinks(Object)} methods.
 	 */
-	String[] links() default "";
+	String pageLinks() default "";
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java b/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
index be489da..4b26bcb 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.jena;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.rest.RestContext.*;
 
 import org.apache.juneau.dto.swagger.*;
@@ -223,11 +222,7 @@ import org.apache.juneau.xml.*;
 	},
 	properties={
 		// Allow &method parameter on safe HTTP methods.
-		@Property(name=REST_allowMethodParam, value="OPTIONS"),
-		// Provide a default title on HTML pages.
-		@Property(name=HTMLDOC_title, value="$R{servletTitle}"),
-		// Provide a default description on HTML pages.
-		@Property(name=HTMLDOC_description, value="$R{servletDescription}")
+		@Property(name=REST_allowMethodParam, value="OPTIONS")
 	},
 	stylesheet="styles/juneau.css",
 	favicon="juneau.ico",
@@ -243,10 +238,8 @@ public abstract class RestServletJenaDefault extends RestServlet {
 	 * @return The bean containing the contents of the OPTIONS page.
 	 */
 	@RestMethod(name="OPTIONS", path="/*",
-		properties={
-			@Property(name=HTMLDOC_links, value="{back:'$R{servletURI}'}"),
-			@Property(name=HTMLDOC_description, value="Resource options")
-		},
+		summary="Resource options",
+		pageLinks="{back:'$R{servletURI}'}",
 		description="Resource options"
 	)
 	public Swagger getOptions(RestRequest req) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
index 6b08a70..f6f9cb4 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
@@ -226,9 +226,7 @@
 	 */</jd>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/HelloWorldResource"</js>, 
-		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>)
-		}
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
 	)
 	<jk>public class</jk> HelloWorldResource <jk>extends</jk> Resource {
 	
@@ -1037,11 +1035,8 @@
 	 * <ja>@return</ja> A bean containing the contents for the OPTIONS page.
 	 */</jd>
 	<ja>@RestMethod</ja>(name=<js>"OPTIONS"</js>, path=<js>"/*"</js>,
-		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{back:'$R{servletURI}'}"</js>),
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"Resource options"</js>)
-		},
-		description=<js>"Resource options"</js>
+		summary=<js>"Resource options"</js>,
+		pageLinks=<js>"{back:'$R{servletURI}'}"</js>
 	)
 	<jk>public</jk> Swagger getOptions(RestRequest req) {
 		<jk>return</jk> req.getSwagger();
@@ -1116,12 +1111,8 @@
 		</p>
 		<p class='bcode'>
 	<ja>@RestResource</ja>(
-		properties={
-			<jc>// Provide a default title on HTML pages.</jc>
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"$R{servletTitle}"</js>),
-			<jc>// Provide a default description on HTML pages.</jc>
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"$R{servletDescription}"</js>)
-		}
+		pageTitle=<js>"The title for this page is $R{servletTitle}"</js>,
+		pageText=<js>"The description for this page is $R{servletDescription}"</js>
 	)
 	<jk>public abstract class</jk> RestServletDefault <jk>extends</jk> RestServlet {
 	 	</p>
@@ -1430,6 +1421,7 @@
 				value=<js>"{jp06:'http://jazz.net/xmlns/prod/jazz/process/0.6/',jp:'http://jazz.net/xmlns/prod/jazz/process/1.0/'}"</js>),
 
 			<jc>// Specify a default title for the HtmlSerializer serializer</jc>
+			<jc>// This is equivalent to @RestResource(title/pageTitle)</jc>
 			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"My resource"</js>)
 		}
 	)
@@ -1457,6 +1449,7 @@
 				value=<js>"{jp06:'http://jazz.net/xmlns/prod/jazz/process/0.6/',jp:'http://jazz.net/xmlns/prod/jazz/process/1.0/'}"</js>),
 
 			<jc>// Specify a default title for the HtmlSerializer serializer</jc>
+			<jc>// This is equivalent to @RestMethod(pageTitle)</jc>
 			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"My resource"</js>)
 		}
 	<jk>public</jk> Object doGet() {
@@ -1753,10 +1746,6 @@
 	 */</jd>
 	<ja>@RestResource</ja>(
 		path=<js>"/"</js>,
-		messages=<js>"nls/RootResources"</js>,
-		properties={
-			<ja>@Property</ja>(name=HTMLDOC_links, value=<js>"{options:'$R{servletURI}?method=OPTIONS',source:'$R{servletURI}/source?classes=(org.apache.juneau.rest.samples.RootResources)'}"</js>)
-		},
 		children={
 			HelloWorldResource.<jk>class</jk>,
 			MethodExampleResource.<jk>class</jk>,
@@ -1905,9 +1894,6 @@
 		<p class='bcode'>
 	<ja>@RestResource</ja>(
 		title=<js>"$L{my.label}"</js>
- 		properties={
- 			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'$R{servletURI}?method=OPTIONS'"</js>)
- 		}
     )
 		</p>
 		<p>
@@ -2136,11 +2122,9 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/urlEncodedForm"</js>, 
 		messages=<js>"nls/UrlEncodedFormResource"</js>, 
-		properties={
-			<ja>@Property</ja>(name=HTMLDOC_title, value=<js>"URL-encoded Form Post Resource"</js>), 
-			<ja>@Property</ja>(name=HTMLDOC_description, value=<js>"Shows how form posts are converted into beans."</js>), 
-			<ja>@Property</ja>(name=HTMLDOC_links, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.UrlEncodedFormResource)'}"</js>) 
-		} 
+		title=<js>"URL-encoded Form Post Resource"</js>, 
+		description=<js>"Shows how form posts are converted into beans."</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> 
 	) 
 	<jk>public class</jk> UrlEncodedFormResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -2893,11 +2877,9 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/photos"</js>,
 		messages=<js>"nls/PhotosResource"</js>,
-		properties={
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"Photo REST service"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>)
-		}
+		title=<js>"Photo REST service"</js>,
+		description=<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS'}"</js>
 	)
 	<jk>public class</jk> PhotosResource <jk>extends</jk> RestServletDefault {
 	
@@ -2926,8 +2908,8 @@
 		<jd>/** GET request handler for list of all photos */</jd>
 		<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/"</js>)
 		<jk>public</jk> Collection&lt;Photo&gt; getAllPhotos(RestRequest req, RestResponse res) <jk>throws</jk> Exception {
-			res.setProperty(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, <js>"Photo REST service"</js>);
-			res.setProperty(HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, <js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>);
+			res.setPageTitle(<js>"Photo REST service"</js>);
+			res.setPageText(<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>);
 			<jk>return</jk> photos.values();
 		}
 		
@@ -3187,13 +3169,13 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/addressBook"</js>, 
 		messages=<js>"nls/AddressBookResource"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>, 
 		properties={ 
 			<ja>@Property</ja>(name=<jsf>REST_allowMethodParam</jsf>, value=<js>"*"</js>), 
 			<ja>@Property</ja>(name=<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>), 
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>), 
 			<ja>@Property</ja>(name=<jsf>RDF_rdfxml_tab</jsf>, value=<js>"5"</js>), 
 			<ja>@Property</ja>(name=<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.addressbook.AddressBookResource,org.apache.juneau.examples.addressbook.Address,org.apache.juneau.examples.addressbook.AddressBook,org.apache.juneau.examples.addressbook.CreateAddress,org.apache.juneau.examples.addressbook.CreatePerson,org.apache.juneau.examples.addressbook.IAddressBook,org.apache.juneau.examples.addressbook.Person)'}"</js>), 
 			<jc>// Resolve all relative URIs so that they're relative to this servlet!</jc> 
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_relativeUriBase</jsf>, value=<js>"$R{servletURI}"</js>), 
 		}, 



[3/3] incubator-juneau git commit: Add @RestResource.pageTitle/pageText/pageLinks annotations.

Posted by ja...@apache.org.
Add @RestResource.pageTitle/pageText/pageLinks annotations.

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

Branch: refs/heads/master
Commit: 703cadd2d9c0ccd68cefb13e078b8efd86e8636a
Parents: a058007
Author: JamesBognar <ja...@apache.org>
Authored: Fri Mar 31 18:42:46 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Fri Mar 31 18:42:46 2017 -0400

----------------------------------------------------------------------
 .../java/org/apache/juneau/jena/package.html    |  16 +-
 .../apache/juneau/dto/jsonschema/package.html   |   6 +-
 .../apache/juneau/html/HtmlDocSerializer.java   |   2 +-
 .../juneau/html/HtmlDocSerializerContext.java   |  49 ++-
 .../juneau/html/HtmlDocSerializerSession.java   |  14 +-
 .../java/org/apache/juneau/json/package.html    |  16 +-
 .../apache/juneau/serializer/StringObject.java  |  92 ------
 .../juneau/serializer/WriterSerializer.java     |   1 +
 .../java/org/apache/juneau/uon/package.html     |  16 +-
 .../org/apache/juneau/urlencoding/package.html  |  16 +-
 .../org/apache/juneau/utils/StringMessage.java  |  76 +++++
 .../org/apache/juneau/utils/StringObject.java   |  93 ++++++
 .../java/org/apache/juneau/xml/package.html     |  16 +-
 juneau-core/src/main/javadoc/overview.html      | 151 +++++----
 .../juneau/examples/rest/AtomFeedResource.java  |  11 +-
 .../examples/rest/CodeFormatterResource.java    |  10 +-
 .../juneau/examples/rest/DirectoryResource.java |   2 +-
 .../examples/rest/DockerRegistryResource.java   |   6 +-
 .../examples/rest/HelloWorldResource.java       |  10 +-
 .../examples/rest/JsonSchemaResource.java       |  13 +-
 .../examples/rest/MethodExampleResource.java    |   6 +-
 .../juneau/examples/rest/PhotosResource.java    |  16 +-
 .../examples/rest/RequestEchoResource.java      |  14 +-
 .../juneau/examples/rest/RootResources.java     |   9 +-
 .../examples/rest/SampleRemoteableServlet.java  |   7 +-
 .../juneau/examples/rest/SqlQueryResource.java  |  13 +-
 .../examples/rest/SystemPropertiesResource.java |   4 +-
 .../juneau/examples/rest/TempDirResource.java   |   8 +-
 .../examples/rest/TumblrParserResource.java     |  14 +-
 .../examples/rest/UrlEncodedFormResource.java   |   9 +-
 .../rest/addressbook/AddressBookResource.java   |   2 +-
 .../rest/nls/AtomFeedResource.properties        |  21 --
 .../rest/nls/CodeFormatterResource.properties   |  18 --
 .../rest/nls/HelloWorldResource.properties      |  19 --
 .../rest/nls/JsonSchemaResource.properties      |  20 --
 .../examples/rest/nls/PhotosResource.properties |  24 --
 .../rest/nls/RequestEchoResource.properties     |  19 --
 .../examples/rest/nls/RootResources.properties  |  18 --
 .../rest/nls/SampleRemoteableServlet.properties |  17 --
 .../examples/rest/nls/SourceResource.properties |  19 --
 .../rest/nls/SqlQueryResource.properties        |  19 --
 .../rest/nls/TempDirResource.properties         |  18 --
 .../rest/nls/TumblrParserResource.properties    |  19 --
 .../rest/nls/UrlEncodedFormResource.properties  |   2 -
 .../apache/juneau/microservice/Resource.java    |   2 +-
 .../juneau/microservice/ResourceGroup.java      |   6 +-
 .../juneau/microservice/ResourceJena.java       |   6 +-
 .../org/apache/juneau/microservice/package.html |   4 +-
 .../microservice/resources/ConfigResource.java  |   5 +-
 .../resources/DirectoryResource.java            |   2 +-
 .../microservice/resources/LogsResource.java    |   9 +-
 .../rest/test/HtmlPropertiesResource.java       | 305 +++++++++++++++++++
 .../java/org/apache/juneau/rest/test/Root.java  |   1 +
 .../rest/test/HtmlPropertiesResource.properties |  37 +++
 .../juneau/rest/test/HtmlPropertiesTest.java    | 286 +++++++++++++++++
 .../java/org/apache/juneau/rest/CallMethod.java |  28 +-
 .../org/apache/juneau/rest/ReaderResource.java  |   4 +-
 .../java/org/apache/juneau/rest/RestConfig.java |  47 ++-
 .../org/apache/juneau/rest/RestContext.java     |  42 ++-
 .../java/org/apache/juneau/rest/RestLogger.java |   2 +-
 .../org/apache/juneau/rest/RestRequest.java     |  56 +++-
 .../org/apache/juneau/rest/RestResponse.java    |  66 +++-
 .../apache/juneau/rest/RestServletDefault.java  |  13 +-
 .../juneau/rest/annotation/RestMethod.java      |  15 +-
 .../juneau/rest/annotation/RestResource.java    | 105 ++++++-
 .../rest/jena/RestServletJenaDefault.java       |  13 +-
 .../java/org/apache/juneau/rest/package.html    |  50 +--
 67 files changed, 1419 insertions(+), 636 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
index 5f1d7aa..095dc7e 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
@@ -1060,14 +1060,14 @@
 	// Consists of an in-memory address book repository.</jc>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/AddressBookResource"</js>,
+		title=<js>"$L{title}"</js>,
+		description=<js>"$L{description}"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>,
 		properties={
 			<ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>),
 			<ja>@Property</ja>(name=RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>),
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>),
-			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>)
 		},
 		encoders=GzipEncoder.<jk>class</jk>
 	)
@@ -1097,8 +1097,8 @@
 			<p class='bcode'>
 	<jc>// GET person request handler</jc>
 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 	
@@ -1160,8 +1160,8 @@
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
 		}
 	)
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 			</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html
index 77b0b5f..8353a46 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html
@@ -406,10 +406,8 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/jsonSchema"</js>,
 		messages=<js>"nls/JsonSchemaResource"</js>,
-		properties={
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"Sample JSON-Schema document"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>)
-		}
+		title=<js>"Sample JSON-Schema document"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS'}"</js>
 	)
 	<jk>public class</jk> JsonSchemaResource <jk>extends</jk> RestServletJenaDefault {
 	

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 03ca0ec..b7030e5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -112,7 +112,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 		String title = s.getTitle();
 		if (title == null && isOptionsPage)
 			title = "Options";
-		String description = s.getDescription();
+		String description = s.getText();
 		if (title != null)
 			w.oTag(1, "h3").attr("class", "title").append('>').text(title).eTag("h3").nl();
 		if (description != null)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
index 1849755..4101832 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
@@ -35,6 +35,18 @@ import org.apache.juneau.*;
  * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
  * </p>
  * <p>
+ * Note that shortcut annotations are also provided for these particular settings:
+ * <p class='bcode'>
+ * 	<ja>@RestResource</ja>(
+ * 		messages=<js>"nls/AddressBookResource"</js>,
+ * 		title=<js>"$L{title}"</js>,  <jc>// or pageTitle</jc>
+ * 		description=<js>"$L{description}"</js>,  <jc>// or pageText</jc>
+ * 		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>
+ * 	)
+ * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+ * </p>
+ *
+ * <p>
  * The <code>$L{...}</code> variable represent localized strings pulled from the resource bundle identified by the <code>messages</code> annotation.
  * These variables are replaced at runtime based on the HTTP request locale.
  * Several built-in runtime variable types are defined, and the API can be extended to include user-defined variables.
@@ -86,6 +98,15 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 	 * 	...to produce this title on the HTML page...
 	 * </p>
 	 * <img class='bordered' src='doc-files/HTML_TITLE.png'>
+	 * <p>
+	 * Shortcuts on <ja>@RestResource</ja> are also provided for this setting:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		messages=<js>"nls/AddressBookResource"</js>,
+	 * 		title=<js>"My title"</js>,  <jc>// or pageTitle</jc>
+	 * 	)
+	 * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+	 * </p>
 	 */
 	public static final String HTMLDOC_title = "HtmlSerializer.title";
 
@@ -108,7 +129,7 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 	 * 	<ja>@RestResource</ja>(
 	 * 		messages=<js>"nls/AddressBookResource"</js>,
 	 * 		properties={
-	 * 			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"description"</js>, type=<jsf>NLS</jsf>)
+	 * 			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"My description"</js>)
 	 * 		}
 	 * 	)
 	 * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
@@ -123,8 +144,17 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 	 * 	...to produce this description on the HTML page...
 	 * </p>
 	 * <img class='bordered' src='doc-files/HTML_DESCRIPTION.png'>
+	 * <p>
+	 * Shortcuts on <ja>@RestResource</ja> are also provided for this setting:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		messages=<js>"nls/AddressBookResource"</js>,
+	 * 		description=<js>"My description"</js>,  <jc>// or pageText</jc>
+	 * 	)
+	 * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+	 * </p>
 	 */
-	public static final String HTMLDOC_description = "HtmlSerializer.description";
+	public static final String HTMLDOC_text = "HtmlSerializer.description";
 
 	/**
 	 * <b>Configuration property:</b>  Page links.
@@ -165,6 +195,15 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 	 * 	...to produce this list of links on the HTML page...
 	 * </p>
 	 * <img class='bordered' src='doc-files/HTML_LINKS.png'>
+	 * <p>
+	 * A shortcut on <ja>@RestResource</ja> is also provided for this setting:
+	 * <p class='bcode'>
+	 * 	<ja>@RestResource</ja>(
+	 * 		messages=<js>"nls/AddressBookResource"</js>,
+	 * 		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>
+	 * 	)
+	 * 	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+	 * </p>
 	 */
 	public static final String HTMLDOC_links = "HtmlDocSerializer.links.map";
 
@@ -225,7 +264,7 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 
 	final String[] cssImports;
 	final Map<String,String> links;
-	final String title, description, cssUrl;
+	final String title, text, cssUrl;
 	final boolean nowrap;
 
 	/**
@@ -239,7 +278,7 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 		super(ps);
 		cssImports = ps.getProperty(HTMLDOC_cssImports, String[].class, new String[0]);
 		title = ps.getProperty(HTMLDOC_title, String.class, null);
-		description = ps.getProperty(HTMLDOC_description, String.class, null);
+		text = ps.getProperty(HTMLDOC_text, String.class, null);
 		cssUrl = ps.getProperty(HTMLDOC_cssUrl, String.class, null);
 		nowrap = ps.getProperty(HTMLDOC_nowrap, boolean.class, false);
 		links = ps.getMap(HTMLDOC_links, String.class, String.class, Collections.<String,String>emptyMap());
@@ -251,7 +290,7 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 			.append("HtmlDocSerializerContext", new ObjectMap()
 				.append("cssImports", cssImports)
 				.append("title", title)
-				.append("description", description)
+				.append("text", text)
 				.append("cssUrl", cssUrl)
 				.append("nowrap", nowrap)
 				.append("links", links)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
index 94666f8..440c80b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
@@ -31,7 +31,7 @@ import org.apache.juneau.serializer.*;
  */
 public final class HtmlDocSerializerSession extends HtmlSerializerSession {
 
-	private final String title, description, cssUrl;
+	private final String title, text, cssUrl;
 	private final String[] cssImports;
 	private final Map<String,String> links;
 	private final boolean nowrap;
@@ -56,14 +56,14 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession {
 		super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 		if (op == null || op.isEmpty()) {
 			title = ctx.title;
-			description = ctx.description;
+			text = ctx.text;
 			links = ctx.links;
 			cssUrl = ctx.cssUrl;
 			cssImports = ctx.cssImports;
 			nowrap = ctx.nowrap;
 		} else {
 			title = op.getString(HTMLDOC_title, ctx.title);
-			description = op.getString(HTMLDOC_description, ctx.description);
+			text = op.getString(HTMLDOC_text, ctx.text);
 			links = new LinkedHashMap(op.getMap(HTMLDOC_links, ctx.links));
 			cssUrl = op.getString(HTMLDOC_cssUrl, ctx.cssUrl);
 			cssImports = StringUtils.split(op.getString(HTMLDOC_cssImports, null), ',');
@@ -81,12 +81,12 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession {
 	}
 
 	/**
-	 * Returns the {@link HtmlDocSerializerContext#HTMLDOC_description} setting value in this context.
+	 * Returns the {@link HtmlDocSerializerContext#HTMLDOC_text} setting value in this context.
 	 *
-	 * @return The {@link HtmlDocSerializerContext#HTMLDOC_description} setting value in this context.
+	 * @return The {@link HtmlDocSerializerContext#HTMLDOC_text} setting value in this context.
 	 */
-	public final String getDescription() {
-		return description;
+	public final String getText() {
+		return text;
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/json/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/package.html b/juneau-core/src/main/java/org/apache/juneau/json/package.html
index f302ec9..b6decc1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/json/package.html
@@ -1002,12 +1002,12 @@
 	// Consists of an in-memory address book repository.</jc>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/AddressBookResource"</js>,
+		title=<js>"$L{title}"</js>,
+		description=<js>"$L{description}"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>,
 		properties={
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>),
-			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>)
 		},
 		encoders=GzipEncoder.<jk>class</jk>
 	)
@@ -1036,8 +1036,8 @@
 			<p class='bcode'>
 	<jc>// GET person request handler</jc>
 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 	
@@ -1096,8 +1096,8 @@
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
 		}
 	)
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 			</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java b/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
deleted file mode 100644
index 81ae833..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
+++ /dev/null
@@ -1,92 +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;
-
-import java.io.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.json.*;
-
-/**
- * A serializer/object pair used for delayed object serialization.
- * <p>
- * Useful in certain conditions such as logging when you don't want to needlessly serialize objects.
- * <p>
- * Instances of this method are created by the {@link WriterSerializer#toStringObject(Object)} method.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
- * 	<jc>// The POJO will not be serialized unless DEBUG is enabled.</jc>
- * 	logger.log(<jsf>DEBUG</jsf>, <js>"Object contents are: {0}"</js>, JsonSerializer.<jsf>DEFAULT</jsf>.toObjectString(myPojo));
- * </p>
- */
-public class StringObject implements CharSequence, Writable {
-
-	private final WriterSerializer s;
-	private final Object o;
-	private String results;
-
-	/**
-	 * Constructor.
-	 * @param s The serializer to use to serialize the object.
-	 * @param o The object to be serialized.
-	 */
-	public StringObject(WriterSerializer s, Object o) {
-		this.s = s;
-		this.o = o;
-	}
-
-	/**
-	 * Constructor with default serializer {@link JsonSerializer#DEFAULT_LAX}
-	 * @param o The object to be serialized.
-	 */
-	public StringObject(Object o) {
-		this(JsonSerializer.DEFAULT_LAX, o);
-	}
-
-	@Override /* Object */
-	public String toString() {
-		if (results == null)
-			results = s.toString(o);
-		return results;
-	}
-
-	@Override /* CharSequence */
-	public int length() {
-		return toString().length();
-	}
-
-	@Override /* CharSequence */
-	public char charAt(int index) {
-		return toString().charAt(index);
-	}
-
-	@Override /* CharSequence */
-	public CharSequence subSequence(int start, int end) {
-		return toString().subSequence(start, end);
-	}
-
-	@Override /* Writable */
-	public void writeTo(Writer w) throws IOException {
-		try {
-			s.serialize(o, w);
-		} catch (SerializeException e) {
-			throw new IOException(e);
-		}
-	}
-
-	@Override /* Writable */
-	public MediaType getMediaType() {
-		return s.getMediaTypes()[0];
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index e84e593..9a5c79e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
+import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Serializer} for character-based serializers.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/uon/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/package.html b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
index 6c2c6ca..1794466 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
@@ -986,11 +986,11 @@
 	// Consists of an in-memory address book repository.</jc>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/AddressBookResource"</js>,
+		title=<js>"$L{title}"</js>,
+		description=<js>"$L{description}"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>,
 		properties={
-			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
 		},
 		encoders=GzipEncoder.<jk>class</jk>
 	)
@@ -1019,8 +1019,8 @@
 			<p class='bcode'>
 	<jc>// GET person request handler</jc>
 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 	
@@ -1079,8 +1079,8 @@
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
 		}
 	)
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 			</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
index ddb09b2..ce7f90e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
@@ -986,11 +986,11 @@
 	// Consists of an in-memory address book repository.</jc>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/AddressBookResource"</js>,
+		title=<js>"$L{title}"</js>,
+		description=<js>"$L{description}"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>,
 		properties={
-			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
 		},
 		encoders=GzipEncoder.<jk>class</jk>
 	)
@@ -1019,8 +1019,8 @@
 			<p class='bcode'>
 	<jc>// GET person request handler</jc>
 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 	
@@ -1079,8 +1079,8 @@
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
 		}
 	)
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 			</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/utils/StringMessage.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/StringMessage.java b/juneau-core/src/main/java/org/apache/juneau/utils/StringMessage.java
new file mode 100644
index 0000000..f7403f1
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/StringMessage.java
@@ -0,0 +1,76 @@
+// ***************************************************************************************************************************
+// * 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.utils;
+
+import java.io.*;
+import java.text.*;
+
+import org.apache.juneau.*;
+
+/**
+ * An encapsulated MessageFormat-style string and arguments.
+ * <p>
+ * Useful for delayed serialization of arguments for logging.
+ * Message string will not be constructed until the <code>toString()</code> method is called.
+ */
+public class StringMessage implements CharSequence, Writable {
+
+	private final String pattern;
+	private final Object[] args;
+	private String results;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param pattern {@link MessageFormat}-style pattern.
+	 * @param args Message arguments.
+	 */
+	public StringMessage(String pattern, Object...args) {
+		this.pattern = pattern;
+		this.args = args;
+	}
+
+	@Override /* Writable */
+	public void writeTo(Writer w) throws IOException {
+		w.write(toString());
+
+	}
+
+	@Override /* Writable */
+	public MediaType getMediaType() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override /* CharSequence */
+	public char charAt(int index) {
+		return toString().charAt(index);
+	}
+
+	@Override /* CharSequence */
+	public int length() {
+		return toString().length();
+	}
+
+	@Override /* CharSequence */
+	public CharSequence subSequence(int start, int end) {
+		return toString().subSequence(start, end);
+	}
+
+	@Override /* Object */
+	public String toString() {
+		if (results == null)
+			results = (args.length == 0 ? pattern : MessageFormat.format(pattern, args));
+		return results;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/utils/StringObject.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/StringObject.java b/juneau-core/src/main/java/org/apache/juneau/utils/StringObject.java
new file mode 100644
index 0000000..04b7c99
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/StringObject.java
@@ -0,0 +1,93 @@
+// ***************************************************************************************************************************
+// * 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.utils;
+
+import java.io.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * A serializer/object pair used for delayed object serialization.
+ * <p>
+ * Useful in certain conditions such as logging when you don't want to needlessly serialize objects.
+ * <p>
+ * Instances of this method are created by the {@link WriterSerializer#toStringObject(Object)} method.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * 	<jc>// The POJO will not be serialized unless DEBUG is enabled.</jc>
+ * 	logger.log(<jsf>DEBUG</jsf>, <js>"Object contents are: {0}"</js>, JsonSerializer.<jsf>DEFAULT</jsf>.toObjectString(myPojo));
+ * </p>
+ */
+public class StringObject implements CharSequence, Writable {
+
+	private final WriterSerializer s;
+	private final Object o;
+	private String results;
+
+	/**
+	 * Constructor.
+	 * @param s The serializer to use to serialize the object.
+	 * @param o The object to be serialized.
+	 */
+	public StringObject(WriterSerializer s, Object o) {
+		this.s = s;
+		this.o = o;
+	}
+
+	/**
+	 * Constructor with default serializer {@link JsonSerializer#DEFAULT_LAX}
+	 * @param o The object to be serialized.
+	 */
+	public StringObject(Object o) {
+		this(JsonSerializer.DEFAULT_LAX, o);
+	}
+
+	@Override /* Object */
+	public String toString() {
+		if (results == null)
+			results = s.toString(o);
+		return results;
+	}
+
+	@Override /* CharSequence */
+	public int length() {
+		return toString().length();
+	}
+
+	@Override /* CharSequence */
+	public char charAt(int index) {
+		return toString().charAt(index);
+	}
+
+	@Override /* CharSequence */
+	public CharSequence subSequence(int start, int end) {
+		return toString().subSequence(start, end);
+	}
+
+	@Override /* Writable */
+	public void writeTo(Writer w) throws IOException {
+		try {
+			s.serialize(o, w);
+		} catch (SerializeException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override /* Writable */
+	public MediaType getMediaType() {
+		return s.getMediaTypes()[0];
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/java/org/apache/juneau/xml/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/package.html b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
index 4c0fbeb..eb6377b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
@@ -2921,12 +2921,12 @@
 	// Consists of an in-memory address book repository.</jc>
 	<ja>@RestResource</ja>(
 		messages=<js>"nls/AddressBookResource"</js>,
+		title=<js>"$L{title}"</js>,
+		description=<js>"$L{description}"</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>,
 		properties={
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>),
-			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>)
 		},
 		encoders=GzipEncoder.<jk>class</jk>
 	)
@@ -2955,8 +2955,8 @@
 			<p class='bcode'>
 	<jc>// GET person request handler</jc>
 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 	
@@ -3015,8 +3015,8 @@
 			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
 		}
 	)
-	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
-		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+	<jk>public</jk> Person getPerson(RestRequest req, RestRequest res, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		res.setPageTitle(req.getPathInfo());
 		<jk>return</jk> findPerson(id);
 	}
 			</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 3b99922..f5353a1 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -1957,9 +1957,9 @@
 		path=<js>"/systemProperties"</js>,
 		title=<js>"System properties resource"</js>,
 		description=<js>"REST interface for performing CRUD operations on system properties."</js>,
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>,
 		properties={
-			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>),
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS'}"</js>),
+			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
 		},
 		stylesheet=<js>"styles/devops.css"</js>,
 		encoders=GzipEncoder.<jk>class</jk>,
@@ -2623,9 +2623,7 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/"</js>,
 		messages=<js>"nls/RootResources"</js>,
-		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'$R{servletURI}?method=OPTIONS',source:'$R{servletURI}/source?classes=(org.apache.juneau.rest.samples.RootResources)'}"</js>)
-		},
+		pageLinks=<js>"{options:'?method=OPTIONS'}"</js>,
 		children={
 			HelloWorldResource.<jk>class</jk>, 
 			MethodExampleResource.<jk>class</jk>, 
@@ -2717,9 +2715,7 @@
 	<ja>@RestResource</ja>( 
 		messages=<js>"nls/HelloWorldResource"</js>, 
 		path=<js>"/helloWorld"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=HTMLDOC_links, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>) 
-		} 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
 	) 
 	<jk>public class</jk> HelloWorldResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -2794,9 +2790,7 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/methodExample"</js>, 
 		messages=<js>"nls/MethodExampleResource"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.MethodExampleResource)'}"</js>) 
-		} 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
 	) 
 	<jk>public class</jk> MethodExampleResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -2938,9 +2932,7 @@
 		</p>
 		<p class='bcode'>
 	<ja>@RestResource</ja>(
-		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>)
-		}
+		pageLinks=<js>"{options:'?method=OPTIONS'}"</js>
 	)
 		</p>
 		<p>
@@ -3205,10 +3197,10 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/echo"</js>,
 		messages=<js>"nls/RequestEchoResource"</js>,
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>,
 		properties={
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_maxDepth</jsf>, value=<js>"10"</js>),
-			<ja>@Property</ja>(name=<jsf>SERIALIZER_detectRecursions</jsf>, value=<js>"true"</js>),
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.RequestEchoResource)'}"</js>)
+			<ja>@Property</ja>(name=<jsf>SERIALIZER_detectRecursions</jsf>, value=<js>"true"</js>)
 		},
 		beanFilters={
 			<jc>// Interpret these as their parent classes, not subclasses</jc>
@@ -3223,10 +3215,9 @@
 	
 		<jd>/** GET request handler */</jd>
 		<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/*"</js>, converters={Queryable.<jk>class</jk>,Traversable.<jk>class</jk>})
-		<jk>public</jk> HttpServletRequest doGet(RestRequest req, <ja>@Properties</ja> ObjectMap properties) {
+		<jk>public</jk> HttpServletRequest doGet(RestRequest req, RestResponse res, <ja>@Properties</ja> ObjectMap properties) {
 			<jc>// Set the HtmlDocSerializer title programmatically.
-			// This sets the value for this request only.</jc>
-			properties.put(<jsf>HTMLDOC_title</jsf>, <js>"Contents of HttpServletRequest object"</js>);
+			res.setPageTitle(req.getPathInfo());
 			
 			<jc>// Just echo the request back as the response.</jc>
 			<jk>return</jk> req;
@@ -3264,7 +3255,7 @@
 			.addPojoSwaps(EnumerationSwap.<jk>class</jk>)
 			.setProperty(<jsf>SERIALIZER_maxDepth</jsf>, 10)
 			.setProperty(<jsf>SERIALIZER_detectRecursions</jsf>, <jk>true</jk>)
-			.property(<jsf>HTMLDOC_links</jsf>, <js>"{...}"</js>);
+			.setPageLinks(<js>"{...}"</js>);
 		
 		<jc>// Don't forget to call this!</jc>
 		<jk>super</jk>.init(config);
@@ -3661,13 +3652,13 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/addressBook"</js>, 
 		messages=<js>"nls/AddressBookResource"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>, 
 		properties={ 
 			<ja>@Property</ja>(name=<jsf>REST_allowMethodParam</jsf>, value=<js>"*"</js>), 
 			<ja>@Property</ja>(name=<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>), 
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>), 
 			<ja>@Property</ja>(name=<jsf>RDF_rdfxml_tab</jsf>, value=<js>"5"</js>), 
 			<ja>@Property</ja>(name=<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.addressbook.AddressBookResource,org.apache.juneau.examples.addressbook.Address,org.apache.juneau.examples.addressbook.AddressBook,org.apache.juneau.examples.addressbook.CreateAddress,org.apache.juneau.examples.addressbook.CreatePerson,org.apache.juneau.examples.addressbook.IAddressBook,org.apache.juneau.examples.addressbook.Person)'}"</js>), 
 			<jc>// Resolve all relative URIs so that they're relative to this servlet!</jc> 
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_relativeUriBase</jsf>, value=<js>"$R{servletURI}"</js>), 
 		}, 
@@ -4310,10 +4301,10 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/remoteable"</js>, 
 		messages=<js>"nls/SampleRemoteableServlet"</js>, 
+		title=<js>"Remoteable Service Proxy API"</js>, 
+		description=<js>"Sample class showing how to use remoteable proxies. The list below are exposed services that can be retrieved using RestClient.getProxyInterface(Class)."</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>, 
 		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"Remoteable Service Proxy API"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"Sample class showing how to use remoteable proxies. The list below are exposed services that can be retrieved using RestClient.getProxyInterface(Class)."</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.SampleRemoteableServlet)'}"</js>), 
 			<jc>// Allow us to use method=POST from a browser.</jc> 
 			<ja>@Property</ja>(name=<jsf>REST_allowMethodParam</jsf>, value=<js>"*"</js>) 
 		} 
@@ -4417,12 +4408,12 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/tempDir"</js>, 
 		messages=<js>"nls/TempDirResource"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',upload:'upload'}"</js>,
 		properties={ 
 			<ja>@Property</ja>(name=<js>"DirectoryResource.rootDir"</js>, value=<js>"$S{java.io.tmpdir}"</js>), 
 			<ja>@Property</ja>(name=<js>"DirectoryResource.allowViews"</js>, value=<js>"true"</js>), 
 			<ja>@Property</ja>(name=<js>"DirectoryResource.allowDeletes"</js>, value=<js>"true"</js>), 
-			<ja>@Property</ja>(name=<js>"DirectoryResource.allowPuts"</js>, value=<js>"false"</js>), 
-			<ja>@Property</ja>(name=HTMLDOC_links, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',upload:'upload',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.TempDirResource,org.apache.juneau.rest.samples.DirectoryResource)'}"</js>),
+			<ja>@Property</ja>(name=<js>"DirectoryResource.allowPuts"</js>, value=<js>"false"</js>) 
 		}, 
 		stylesheet=<js>"styles/devops.css"</js> 
 	) 
@@ -4535,11 +4526,11 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/atom"</js>, 
 		messages=<js>"nls/AtomFeedResource"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>,
 		properties={ 
 			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>), 
 			<ja>@Property</ja>(name=<jsf>RDF_rdfxml_tab</jsf>, value=<js>"5"</js>), 
-			<ja>@Property</ja>(name=<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.AtomFeedResource)'}"</js>) 
+			<ja>@Property</ja>(name=<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>)
 		}, 
 		encoders=GzipEncoder.<jk>class</jk> 
 	) 
@@ -4643,9 +4634,7 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/docker"</js>, 
 		title=<js>"Sample Docker resource"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.AtomFeedResource)'}"</js>) 
-		} 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> 
 	) 
 	<jk>public class</jk> DockerRegistryResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -4724,11 +4713,9 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/tumblrParser"</js>, 
 		messages=<js>"nls/TumblrParserResource"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.TumblrParserResource)'}"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"Tumblr parser service"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"Specify a URL to a Tumblr blog and parse the results."</js>) 
-		} 
+		title=<js>"Tumblr parser service"</js>, 
+		description=<js>"Specify a URL to a Tumblr blog and parse the results."</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> 
 	) 
 	<jk>public class</jk> TumblrParserResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -4808,11 +4795,9 @@
 	<ja>@RestResource</ja>(
 		path=<js>"/photos"</js>,
 		messages=<js>"nls/PhotosResource"</js>,
-		properties={
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"Photo REST service"</js>),
-			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>)
-		}
+		title=<js>"Photo REST service"</js>,
+		description=<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>,
+		pageLinks=<js>"{options:'?method=OPTIONS'}"</js>
 	)
 	<jk>public class</jk> PhotosResource <jk>extends</jk> RestServletDefault {
 	
@@ -4854,8 +4839,8 @@
 		<jd>/** GET request handler for list of all photos */</jd>
 		<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/"</js>)
 		<jk>public</jk> Collection&lt;Photo&gt; getAllPhotos(RestRequest req, RestResponse res) <jk>throws</jk> Exception {
-			res.setProperty(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, <js>"Photo REST service"</js>);
-			res.setProperty(HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, <js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>);
+			res.setPageTitle(<js>"Photo REST service"</js>);
+			res.setPageText(<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>);
 			<jk>return</jk> photos.values();
 		}
 		
@@ -4950,10 +4935,8 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/jsonSchema"</js>, 
 		messages=<js>"nls/JsonSchemaResource"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"Sample JSON-Schema document"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.JsonSchemaResource)'}"</js>) 
-		} 
+		title=<js>"Sample JSON-Schema document"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> 
 	) 
 	<jk>public class</jk> JsonSchemaResource <jk>extends</jk> ResourceJena { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -5032,11 +5015,9 @@
 	<ja>@RestResource</ja>( 
 		path=<js>"/sqlQuery"</js>, 
 		messages=<js>"nls/SqlQueryResource"</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"SQL query service"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"Executes queries against the local derby '$C{SqlQueryResource/connectionUrl}' database"</js>), 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.SqlQueryResource)'}"</js>), 
-		} 
+		title=<js>"SQL query service"</js>, 
+		description=<js>"Executes queries against the local derby '$C{SqlQueryResource/connectionUrl}' database"</js>, 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> 
 	) 
 	<jk>public class</jk> SqlQueryResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -5223,9 +5204,7 @@
 		path=<js>"/config"</js>, 
 		title=<js>"Configuration"</js>, 
 		description=<js>"Contents of configuration file."</js>, 
-		properties={ 
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',edit:'$R{servletURI}/edit'}"</js>), 
-		} 
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS',edit:'edit'}"</js>
 	) 
 	<jk>public class</jk> ConfigResource <jk>extends</jk> Resource { 
 		<jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; 
@@ -5729,6 +5708,7 @@
 				<li>{@link org.apache.juneau.serializer.SerializerGroupBuilder}
 				<li>{@link org.apache.juneau.parser.ParserGroupBuilder}
 				<li>{@link org.apache.juneau.encoders.EncoderGroupBuilder}
+			</ul>
 			<li>Revamped the config file API to use a build:  {@link org.apache.juneau.ini.ConfigFileBuilder}.
 			<li>Removed the <code><del>Lockable</del></code> interface.
 			<li>New <code>addBeanTypeProperties</code> setting added to serializers to override the 
@@ -5805,16 +5785,54 @@
 				</ul>
 			<li>New annotations added to {@link org.apache.juneau.rest.annotation.RestResource @RestResource} to allow non-<code>RestServlet</code>
 				resources to do the same as subclassing directly from <code>RestServlet</code>:
-			<ul>
-				<li>{@link org.apache.juneau.rest.annotation.RestResource#resourceResolver() resourceResolver()} 
-					- Specify a {@link org.apache.juneau.rest.RestResourceResolver} class for resolving child resources.
-				<li>{@link org.apache.juneau.rest.annotation.RestResource#callHandler() callHandler()} 
-					- Specify a {@link org.apache.juneau.rest.RestCallHandler} class for handling the lifecycle of a REST call.
-				<li>{@link org.apache.juneau.rest.annotation.RestResource#infoProvider() infoProvider()} 
-					- Specify a {@link org.apache.juneau.rest.RestInfoProvider} class for customizing title/description/Swagger information on a REST resource.
-				<li>{@link org.apache.juneau.rest.annotation.RestResource#logger() logger()} 
-					- Specify a {@link org.apache.juneau.rest.RestLogger} class for handling logging.
-			</ul>
+				<ul>
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#resourceResolver() resourceResolver()} 
+						- Specify a {@link org.apache.juneau.rest.RestResourceResolver} class for resolving child resources.
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#callHandler() callHandler()} 
+						- Specify a {@link org.apache.juneau.rest.RestCallHandler} class for handling the lifecycle of a REST call.
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#infoProvider() infoProvider()} 
+						- Specify a {@link org.apache.juneau.rest.RestInfoProvider} class for customizing title/description/Swagger information on a REST resource.
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#logger() logger()} 
+						- Specify a {@link org.apache.juneau.rest.RestLogger} class for handling logging.
+				</ul>
+			<li>New annotations added to {@link org.apache.juneau.rest.annotation.RestResource @RestResource} and {@link org.apache.juneau.rest.annotation.RestMethod @RestMethod}
+				to simplify defining page title, text, and links on HTML views:
+				<ul>
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#pageTitle() @RestResource.pageTitle()} 
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#pageTitle() @RestMethod.pageTitle()} 
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#pageText() @RestResource.pageText()} 
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#pageText() @RestMethod.pageText()} 
+					<li>{@link org.apache.juneau.rest.annotation.RestResource#pageLinks() @RestResource.pageLinks()} 
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#pageLinks() @RestMethod.pageLinks()} 
+				</ul>				
+				<p class='bcode'>
+	<jc>// Old method</jc>
+	<ja>@RestResource</ja>(
+		properties={
+			<ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"System properties resource"</js>),
+			<ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"REST interface for performing CRUD operations on system properties."</js>),
+			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>)
+		}
+	)
+		
+	<jc>// New method</jc>
+	<ja>@RestResource</ja>(
+		pageTitle=<js>"System properties resource"</js>,
+		pageDescription=<js>"REST interface for performing CRUD operations on system properties."</js>,
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
+	)
+				</p>		
+				<p>
+					Typically you're going to simply want to use the <code>title</code> and <code>description</code> annotations
+					which apply to both the page title/text and the swagger doc:		
+				</p>
+				<p class='bcode'>
+	<ja>@RestResource</ja>(
+		title=<js>"System properties resource"</js>,
+		description=<js>"REST interface for performing CRUD operations on system properties."</js>,
+		pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
+	)
+				</p>
 			<li>{@link org.apache.juneau.rest.annotation.RestResource#stylesheet()} can now take in a comma-delimited list of stylesheet paths.
 			<li>{@link org.apache.juneau.rest.StreamResource} can now contain multiple sources from a variety of source types (e.g. <code><jk>byte</jk>[]</code> arrays, <code>InputStreams</code>, <code>Files</code>, etc...)
 				and is now immutable.  It also includes a new {@link org.apache.juneau.rest.StreamResource.Builder} class.
@@ -5858,6 +5876,7 @@
 				<li>{@link org.apache.juneau.rest.client.RestClientBuilder#debug(boolean)} now adds a <code>Debug: true</code> header on all requests.
 			</ul>
 			<li>New doc: <a class='doclink' href='org/apache/juneau/rest/client/package-summary.html#Debugging'>1.5 - Debugging</a>
+			<li>{@link org.apache.juneau.rest.annotation.RestMethod#name() @RestMethod.name()} annotation is now optional.  Defaults to <js>"GET"</js>.
 		</ul>
 		
 		<h6 class='topic'>org.apache.juneau.microservice</h6>
@@ -6434,7 +6453,7 @@
 				<ul>
 					<li>{@link org.apache.juneau.Streamable} interface for identifying objects that can be serialized directly to an output stream.
 					<li>{@link org.apache.juneau.Writable} interface for identifying objects that can be serialized directly to a writer.
-					<li>{@link org.apache.juneau.serializer.StringObject} class that can be used for delayed object serialization.
+					<li><code><del>StringObject</del></code> class that can be used for delayed object serialization.
 					<li>{@link org.apache.juneau.internal.ByteArrayCache}
 					<li>{@link org.apache.juneau.internal.ByteArrayInOutStream} 
 					<li>{@link org.apache.juneau.internal.FileUtils}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
index 54e7937..0d0f884 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
@@ -29,12 +29,13 @@ import org.apache.juneau.rest.annotation.*;
  */
 @RestResource(
 	path="/atom",
-	messages="nls/AtomFeedResource",
+	title="Sample ATOM feed resource",
+	description="Sample resource that shows how to render ATOM feeds",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/AtomFeedResource.java'}",
 	properties={
 		@Property(name=SERIALIZER_quoteChar, value="'"),
 		@Property(name=RDF_rdfxml_tab, value="5"),
-		@Property(name=RDF_addRootProperty, value="true"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/AtomFeedResource.java'}")
+		@Property(name=RDF_addRootProperty, value="true")
 	},
 	encoders=GzipEncoder.class
 )
@@ -86,7 +87,7 @@ public class AtomFeedResource extends ResourceJena {
 	/**
 	 * GET request handler
 	 */
-	@RestMethod(name="GET", path="/")
+	@RestMethod(name="GET", path="/", summary="Get the sample ATOM feed")
 	public Feed getFeed() throws Exception {
 		return feed;
 	}
@@ -95,7 +96,7 @@ public class AtomFeedResource extends ResourceJena {
 	 * PUT request handler.
 	 * Replaces the feed with the specified content, and then mirrors it as the response.
 	 */
-	@RestMethod(name="PUT", path="/")
+	@RestMethod(name="PUT", path="/", summary="Overwrite the sample ATOM feed")
 	public Feed setFeed(@Body Feed feed) throws Exception {
 		this.feed = feed;
 		return feed;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
index de9df31..10a0b07 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import java.io.*;
 
 import org.apache.juneau.microservice.*;
@@ -27,11 +25,9 @@ import org.apache.juneau.rest.annotation.*;
 @RestResource(
 	path="/codeFormatter",
 	messages="nls/CodeFormatterResource",
-	properties={
-		@Property(name=HTMLDOC_title, value="Code Formatter"),
-		@Property(name=HTMLDOC_description, value="Add syntax highlighting tags to source code"),
-		@Property(name=HTMLDOC_links, value="{options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/CodeFormatterResource.java'}"),
-	}
+	title="Code Formatter",
+	description="Utility for generating HTML code-formatted source code",
+	pageLinks="{options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/CodeFormatterResource.java'}"
 )
 @SuppressWarnings({"serial"})
 public class CodeFormatterResource extends Resource {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java
index f0b6a3d..9c3919f 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java
@@ -35,9 +35,9 @@ import org.apache.juneau.utils.*;
  */
 @RestResource(
 	messages="nls/DirectoryResource",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/DirectoryResource.java'}",
 	properties={
 		@Property(name=HTML_uriAnchorText, value=PROPERTY_NAME),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/DirectoryResource.java'}"),
 		@Property(name=REST_allowMethodParam, value="*"),
 		@Property(name="rootDir", value="$S{java.io.tmpdir}"),
 		@Property(name="allowViews", value="false"),

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
index 00bc907..61192f0 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import java.util.*;
 
 import org.apache.juneau.ini.*;
@@ -29,9 +27,7 @@ import org.apache.juneau.rest.labels.*;
 @RestResource(
 	path="/docker",
 	title="Sample Docker resource",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/DockerRegistryResource.java'}")
-	}
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/DockerRegistryResource.java'}"
 )
 public class DockerRegistryResource extends Resource {
 	private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
index 5b5fae8..935989b 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.rest.annotation.*;
 
@@ -22,16 +20,16 @@ import org.apache.juneau.rest.annotation.*;
  */
 @RestResource(
 	messages="nls/HelloWorldResource",
+	title="Hello World sample resource",
+	description="Simplest possible resource",
 	path="/helloWorld",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/HelloWorldResource.java'}")
-	}
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/HelloWorldResource.java'}"
 )
 public class HelloWorldResource extends Resource {
 	private static final long serialVersionUID = 1L;
 
 	/** GET request handler */
-	@RestMethod(name="GET", path="/*")
+	@RestMethod(name="GET", path="/*", summary="Responds with \"Hello world!\"")
 	public String sayHello() {
 		return "Hello world!";
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
index ae17734..d4a6c90 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.dto.jsonschema.*;
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.rest.annotation.*;
@@ -24,10 +22,9 @@ import org.apache.juneau.rest.annotation.*;
 @RestResource(
 	path="/jsonSchema",
 	messages="nls/JsonSchemaResource",
-	properties={
-		@Property(name=HTMLDOC_title, value="Sample JSON-Schema document"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/JsonSchemaResource.java'}")
-	}
+	title="Sample JSON-Schema document",
+	description="Sample resource that shows how to generate JSON-Schema documents",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/JsonSchemaResource.java'}"
 )
 public class JsonSchemaResource extends ResourceJena {
 	private static final long serialVersionUID = 1L;
@@ -57,7 +54,7 @@ public class JsonSchemaResource extends ResourceJena {
 	}
 
 	/** GET request handler */
-	@RestMethod(name="GET", path="/")
+	@RestMethod(name="GET", path="/", summary="Get the JSON-Schema document")
 	public Schema getSchema() throws Exception {
 		return schema;
 	}
@@ -66,7 +63,7 @@ public class JsonSchemaResource extends ResourceJena {
 	 * PUT request handler.
 	 * Replaces the schema document with the specified content, and then mirrors it as the response.
 	 */
-	@RestMethod(name="PUT", path="/")
+	@RestMethod(name="PUT", path="/", summary="Overwrite the JSON-Schema document")
 	public Schema setSchema(@Body Schema schema) throws Exception {
 		this.schema = schema;
 		return schema;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
index ee0a0b9..1d06a5a 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import java.util.*;
 
 import org.apache.juneau.microservice.*;
@@ -26,9 +24,7 @@ import org.apache.juneau.rest.annotation.*;
 @RestResource(
 	path="/methodExample",
 	messages="nls/MethodExampleResource",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{servletParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/MethodExampleResource.java'}")
-	}
+	pageLinks="{up:'$R{servletParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/MethodExampleResource.java'}"
 )
 public class MethodExampleResource extends Resource {
 	private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index ff5c242..b5dace5 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -37,10 +37,10 @@ import org.apache.juneau.serializer.*;
 @RestResource(
 	path="/photos",
 	messages="nls/PhotosResource",
+	title="Photo REST service",
+	description="Sample resource that allows images to be uploaded and retrieved.",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/PhotosResource.java'}",
 	properties={
-		@Property(name=HTMLDOC_title, value="Photo REST service"),
-		@Property(name=HTMLDOC_description, value="Use a tool like Poster to upload and retrieve jpeg and png images."),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/PhotosResource.java'}"),
 		// Resolve all relative URIs so that they're relative to this servlet!
 		@Property(name=SERIALIZER_relativeUriBase, value="$R{servletURI}"),
 	}
@@ -80,13 +80,13 @@ public class PhotosResource extends Resource {
 	}
 
 	/** GET request handler for list of all photos */
-	@RestMethod(name="GET", path="/")
+	@RestMethod(name="GET", path="/", summary="Show the list of all currently loaded photos")
 	public Collection<Photo> getAllPhotos() throws Exception {
 		return photos.values();
 	}
 
 	/** GET request handler for single photo */
-	@RestMethod(name="GET", path="/{id}", serializers=ImageSerializer.class)
+	@RestMethod(name="GET", path="/{id}", serializers=ImageSerializer.class, summary="Get a photo by ID")
 	public BufferedImage getPhoto(@Path int id) throws Exception {
 		Photo p = photos.get(id);
 		if (p == null)
@@ -95,14 +95,14 @@ public class PhotosResource extends Resource {
 	}
 
 	/** PUT request handler */
-	@RestMethod(name="PUT", path="/{id}", parsers=ImageParser.class)
+	@RestMethod(name="PUT", path="/{id}", parsers=ImageParser.class, summary="Add a photo")
 	public String addPhoto(@Path int id, @Body BufferedImage image) throws Exception {
 		photos.put(id, new Photo(id, image));
 		return "OK";
 	}
 
 	/** POST request handler */
-	@RestMethod(name="POST", path="/", parsers=ImageParser.class)
+	@RestMethod(name="POST", path="/", parsers=ImageParser.class, summary="Overwrite a photo by ID")
 	public Photo setPhoto(@Body BufferedImage image) throws Exception {
 		int id = photos.size();
 		Photo p = new Photo(id, image);
@@ -111,7 +111,7 @@ public class PhotosResource extends Resource {
 	}
 
 	/** DELETE request handler */
-	@RestMethod(name="DELETE", path="/{id}")
+	@RestMethod(name="DELETE", path="/{id}", summary="Delete a photo by ID")
 	public String deletePhoto(@Path int id) throws Exception {
 		Photo p = photos.remove(id);
 		if (p == null)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
index 5cbd34f..244f6a0 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
@@ -29,11 +29,12 @@ import org.apache.juneau.transforms.*;
  */
 @RestResource(
 	path="/echo",
-	messages="nls/RequestEchoResource",
+	title="Request echo service",
+	description="Echos the current HttpServletRequest object back to the browser.",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/RequestEchoResource.java'}",
 	properties={
 		@Property(name=SERIALIZER_maxDepth, value="5"),
-		@Property(name=SERIALIZER_detectRecursions, value="true"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/RequestEchoResource.java'}")
+		@Property(name=SERIALIZER_detectRecursions, value="true")
 	},
 	beanFilters={
 		// Interpret these as their parent classes, not subclasses
@@ -48,11 +49,10 @@ public class RequestEchoResource extends Resource {
 	private static final long serialVersionUID = 1L;
 
 	/** GET request handler */
-	@RestMethod(name="GET", path="/*", converters={Traversable.class,Queryable.class})
-	public HttpServletRequest doGet(RestRequest req, @Properties ObjectMap properties) {
+	@RestMethod(name="GET", path="/*", converters={Traversable.class,Queryable.class}, summary="Serializes the incoming HttpServletRequest object.")
+	public HttpServletRequest doGet(RestRequest req, RestResponse res, @Properties ObjectMap properties) {
 		// Set the HtmlDocSerializer title programmatically.
-		// This sets the value for this request only.
-		properties.put(HTMLDOC_title, "Contents of HttpServletRequest object");
+		res.setPageTitle("Contents of HttpServletRequest object");
 
 		// Just echo the request back as the response.
 		return req;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
index ce51c81..6ce7e38 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.examples.rest.addressbook.*;
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.microservice.resources.*;
@@ -24,10 +22,9 @@ import org.apache.juneau.rest.annotation.*;
  */
 @RestResource(
 	path="/",
-	messages="nls/RootResources",
-	properties={
-		@Property(name=HTMLDOC_links, value="{options:'$R{servletURI}?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/RootResources.java'}")
-	},
+	title="Root resources",
+	description="This is an example of a router resource that is used to access other resources.",
+	pageLinks="{options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/RootResources.java'}",
 	children={
 		HelloWorldResource.class,
 		SystemPropertiesResource.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
index 4173623..b581e18 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.rest.RestContext.*;
 
 import java.util.*;
@@ -28,10 +27,10 @@ import org.apache.juneau.rest.remoteable.*;
 @RestResource(
 	path="/remoteable",
 	messages="nls/SampleRemoteableServlet",
+	title="Remoteable Service Proxy API",
+	description="Sample class showing how to use remoteable proxies.  The list below are exposed services that can be retrieved using RestClient.getProxyInterface(Class).",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SampleRemoteableServlet.java'}",
 	properties={
-		@Property(name=HTMLDOC_title, value="Remoteable Service Proxy API"),
-		@Property(name=HTMLDOC_description, value="Sample class showing how to use remoteable proxies.  The list below are exposed services that can be retrieved using RestClient.getProxyInterface(Class)."),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SampleRemoteableServlet.java'}"),
 		// Allow us to use method=POST from a browser.
 		@Property(name=REST_allowMethodParam, value="*")
 	},

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
index e32d302..5be1140 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
@@ -14,7 +14,6 @@ package org.apache.juneau.examples.rest;
 
 import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.sql.*;
 import java.util.*;
@@ -34,11 +33,9 @@ import org.apache.juneau.rest.annotation.Body;
 @RestResource(
 	path="/sqlQuery",
 	messages="nls/SqlQueryResource",
-	properties={
-		@Property(name=HTMLDOC_title, value="SQL query service"),
-		@Property(name=HTMLDOC_description, value="Executes queries against the local derby '$C{SqlQueryResource/connectionUrl}' database"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SqlQueryResource.java'}"),
-	}
+	title="SQL query service",
+	description="Executes queries against the local derby '$C{SqlQueryResource/connectionUrl}' database",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SqlQueryResource.java'}"
 )
 public class SqlQueryResource extends Resource {
 	private static final long serialVersionUID = 1L;
@@ -65,7 +62,7 @@ public class SqlQueryResource extends Resource {
 	}
 
 	/** GET request handler - Display the query entry page. */
-	@RestMethod(name="GET", path="/")
+	@RestMethod(name="GET", path="/", summary="Display the query entry page")
 	public Div doGet(RestRequest req) {
 		return div(
 			script("text/javascript",
@@ -108,7 +105,7 @@ public class SqlQueryResource extends Resource {
 	}
 
 	/** POST request handler - Execute the query. */
-	@RestMethod(name="POST", path="/")
+	@RestMethod(name="POST", path="/", summary="Execute one or more queries")
 	public List<Object> doPost(@Body PostInput in) throws Exception {
 
 		List<Object> results = new LinkedList<Object>();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
index 538ac73..8cb843e 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
@@ -30,9 +30,9 @@ import org.apache.juneau.rest.annotation.Body;
 	path="/systemProperties",
 	title="System properties resource",
 	description="REST interface for performing CRUD operations on system properties.",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',form:'formPage',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java'}",
 	properties={
-		@Property(name=SERIALIZER_quoteChar, value="'"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',form:'formPage',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java'}"),
+		@Property(name=SERIALIZER_quoteChar, value="'")
 	},
 	stylesheet="styles/devops.css",
 	encoders=GzipEncoder.class,


[2/3] incubator-juneau git commit: Add @RestResource.pageTitle/pageText/pageLinks annotations.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
index 70c7b73..b92f3c3 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
@@ -13,7 +13,6 @@
 package org.apache.juneau.examples.rest;
 
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.io.*;
 
@@ -29,13 +28,14 @@ import org.apache.juneau.utils.*;
  */
 @RestResource(
 	path="/tempDir",
-	messages="nls/TempDirResource",
+	title="Temp Directory View Service",
+	description="View and download files in the '$S{java.io.tmpdir}' directory.",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',upload:'upload',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TempDirResource.java'}",
 	properties={
 		@Property(name="rootDir", value="$S{java.io.tmpdir}"),
 		@Property(name="allowViews", value="true"),
 		@Property(name="allowDeletes", value="true"),
-		@Property(name="allowPuts", value="false"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',upload:'upload',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TempDirResource.java'}"),
+		@Property(name="allowPuts", value="false")
 	},
 	stylesheet="styles/devops.css"
 )

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
index 282fa04..bd53404 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.*;
 import org.apache.juneau.dto.Link;
 import org.apache.juneau.dto.html5.*;
@@ -24,21 +22,19 @@ import org.apache.juneau.rest.client.*;
 @RestResource(
 	path="/tumblrParser",
 	messages="nls/TumblrParserResource",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TumblrParserResource.java'}"),
-		@Property(name=HTMLDOC_title, value="Tumblr parser service"),
-		@Property(name=HTMLDOC_description, value="Specify a URL to a Tumblr blog and parse the results.")
-	}
+	title="Tumblr parser service",
+	description="Specify a URL to a Tumblr blog and parse the results.",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TumblrParserResource.java'}"
 )
 public class TumblrParserResource extends Resource {
 	private static final long serialVersionUID = 1L;
 
-	@RestMethod(name="GET", path="/")
+	@RestMethod(name="GET", path="/", summary="Get the instructions page")
 	public String getInstructions() throws Exception {
 		return "Append the Tumblr blog name to the URL above (e.g. /juneau/sample/tumblrParser/mytumblrblog)";
 	}
 
-	@RestMethod(name="GET", path="/{blogName}")
+	@RestMethod(name="GET", path="/{blogName}", summary="Parse the specified blog")
 	public ObjectList parseBlog(@Path String blogName) throws Exception {
 		ObjectList l = new ObjectList();
 		RestClient rc = new RestClientBuilder().build();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
index 3f548b0..ec13b5e 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
@@ -13,7 +13,6 @@
 package org.apache.juneau.examples.rest;
 
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.util.*;
 
@@ -31,11 +30,9 @@ import org.apache.juneau.transforms.*;
 @RestResource(
 	path="/urlEncodedForm",
 	messages="nls/UrlEncodedFormResource",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/UrlEncodedFormResource.java'}"),
-		@Property(name=HTMLDOC_title, value="Tumblr parser service"),
-		@Property(name=HTMLDOC_description, value="Specify a URL to a Tumblr blog and parse the results.")
-	}
+	title="Tumblr parser service",
+	description="Specify a URL to a Tumblr blog and parse the results.",
+	pageLinks="{up:'$R{requestParentURI}',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/UrlEncodedFormResource.java'}"
 )
 public class UrlEncodedFormResource extends Resource {
 	private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
index 4a49a60..ab9ef57 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
@@ -41,13 +41,13 @@ import org.apache.juneau.utils.*;
 @RestResource(
 	path="/addressBook",
 	messages="nls/AddressBookResource",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java'}",
 	properties={
 		@Property(name=REST_allowMethodParam, value="*"),
 		@Property(name=HTML_uriAnchorText, value=TO_STRING),
 		@Property(name=SERIALIZER_quoteChar, value="'"),
 		@Property(name=RDF_rdfxml_tab, value="5"),
 		@Property(name=RDF_addRootProperty, value="true"),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java'}"),
 		// Resolve all relative URIs so that they're relative to this servlet!
 		@Property(name=SERIALIZER_relativeUriBase, value="$R{servletURI}"),
 	},

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/AtomFeedResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/AtomFeedResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/AtomFeedResource.properties
deleted file mode 100644
index 7ff4a44..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/AtomFeedResource.properties
+++ /dev/null
@@ -1,21 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# AtomFeedResource labels
-#--------------------------------------------------------------------------------
-title = Sample ATOM feed resource
-description = Sample resource that shows how to render ATOM feeds
-getFeed = Get the sample ATOM feed
-setFeed = Overwrite the sample ATOM feed
-doOptions = Show resource options

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/CodeFormatterResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/CodeFormatterResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/CodeFormatterResource.properties
deleted file mode 100644
index ac2f236..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/CodeFormatterResource.properties
+++ /dev/null
@@ -1,18 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# CodeFormatterResource labels
-#--------------------------------------------------------------------------------
-title = Code Formatter
-description = Utility for generating HTML code-formatted source code

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/HelloWorldResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/HelloWorldResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/HelloWorldResource.properties
deleted file mode 100644
index 7c8f03d..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/HelloWorldResource.properties
+++ /dev/null
@@ -1,19 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# HelloWorldResource labels
-#--------------------------------------------------------------------------------
-title = Hello World sample resource
-description = Simplest possible resource
-sayHello = Responds with "Hello world!" 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/JsonSchemaResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/JsonSchemaResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/JsonSchemaResource.properties
deleted file mode 100644
index 1a486a9..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/JsonSchemaResource.properties
+++ /dev/null
@@ -1,20 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# JsonSchemaResource labels
-#--------------------------------------------------------------------------------
-title = Sample resource that shows how to generate JSON-Schema documents
-getSchema = Get the JSON-Schema document
-setSchema = Overwrite the JSON-Schema document
-doOptions = Show resource options

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/PhotosResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/PhotosResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/PhotosResource.properties
deleted file mode 100644
index 93f7f7d..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/PhotosResource.properties
+++ /dev/null
@@ -1,24 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# PhotosResource labels
-#--------------------------------------------------------------------------------
-title = Sample resource that allows images to be uploaded and retrieved.
-getAllPhotos = Show the list of all currently loaded photos
-getPhoto = Get a photo by ID
-addPhoto = Add a photo
-setPhoto = Overwrite a photo by ID
-deletePhoto = Delete a photo by ID
-doOptions = Show resource options
-

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RequestEchoResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RequestEchoResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RequestEchoResource.properties
deleted file mode 100644
index db7641c..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RequestEchoResource.properties
+++ /dev/null
@@ -1,19 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# RequestEchoResource labels
-#--------------------------------------------------------------------------------
-title = Echos the current HttpServletRequest object back to the browser.
-doGet = Serializes the incoming HttpServletRequest object.
-

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RootResources.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RootResources.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RootResources.properties
deleted file mode 100644
index 301057d..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/RootResources.properties
+++ /dev/null
@@ -1,18 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# RootResources labels
-#--------------------------------------------------------------------------------
-title = Root resources
-description = This is an example of a router resource that is used to access other resources.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SampleRemoteableServlet.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SampleRemoteableServlet.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SampleRemoteableServlet.properties
deleted file mode 100644
index 48fd5ce..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SampleRemoteableServlet.properties
+++ /dev/null
@@ -1,17 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# SampleRemoteableServlet labels
-#--------------------------------------------------------------------------------
-title = Sample resource that demonstrates the remotable API

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SourceResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SourceResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SourceResource.properties
deleted file mode 100644
index 363f00a..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SourceResource.properties
+++ /dev/null
@@ -1,19 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# SourceResource labels
-#--------------------------------------------------------------------------------
-title = Servlet for viewing source code on classes whose Java files are present on the classpath.
-getSource = View source on the specified classes.
-

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SqlQueryResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SqlQueryResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SqlQueryResource.properties
deleted file mode 100644
index 527ca93..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/SqlQueryResource.properties
+++ /dev/null
@@ -1,19 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# SqlQueryResource labels
-#--------------------------------------------------------------------------------
-title = Sample resource that shows how to serialize SQL ResultSets 
-doGet = Display the query entry page
-doPost = Execute one or more queries

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TempDirResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TempDirResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TempDirResource.properties
deleted file mode 100644
index 94c009e..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TempDirResource.properties
+++ /dev/null
@@ -1,18 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# TempDirResource labels
-#--------------------------------------------------------------------------------
-title = Temp Directory View Service
-description = View and download files in the '$S{java.io.tmpdir}' directory.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TumblrParserResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TumblrParserResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TumblrParserResource.properties
deleted file mode 100644
index 28a3e72..0000000
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/TumblrParserResource.properties
+++ /dev/null
@@ -1,19 +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.                                              *
-# ***************************************************************************************************************************
-
-#--------------------------------------------------------------------------------
-# SqlQueryResource labels
-#--------------------------------------------------------------------------------
-title = Tumblr blog parser service
-getInstructions = Get the instructions page
-parseBlog = Parse the specified blog

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/UrlEncodedFormResource.properties
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/UrlEncodedFormResource.properties b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/UrlEncodedFormResource.properties
index c7015c3..22575ae 100644
--- a/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/UrlEncodedFormResource.properties
+++ b/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/nls/UrlEncodedFormResource.properties
@@ -14,8 +14,6 @@
 #--------------------------------------------------------------------------------
 # UrlEncodedFormResource labels
 #--------------------------------------------------------------------------------
-title = URL-Encoded Form Post Example
-description = Shows how URL-Encoded form input can be loaded into POJOs.  POJO is simply echoed back.
 aString = A String:
 aNumber = A Number:
 aDate = A Date:

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
index 6102193..bd57ece 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
@@ -40,7 +40,7 @@ import org.apache.juneau.svl.vars.*;
 @SuppressWarnings("serial")
 @RestResource(
 	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS'}")
+		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS'}")
 	},
 	config="$S{juneau.configFile}",
 	stylesheet="$C{REST/stylesheet,styles/juneau.css}"

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
index 440bd28..e02234b 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.microservice;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.svl.vars.*;
@@ -40,9 +38,7 @@ import org.apache.juneau.svl.vars.*;
  */
 @SuppressWarnings("serial")
 @RestResource(
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS'}"),
-	},
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS'}",
 	config="$S{juneau.configFile}",
 	stylesheet="$C{REST/stylesheet,styles/juneau.css}"
 )

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJena.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJena.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJena.java
index 9c40804..2eafb12 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJena.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJena.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.microservice;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
-
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.jena.*;
 
@@ -22,9 +20,7 @@ import org.apache.juneau.rest.jena.*;
  */
 @SuppressWarnings("serial")
 @RestResource(
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS'}")
-	},
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS'}",
 	config="$S{juneau.configFile}",
 	stylesheet="$C{REST/stylesheet,styles/juneau.css}"
 )

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
index f77d119..dcdf2c5 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
@@ -166,7 +166,7 @@
 		title=<js>"Juneau Microservice Template"</js>,
 		description=<js>"Template for creating REST microservices"</js>,
 		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'$R{servletURI}?method=OPTIONS'}"</js>)
+			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>)
 		},
 		children={
 			HelloWorldResource.<jk>class</jk>,
@@ -755,7 +755,7 @@
 		title=<js>"Juneau Microservice Template"</js>,
 		description=<js>"Template for creating REST microservices"</js>,
 		properties={
-			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'$R{servletURI}?method=OPTIONS'}"</js>)
+			<ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>)
 		},
 		children={
 			HelloWorldResource.<jk>class</jk>,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
index 5bd0438..3d60bb9 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
@@ -14,7 +14,6 @@ package org.apache.juneau.microservice.resources;
 
 import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.io.*;
 import java.util.Map;
@@ -34,9 +33,7 @@ import org.apache.juneau.rest.annotation.Body;
 	path="/config",
 	title="Configuration",
 	description="Contents of configuration file.",
-	properties={
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',edit:'$R{servletURI}/edit'}"),
-	}
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS',edit:'edit'}"
 )
 public class ConfigResource extends Resource {
 	private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
index 0922221..556dd98 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
@@ -57,9 +57,9 @@ import org.apache.juneau.utils.*;
 	title="File System Explorer",
 	description="Contents of $R{attribute.path}",
 	messages="nls/DirectoryResource",
+	pageLinks="{up:'$R{requestParentURI}',options:'?method=OPTIONS'}",
 	properties={
 		@Property(name=HTML_uriAnchorText, value=PROPERTY_NAME),
-		@Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.rest.samples.DirectoryResource)'}"),
 		@Property(name=REST_allowMethodParam, value="*"),
 		@Property(name="DirectoryResource.rootDir", value=""),
 		@Property(name="DirectoryResource.allowViews", value="false"),

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
index b2011a4..e39aa7a 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
@@ -32,6 +32,7 @@ import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.annotation.Properties;
 import org.apache.juneau.rest.converters.*;
 import org.apache.juneau.transforms.*;
+import org.apache.juneau.utils.*;
 
 /**
  * REST resource for viewing and accessing log files.
@@ -80,13 +81,14 @@ public class LogsResource extends Resource {
 	 * [GET /*] - Get file details or directory listing.
 	 *
 	 * @param req The HTTP request
+	 * @param res The HTTP response
 	 * @param properties The writable properties for setting the descriptions.
 	 * @param path The log file path.
 	 * @return The log file.
 	 * @throws Exception
 	 */
 	@RestMethod(name="GET", path="/*", responses={@Response(200),@Response(404)})
-	public Object getFileOrDirectory(RestRequest req, @Properties ObjectMap properties, @PathRemainder String path) throws Exception {
+	public Object getFileOrDirectory(RestRequest req, RestResponse res, @Properties ObjectMap properties, @PathRemainder String path) throws Exception {
 
 		File f = getFile(path);
 
@@ -99,11 +101,12 @@ public class LogsResource extends Resource {
 					l.add(new FileResource(fc, fUrl));
 				}
 			}
-			properties.put(HTMLDOC_description, "Contents of " + f.getAbsolutePath());
+			res.setPageText(new StringMessage("Contents of {0}", f.getAbsolutePath()));
+			properties.put(HTMLDOC_text, "Contents of " + f.getAbsolutePath());
 			return l;
 		}
 
-		properties.put(HTMLDOC_description, "File details on " + f.getAbsolutePath());
+		res.setPageText(new StringMessage("File details on {0}", f.getAbsolutePath()));
 		return new FileResource(f, new URL(req.getTrimmedRequestURL().toString()));
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlPropertiesResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlPropertiesResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlPropertiesResource.java
new file mode 100644
index 0000000..648008c
--- /dev/null
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlPropertiesResource.java
@@ -0,0 +1,305 @@
+// ***************************************************************************************************************************
+// * 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.rest.test;
+
+import org.apache.juneau.html.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * JUnit automated testcase resource.
+ * Tests the various permutations of populating the HTML page titles, text, and links.
+ */
+@RestResource(
+	path="/testHtmlProperties",
+	children={
+		HtmlPropertiesResource.Normal.class,
+		HtmlPropertiesResource.NormalInit.class,
+		HtmlPropertiesResource.NormalDefaulting.class,
+		HtmlPropertiesResource.NormalSubclassed1.class,
+		HtmlPropertiesResource.NormalSubclassed2.class,
+		HtmlPropertiesResource.LocalizedImplicit.class,
+		HtmlPropertiesResource.LocalizedExplicit.class
+	}
+)
+@SuppressWarnings("serial")
+public class HtmlPropertiesResource extends RestServletGroupDefault {
+	private static final long serialVersionUID = 1L;
+
+
+	@RestResource(
+		path="/Normal",
+		pageTitle="Normal-title",
+		pageText="Normal-text",
+		pageLinks="{link:'Normal-links'}"
+	)
+	public static class Normal extends RestServletDefault {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX).
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(name="GET", path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX), overridden by @RestMethod(pageX) annotations.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test2", pageTitle="Normal.test2-title", pageText="Normal.test2-text", pageLinks="{link:'Normal.test2-links'}")
+		public String test2() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX), overridden by RestResponse.setPageX() methods.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test3")
+		public String test3(RestResponse res) {
+			res.setPageTitle("Normal.test3-title");
+			res.setPageText("Normal.test3-text");
+			res.setPageLinks("{link:'Normal.test3-links'}");
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX), overridden by RestResponse.setProperty() method.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test4")
+		public String test4(RestResponse res) {
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_title, "Normal.test4-title");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_text, "Normal.test4-text");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_links, "{link:'Normal.test4-links'}");
+			return "OK";
+		}
+	}
+
+	@RestResource(
+		path="/NormalInit"
+	)
+	public static class NormalInit extends RestServletDefault {
+
+		@Override
+		public void init(RestConfig config) throws Exception {
+			config.setPageTitle("NormalInit-title");
+			config.setPageText("NormalInit-text");
+			config.setPageLinks("{link:'NormalInit-links'}");
+			super.init(config);
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from RestConfig.setX() methods.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from RestConfig.setX() methods, overridden by @RestMethod(pageX) annotations.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test2", pageTitle="NormalInit.test2-title", pageText="NormalInit.test2-text", pageLinks="{link:'NormalInit.test2-links'}")
+		public String test2() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from RestConfig.setX() methods, overridden by RestResponse.setPageX() methods.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test3")
+		public String test3(RestResponse res) {
+			res.setPageTitle("NormalInit.test3-title");
+			res.setPageText("NormalInit.test3-text");
+			res.setPageLinks("{link:'NormalInit.test3-links'}");
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from RestConfig.setX() methods, overridden by RestResponse.setProperty() method.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test4")
+		public String test4(RestResponse res) {
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_title, "NormalInit.test4-title");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_text, "NormalInit.test4-text");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_links, "{link:'NormalInit.test4-links'}");
+			return "OK";
+		}
+	}
+
+	@RestResource(
+		path="/NormalDefaulting",
+		title="NormalDefaulting-title",
+		description="NormalDefaulting-description"
+	)
+	public static class NormalDefaulting extends RestServletDefault {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(path/title).
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(path/title), overridden by @RestMethod(pageX) annotations.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test2", summary="NormalDefaulting.test2-summary")
+		public String test2() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(path/title), overridden by RestResponse.setPageX() methods.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test3")
+		public String test3(RestResponse res) {
+			res.setPageTitle("NormalDefaulting.test3-title");
+			res.setPageText("NormalDefaulting.test3-text");
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(path/title), overridden by RestResponse.setProperty() method.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test4")
+		public String test4(RestResponse res) {
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_title, "NormalDefaulting.test4-title");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_text, "NormalDefaulting.test4-text");
+			return "OK";
+		}
+	}
+
+
+	@RestResource(
+		path="/NormalSubclassed1"
+	)
+	public static class NormalSubclassed1 extends Normal {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from parent @RestResource(path/title).
+		//----------------------------------------------------------------------------------------------------
+		@Override
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from parent @RestResource(path/title), overridden by @RestMethod(pageX) annotations.
+		//----------------------------------------------------------------------------------------------------
+		@Override
+		@RestMethod(path="/test2", pageTitle="NormalSubclassed1.test2-title", pageText="NormalSubclassed1.test2-text", pageLinks="{link:'NormalSubclassed1.test2-links'}")
+		public String test2() {
+			return "OK";
+		}
+	}
+
+	@RestResource(
+		path="/NormalSubclassed2",
+		pageTitle="NormalSubclassed2-title",
+		pageText="NormalSubclassed2-text",
+		pageLinks="{link:'NormalSubclassed2-links'}"
+	)
+	public static class NormalSubclassed2 extends Normal {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from parent @RestResource(path/title), overridden by child @RestResource(pageTitle/pageText).
+		//----------------------------------------------------------------------------------------------------
+		@Override
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from parent @RestResource(path/title), overridden by @RestMethod(pageX).
+		//----------------------------------------------------------------------------------------------------
+		@Override
+		@RestMethod(path="/test2", pageTitle="NormalSubclassed2.test2-title", pageText="NormalSubclassed2.test2-text", pageLinks="{link:'NormalSubclassed2.test2-links'}")
+		public String test2() {
+			return "OK";
+		}
+	}
+
+	@RestResource(
+		path="/LocalizedExplicit",
+		messages="HtmlPropertiesResource",
+		pageTitle="$L{pageTitle}",
+		pageText="$L{pageText}",
+		pageLinks="$L{pageLinks}"
+	)
+	public static class LocalizedExplicit extends RestServletDefault {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX) with $L variables.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX) with $L variables, overridden by @RestMethod(pageX) with $L variables.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test2", pageTitle="$L{test2.pageTitle}", pageText="$L{test2.pageText}", pageLinks="$L{test2.pageLinks}")
+		public String test2() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX) with $L variables, overridden by RestResponse.setPageX() with $L variables.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test3")
+		public String test3(RestResponse res) {
+			res.setPageTitle("$L{test3.pageTitle}");
+			res.setPageText("$L{test3.pageText}");
+			res.setPageLinks("$L{test3.pageLinks}");
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from @RestResource(pageX) with $L variables, overridden by RestResponse.setProperty() with $L variables.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test4")
+		public String test4(RestResponse res) {
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_title, "$L{test4.pageTitle}");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_text, "$L{test4.pageText}");
+			res.setProperty(HtmlDocSerializerContext.HTMLDOC_links, "$L{test4.pageLinks}");
+			return "OK";
+		}
+	}
+
+	@RestResource(
+		path="/LocalizedImplicit",
+		messages="HtmlPropertiesResource"
+	)
+	public static class LocalizedImplicit extends RestServletDefault {
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from resource bundle.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test1")
+		public String test1() {
+			return "OK";
+		}
+
+		//----------------------------------------------------------------------------------------------------
+		// Values pulled from resource bundle, overridden by values in resource bundle at method level.
+		//----------------------------------------------------------------------------------------------------
+		@RestMethod(path="/test2")
+		public String test2() {
+			return "OK";
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
index ceeaf48..74834a0 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -33,6 +33,7 @@ import org.apache.juneau.rest.labels.*;
 		GroupsResource.class,
 		GzipResource.TestGzipOff.class,
 		GzipResource.TestGzipOn.class,
+		HtmlPropertiesResource.class,
 		InheritanceResource.TestEncoders.class,
 		InheritanceResource.TestTransforms.class,
 		InheritanceResource.TestParsers.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest-test/src/main/resources/org/apache/juneau/rest/test/HtmlPropertiesResource.properties
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/resources/org/apache/juneau/rest/test/HtmlPropertiesResource.properties b/juneau-rest-test/src/main/resources/org/apache/juneau/rest/test/HtmlPropertiesResource.properties
new file mode 100644
index 0000000..a216564
--- /dev/null
+++ b/juneau-rest-test/src/main/resources/org/apache/juneau/rest/test/HtmlPropertiesResource.properties
@@ -0,0 +1,37 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# *                                                                                                                         *
+# ***************************************************************************************************************************
+
+LocalizedExplicit.pageTitle = LocalizedExplicit.nls.pageTitle
+LocalizedExplicit.pageText = LocalizedExplicit.nls.pageText
+LocalizedExplicit.pageLinks = {link:'LocalizedExplicit.nls.pageLinks'}
+
+LocalizedExplicit.test2.pageTitle = LocalizedExplicit.test2.nls.pageTitle
+LocalizedExplicit.test2.pageText = LocalizedExplicit.test2.nls.pageText
+LocalizedExplicit.test2.pageLinks = {link:'LocalizedExplicit.test2.nls.pageLinks'}
+
+LocalizedExplicit.test3.pageTitle = LocalizedExplicit.test3.nls.pageTitle
+LocalizedExplicit.test3.pageText = LocalizedExplicit.test3.nls.pageText
+LocalizedExplicit.test3.pageLinks = {link:'LocalizedExplicit.test3.nls.pageLinks'}
+
+LocalizedExplicit.test4.pageTitle = LocalizedExplicit.test4.nls.pageTitle
+LocalizedExplicit.test4.pageText = LocalizedExplicit.test4.nls.pageText
+LocalizedExplicit.test4.pageLinks = {link:'LocalizedExplicit.test4.nls.pageLinks'}
+
+LocalizedImplicit.pageTitle = LocalizedImplicit.nls.pageTitle
+LocalizedImplicit.pageText = LocalizedImplicit.nls.pageText
+LocalizedImplicit.pageLinks = {link:'LocalizedImplicit.nls.pageLinks'}
+
+LocalizedImplicit.test2.pageTitle = LocalizedImplicit.test2.nls.pageTitle
+LocalizedImplicit.test2.pageText = LocalizedImplicit.test2.nls.pageText
+LocalizedImplicit.test2.pageLinks = {link:'LocalizedImplicit.test2.nls.pageLinks'}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/703cadd2/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlPropertiesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlPropertiesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlPropertiesTest.java
new file mode 100644
index 0000000..410060d
--- /dev/null
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlPropertiesTest.java
@@ -0,0 +1,286 @@
+// ***************************************************************************************************************************
+// * 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.rest.test;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.rest.client.*;
+import org.junit.*;
+
+/**
+ * Tests HTML page titles, text, and links.
+ */
+public class HtmlPropertiesTest extends RestTestcase {
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX).
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalTest1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/Normal/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("Normal-title"));
+		assertTrue(s.contains("Normal-text"));
+		assertTrue(s.contains("Normal-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX), overridden by @RestMethod(pageX) annotations.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalTest2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/Normal/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("Normal.test2-title"));
+		assertTrue(s.contains("Normal.test2-text"));
+		assertTrue(s.contains("Normal.test2-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX), overridden by RestResponse.setPageX() methods.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalTest3() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/Normal/test3").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("Normal.test3-title"));
+		assertTrue(s.contains("Normal.test3-text"));
+		assertTrue(s.contains("Normal.test3-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX), overridden by RestResponse.setProperty() method.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalTest4() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/Normal/test4").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("Normal.test4-title"));
+		assertTrue(s.contains("Normal.test4-text"));
+		assertTrue(s.contains("Normal.test4-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from RestConfig.setX() methods.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalInitTest1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalInit/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalInit-title"));
+		assertTrue(s.contains("NormalInit-text"));
+		assertTrue(s.contains("NormalInit-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from RestConfig.setX() methods, overridden by @RestMethod(pageX) annotations.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalInitTest2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalInit/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalInit.test2-title"));
+		assertTrue(s.contains("NormalInit.test2-text"));
+		assertTrue(s.contains("NormalInit.test2-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from RestConfig.setX() methods, overridden by RestResponse.setPageX() methods.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalInitTest3() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalInit/test3").accept("text/html").getResponseAsString();
+		System.err.println(s);
+		assertTrue(s.contains("NormalInit.test3-title"));
+		assertTrue(s.contains("NormalInit.test3-text"));
+		assertTrue(s.contains("NormalInit.test3-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from RestConfig.setX() methods, overridden by RestResponse.setProperty() method.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalInitTest4() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalInit/test4").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalInit.test4-title"));
+		assertTrue(s.contains("NormalInit.test4-text"));
+		assertTrue(s.contains("NormalInit.test4-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(path/title).
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalDefaultingTest1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalDefaulting/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalDefaulting-title"));
+		assertTrue(s.contains("NormalDefaulting-description"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(path/title), overridden by @RestMethod(pageX) annotations.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalDefaultingTest2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalDefaulting/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalDefaulting-title"));
+		assertTrue(s.contains("NormalDefaulting.test2-summary"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(path/title), overridden by RestResponse.setPageX() methods.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalDefaultingTest3() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalDefaulting/test3").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalDefaulting.test3-title"));
+		assertTrue(s.contains("NormalDefaulting.test3-text"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(path/title), overridden by RestResponse.setProperty() method.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalDefaultingTest4() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalDefaulting/test4").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalDefaulting.test4-title"));
+		assertTrue(s.contains("NormalDefaulting.test4-text"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from parent @RestResource(path/title).
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalSubclassed1Test1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalSubclassed1/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("Normal-title"));
+		assertTrue(s.contains("Normal-text"));
+		assertTrue(s.contains("Normal-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from parent @RestResource(path/title), overridden by @RestMethod(pageX) annotations.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalSubclassed1Test2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalSubclassed1/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalSubclassed1.test2-title"));
+		assertTrue(s.contains("NormalSubclassed1.test2-text"));
+		assertTrue(s.contains("NormalSubclassed1.test2-links"));
+
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from parent @RestResource(path/title), overridden by child @RestResource(pageTitle/pageText).
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalSubclassed2Test1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalSubclassed2/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalSubclassed2-title"));
+		assertTrue(s.contains("NormalSubclassed2-text"));
+		assertTrue(s.contains("NormalSubclassed2-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from parent @RestResource(path/title), overridden by @RestMethod(pageX).
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testNormalSubclassed2Test2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/NormalSubclassed2/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("NormalSubclassed2.test2-title"));
+		assertTrue(s.contains("NormalSubclassed2.test2-text"));
+		assertTrue(s.contains("NormalSubclassed2.test2-links"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX) with $L variables.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedExplicitTest1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedExplicit/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedExplicit.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedExplicit.nls.pageText"));
+		assertTrue(s.contains("LocalizedExplicit.nls.pageLinks"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX) with $L variables, overridden by @RestMethod(pageX) with $L variables.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedExplicitTest2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedExplicit/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedExplicit.test2.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedExplicit.test2.nls.pageText"));
+		assertTrue(s.contains("LocalizedExplicit.test2.nls.pageLinks"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX) with $L variables, overridden by RestResponse.setPageX() with $L variables.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedExplicitTest3() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedExplicit/test3").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedExplicit.test3.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedExplicit.test3.nls.pageText"));
+		assertTrue(s.contains("LocalizedExplicit.test3.nls.pageLinks"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from @RestResource(pageX) with $L variables, overridden by RestResponse.setProperty() with $L variables.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedExplicitTest4() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedExplicit/test4").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedExplicit.test4.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedExplicit.test4.nls.pageText"));
+		assertTrue(s.contains("LocalizedExplicit.test4.nls.pageLinks"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from resource bundle.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedImplicitTest1() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedImplicit/test1").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedImplicit.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedImplicit.nls.pageText"));
+		assertTrue(s.contains("LocalizedImplicit.nls.pageLinks"));
+	}
+
+	//----------------------------------------------------------------------------------------------------
+	// Values pulled from resource bundle, overridden by values in resource bundle at method level.
+	//----------------------------------------------------------------------------------------------------
+	@Test
+	public void testLocalizedImplicitTest2() throws Exception {
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String s = client.doGet("/testHtmlProperties/LocalizedImplicit/test2").accept("text/html").getResponseAsString();
+		assertTrue(s.contains("LocalizedImplicit.test2.nls.pageTitle"));
+		assertTrue(s.contains("LocalizedImplicit.test2.nls.pageText"));
+		assertTrue(s.contains("LocalizedImplicit.test2.nls.pageLinks"));
+	}
+}