juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject juneau git commit: RestContext refactoring.
Date Thu, 04 Jan 2018 19:21:48 GMT
Repository: juneau
Updated Branches:
  refs/heads/master 01ad43031 -> 223e6c6fd


RestContext refactoring.

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

Branch: refs/heads/master
Commit: 223e6c6fdd060b07f3ebc3832fceef0f713f4029
Parents: 01ad430
Author: JamesBognar <jamesbognar@apache.org>
Authored: Thu Jan 4 14:21:37 2018 -0500
Committer: JamesBognar <jamesbognar@apache.org>
Committed: Thu Jan 4 14:21:37 2018 -0500

----------------------------------------------------------------------
 .../org/apache/juneau/rest/RestContext.java     |  83 +++++++++---
 .../apache/juneau/rest/RestContextBuilder.java  | 129 ++++++++++++++++---
 .../apache/juneau/rest/annotation/HtmlDoc.java  |  53 +++++++-
 .../org/apache/juneau/rest/widget/Widget.java   |  33 +++--
 4 files changed, 249 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/223e6c6f/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index d1079b5..bee4518 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -986,6 +986,68 @@ public final class RestContext extends BeanContext {
 	 */
 	public static final String REST_useClasspathResourceCaching = PREFIX + "useClasspathResourceCaching.b";
 
+	/**
+	 * <b>Configuration property:</b>  HTML Widgets. 
+	 *
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RestContext.widgets.lo"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;Class&lt;? <jk>extends</jk>
Widget&gt; | Widget&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * 
+	 * <p>
+	 * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to
quickly
+	 * generate arbitrary replacement text.
+	 * 
+	 * Widgets resolve the following variables:
+	 * <ul>
+	 * 	<li><js>"$W{name}"</js> - Contents returned by {@link Widget#getHtml(RestRequest)}.
+	 * 	<li><js>"$W{name.script}"</js> - Contents returned by {@link Widget#getScript(RestRequest)}.
+	 * 		<br>The script contents are automatically inserted into the <xt>&lt;head/script&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * 	<li><js>"$W{name.style}"</js> - Contents returned by {@link Widget#getStyle(RestRequest)}.
+	 * 		<br>The styles contents are automatically inserted into the <xt>&lt;head/style&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * </ul>
+	 *
+	 * <p>
+	 * The following examples shows how to associate a widget with a REST method and then have
it rendered in the links
+	 * and aside section of the page:
+	 *
+	 * <p class='bcode'>
+	 * 	<ja>@RestMethod</ja>(
+	 * 		widgets={
+	 * 			MyWidget.<jk>class</jk>
+	 * 		}
+	 * 		htmldoc=<ja>@HtmlDoc</ja>(
+	 * 			navlinks={
+	 * 				<js>"$W{MyWidget}"</js>
+	 * 			},
+	 * 			aside={
+	 * 				<js>"Check out this widget:  $W{MyWidget}"</js>
+	 * 			}
+	 * 		)
+	 * 	)
+	 * </p>
+	 * 
+	 * <h6 class='topic'>Notes:</h6>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_widgets}
+	 * 	<li>Annotations: 
+	 * 		<ul>
+	 * 			<li>{@link HtmlDoc#widgets()} 
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#widgets(Class...)}
+	 * 			<li>{@link RestContextBuilder#widgets(Widget...)}
+	 * 			<li>{@link RestContextBuilder#widgets(boolean,Widget...)}
+	 * 		</ul>
+	 * 	<li>Widgets are inherited from parent to child, but can be overridden by reusing
the widget name.
+	 * </ul>
+	 */
+	public static final String REST_widgets = PREFIX + "widgets.lo";
 	
 	//-------------------------------------------------------------------------------------------------------------------
 	// Instance
@@ -1169,7 +1231,11 @@ public final class RestContext extends BeanContext {
 			this.msgs = b.messageBundle;
 			this.childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());
 // Not unmodifiable on purpose so that children can be replaced.
 			this.fullPath = b.fullPath;
-			this.widgets = Collections.unmodifiableMap(b.widgets);
+			
+			Map<String,Widget> _widgets = new LinkedHashMap<>();
+			for (Widget w : getInstanceArrayProperty(REST_widgets, Widget.class, new Widget[0], true,
resource, ps))
+				_widgets.put(w.getName(), w);
+			this.widgets = Collections.unmodifiableMap(_widgets);
 
 			//----------------------------------------------------------------------------------------------------
 			// Initialize the child resources.
@@ -1426,7 +1492,6 @@ public final class RestContext extends BeanContext {
 
 		MessageBundle messageBundle;
 		String fullPath;
-		Map<String,Widget> widgets;
 
 		Builder(RestContextBuilder rcb, PropertyStore ps) throws Exception {
 
@@ -1450,18 +1515,6 @@ public final class RestContext extends BeanContext {
 				messageBundle = new MessageBundle(resource.getClass(), "");
 			
 			fullPath = (rcb.parentContext == null ? "" : (rcb.parentContext.fullPath + '/')) + rcb.path;
-
-			HtmlDocBuilder hdb = new HtmlDocBuilder(rcb.properties);
-
-			this.widgets = new LinkedHashMap<>();
-
-			for (Class<? extends Widget> wc : rcb.widgets) {
-				Widget w = resolve(resource, Widget.class, wc);
-				String n = w.getName();
-				this.widgets.put(n, w);
-				hdb.script("INHERIT", "$W{"+n+".script}");
-				hdb.style("INHERIT", "$W{"+n+".style}");
-			}
 		}
 	}
 
@@ -1794,7 +1847,7 @@ public final class RestContext extends BeanContext {
 	 * The widgets used for resolving <js>"$W{...}"<js> variables.
 	 *
 	 * <p>
-	 * Defined by the {@link HtmlDoc#widgets()} annotation or {@link RestContextBuilder#widget(Class)}
method.
+	 * Defined by the {@link HtmlDoc#widgets()} annotation or {@link RestContextBuilder#widgets(Class...)}
method.
 	 *
 	 * @return The var resolver widgets as a map with keys being the name returned by {@link
Widget#getName()}.
 	 */

http://git-wip-us.apache.org/repos/asf/juneau/blob/223e6c6f/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index d389896..4b9d602 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -112,7 +112,6 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	RestContext parentContext;
 	String path;
 	HtmlDocBuilder htmlDocBuilder;
-	List<Class<? extends Widget>> widgets = new ArrayList<>();
 
 	/**
 	 * Constructor for top-level servlets when using dependency injection.
@@ -251,9 +250,7 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 					maxInput(vr.resolve(r.maxInput()));
 
 				HtmlDoc hd = r.htmldoc();
-				for (Class<? extends Widget> cw : hd.widgets())
-					this.widgets.add(cw);
-
+				widgets(hd.widgets());
 				htmlDocBuilder.process(hd);
 			}
 
@@ -283,6 +280,17 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	 */
 	void init(Object resource) throws ServletException {
 		this.resource = resource;
+
+		// Once we have the resource object, we can construct the Widgets.
+		// We want to do that here so that we can update the script/style properties while they're
still modifiable.
+		HtmlDocBuilder hdb = getHtmlDocBuilder();
+		PropertyStore ps = getPropertyStore();
+		Widget[] widgets = ps.getInstanceArrayProperty(REST_widgets, Widget.class, new Widget[0],
true, ps, resource);
+		for (Widget w : widgets) {
+			hdb.script("INHERIT", "$W{"+w.getName()+".script}");
+			hdb.style("INHERIT", "$W{"+w.getName()+".style}");
+		}
+		widgets(false, widgets);
 		
 		Map<String,Method> map = new LinkedHashMap<>();
 		for (Method m : ClassUtils.getAllMethods(this.resourceClass, true)) {
@@ -679,21 +687,6 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	}
 
 	/**
-	 * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to
quickly
-	 * generate arbitrary replacement text.
-	 *
-	 * <p>
-	 * Widgets are inherited from parent to child, but can be overridden by reusing the widget
name.
-	 *
-	 * @param value The widget class to add.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder widget(Class<? extends Widget> value) {
-		this.widgets.add(value);
-		return this;
-	}
-	
-	/**
 	 * Returns an instance of an HTMLDOC builder for setting HTMLDOC-related properties.
 	 * 
 	 * @return An instance of an HTMLDOC builder for setting HTMLDOC-related properties.
@@ -2299,6 +2292,104 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	}
 
 	/**
+	 * <b>Configuration property:</b>  HTML Widgets. 
+	 *
+	 * <p>
+	 * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to
quickly
+	 * generate arbitrary replacement text.
+	 * 
+	 * Widgets resolve the following variables:
+	 * <ul>
+	 * 	<li><js>"$W{name}"</js> - Contents returned by {@link Widget#getHtml(RestRequest)}.
+	 * 	<li><js>"$W{name.script}"</js> - Contents returned by {@link Widget#getScript(RestRequest)}.
+	 * 		<br>The script contents are automatically inserted into the <xt>&lt;head/script&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * 	<li><js>"$W{name.style}"</js> - Contents returned by {@link Widget#getStyle(RestRequest)}.
+	 * 		<br>The styles contents are automatically inserted into the <xt>&lt;head/style&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * </ul>
+	 *
+	 * <p>
+	 * The following examples shows how to associate a widget with a REST method and then have
it rendered in the links
+	 * and aside section of the page:
+	 *
+	 * <p class='bcode'>
+	 * 	<ja>@RestMethod</ja>(
+	 * 		widgets={
+	 * 			MyWidget.<jk>class</jk>
+	 * 		}
+	 * 		htmldoc=<ja>@HtmlDoc</ja>(
+	 * 			navlinks={
+	 * 				<js>"$W{MyWidget}"</js>
+	 * 			},
+	 * 			aside={
+	 * 				<js>"Check out this widget:  $W{MyWidget}"</js>
+	 * 			}
+	 * 		)
+	 * 	)
+	 * </p>
+	 * 
+	 * <h6 class='topic'>Notes:</h6>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_widgets}
+	 * 	<li>Annotations: 
+	 * 		<ul>
+	 * 			<li>{@link HtmlDoc#widgets()} 
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#widgets(Class...)}
+	 * 			<li>{@link RestContextBuilder#widgets(Widget...)}
+	 * 			<li>{@link RestContextBuilder#widgets(boolean,Widget...)}
+	 * 		</ul>
+	 * 	<li>Widgets are inherited from parent to child, but can be overridden by reusing
the widget name.
+	 * 	<li>Values are appended to the existing list.
+	 * </ul>
+	 *
+	 * @param values The widget classes to add.
+	 * @return This object (for method chaining).
+	 */
+	@SuppressWarnings("unchecked")
+	public RestContextBuilder widgets(Class<? extends Widget>...values) {
+		return addTo(REST_widgets, values);
+	}
+	
+	/**
+	 * <b>Configuration property:</b>  HTML Widgets. 
+	 * 
+	 * <p>
+	 * Same as {@link #widgets(Class...)} but allows you to pass in pre-instantiated Widget
objects.
+	 * 
+	 * <p>
+	 * Values are appended to the existing list.
+	 *
+	 * @param values The widget objects to add.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder widgets(Widget...values) {
+		return addTo(REST_widgets, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  HTML Widgets. 
+	 * 
+	 * <p>
+	 * Same as {@link #widgets(Class...)} but allows you to pass in pre-instantiated Widget
objects.
+	 * 
+	 * <p>
+	 * Values are appended to the existing list.
+	 * 
+	 * @param append 
+	 * 	If <jk>true</jk>, appends to the existing list of widgets.
+	 * 	<br>Otherwise, replaces the previous list.
+	 * @param values The widget objects to add.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder widgets(boolean append, Widget...values) {
+		return set(append, REST_widgets, values);
+	}
+
+	/**
 	 * <b>Configuration property:</b>  Serializer listener.
 	 * 
 	 * <p>

http://git-wip-us.apache.org/repos/asf/juneau/blob/223e6c6f/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
index 4d9e8cc..edeeb22 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
@@ -492,13 +492,58 @@ public @interface HtmlDoc {
 	Class<? extends HtmlDocTemplate> template() default HtmlDocTemplate.class;
 
 	/**
+	 * <b>Configuration property:</b>  HTML Widgets. 
+	 *
+	 * <p>
 	 * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to
quickly
-	 * generate arbitrary replacement HTML.
+	 * generate arbitrary replacement text.
+	 * 
+	 * Widgets resolve the following variables:
+	 * <ul>
+	 * 	<li><js>"$W{name}"</js> - Contents returned by {@link Widget#getHtml(RestRequest)}.
+	 * 	<li><js>"$W{name.script}"</js> - Contents returned by {@link Widget#getScript(RestRequest)}.
+	 * 		<br>The script contents are automatically inserted into the <xt>&lt;head/script&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * 	<li><js>"$W{name.style}"</js> - Contents returned by {@link Widget#getStyle(RestRequest)}.
+	 * 		<br>The styles contents are automatically inserted into the <xt>&lt;head/style&gt;</xt>
section
+	 * 			 in the HTML page.
+	 * </ul>
 	 *
-	 * <h6 class='topic'>Other Notes</h6>
+	 * <p>
+	 * The following examples shows how to associate a widget with a REST method and then have
it rendered in the links
+	 * and aside section of the page:
+	 *
+	 * <p class='bcode'>
+	 * 	<ja>@RestMethod</ja>(
+	 * 		widgets={
+	 * 			MyWidget.<jk>class</jk>
+	 * 		}
+	 * 		htmldoc=<ja>@HtmlDoc</ja>(
+	 * 			navlinks={
+	 * 				<js>"$W{MyWidget}"</js>
+	 * 			},
+	 * 			aside={
+	 * 				<js>"Check out this widget:  $W{MyWidget}"</js>
+	 * 			}
+	 * 		)
+	 * 	)
+	 * </p>
+	 * 
+	 * <h6 class='topic'>Notes:</h6>
 	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Widgets are inherited from parent to child, but can be overridden by reusing the widget
name.
+	 * 	<li>Property:  {@link RestContext#REST_widgets}
+	 * 	<li>Annotations: 
+	 * 		<ul>
+	 * 			<li>{@link HtmlDoc#widgets()} 
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#widgets(Class...)}
+	 * 			<li>{@link RestContextBuilder#widgets(Widget...)}
+	 * 			<li>{@link RestContextBuilder#widgets(boolean,Widget...)}
+	 * 		</ul>
+	 * 	<li>Widgets are inherited from parent to child, but can be overridden by reusing
the widget name.
+	 * 	<li>Values are appended to the existing list.
 	 * </ul>
 	 */
 	Class<? extends Widget>[] widgets() default {};

http://git-wip-us.apache.org/repos/asf/juneau/blob/223e6c6f/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
index 1b135b0..16bb005 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
@@ -26,7 +26,8 @@ import org.apache.juneau.utils.*;
  * Widgets are associated with resources through the following
  * <ul>
  * 	<li>{@link HtmlDoc#widgets() @HtmlDoc.widgets}
- * 	<li>{@link RestContextBuilder#widget(Class)}
+ * 	<li>{@link RestContextBuilder#widgets(Class...)}
+ * 	<li>{@link RestContextBuilder#widgets(Widget...)}
  * </ul>
  *
  * <p>
@@ -89,7 +90,7 @@ import org.apache.juneau.utils.*;
  * </p>
  *
  * <p>
- * Note the {@link #getResourceAsString(String)} and {@link #getResourceAsString(String,
Locale)} convenience methods
+ * Note the {@link #getClasspathResourceAsString(String)} and {@link #getClasspathResourceAsString(String,
Locale)} convenience methods
  * provided for quickly loading javascript and css files from the classpath or file system.
  * These are useful if your script or styles are complex and you want them loaded from files.
  *
@@ -110,6 +111,16 @@ import org.apache.juneau.utils.*;
  * 		}
  * 	}
  * </p>
+ * 
+ * <p>
+ * Widgets must provide one of the following public constructors:
+ * <ul>
+ * 	<li><code><jk>public</jk> Widget();</code>
+ * 	<li><code><jk>public</jk> Widget(PropertyStore);</code>
+ * </ul>
+ * 
+ * <p>
+ * Widgets can be defined as inner classes of REST resource classes.
  */
 public abstract class Widget {
 
@@ -190,12 +201,12 @@ public abstract class Widget {
 	 * @return The resource converted to a string, or <jk>null</jk> if the resource
could not be found.
 	 * @throws IOException
 	 */
-	protected String getResourceAsString(String name) throws IOException {
+	protected String getClasspathResourceAsString(String name) throws IOException {
 		return rm.getString(name);
 	}
 
 	/**
-	 * Same as {@link #getResourceAsString(String)} except also looks for localized-versions
of the file.
+	 * Same as {@link #getClasspathResourceAsString(String)} except also looks for localized-versions
of the file.
 	 *
 	 * <p>
 	 * If the <code>locale</code> is specified, then we look for resources whose
name matches that locale.
@@ -213,12 +224,12 @@ public abstract class Widget {
 	 * @return The resource converted to a string, or <jk>null</jk> if the resource
could not be found.
 	 * @throws IOException
 	 */
-	protected String getResourceAsString(String name, Locale locale) throws IOException {
+	protected String getClasspathResourceAsString(String name, Locale locale) throws IOException
{
 		return rm.getString(name, locale);
 	}
 
 	/**
-	 * Convenience method for calling {@link #getResourceAsString(String)} except also strips
Javascript comments from
+	 * Convenience method for calling {@link #getClasspathResourceAsString(String)} except also
strips Javascript comments from
 	 * the file.
 	 *
 	 * <p>
@@ -229,14 +240,14 @@ public abstract class Widget {
 	 * @throws IOException
 	 */
 	protected String loadScript(String name) throws IOException {
-		String s = getResourceAsString(name);
+		String s = getClasspathResourceAsString(name);
 		if (s != null)
 			s = s.replaceAll("(?s)\\/\\*(.*?)\\*\\/\\s*", "");
 		return s;
 	}
 
 	/**
-	 * Convenience method for calling {@link #getResourceAsString(String)} except also strips
CSS comments from
+	 * Convenience method for calling {@link #getClasspathResourceAsString(String)} except also
strips CSS comments from
 	 * the file.
 	 *
 	 * <p>
@@ -247,14 +258,14 @@ public abstract class Widget {
 	 * @throws IOException
 	 */
 	protected String loadStyle(String name) throws IOException {
-		String s = getResourceAsString(name);
+		String s = getClasspathResourceAsString(name);
 		if (s != null)
 			s = s.replaceAll("(?s)\\/\\*(.*?)\\*\\/\\s*", "");
 		return s;
 	}
 
 	/**
-	 * Convenience method for calling {@link #getResourceAsString(String)} except also strips
HTML comments from the
+	 * Convenience method for calling {@link #getClasspathResourceAsString(String)} except also
strips HTML comments from the
 	 * file.
 	 *
 	 * <p>
@@ -265,7 +276,7 @@ public abstract class Widget {
 	 * @throws IOException
 	 */
 	protected String loadHtml(String name) throws IOException {
-		String s = getResourceAsString(name);
+		String s = getClasspathResourceAsString(name);
 		if (s != null)
 			s = s.replaceAll("(?s)<!--(.*?)-->\\s*", "");
 		return s;


Mime
View raw message