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/09/08 23:25:37 UTC
svn commit: r21540 [22/27] - in /release/incubator/juneau:
juneau-rest-client/ juneau-rest-client/.settings/ juneau-rest-client/bin/
juneau-rest-client/src/ juneau-rest-client/src/main/
juneau-rest-client/src/main/java/ juneau-rest-client/src/main/java...
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,65 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.widget.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * HTML widget variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$W{widgetName}"</js>.
+ *
+ * <p>
+ * Widgets are simple class that produce some sort of string based on a passed-in HTTP request.
+ *
+ * <p>
+ * They're registered via the following mechanisms:
+ * <ul>
+ * <li>{@link HtmlDoc#widgets() @HtmlDoc.widgets()}
+ * <li>{@link RestConfig#addHtmlWidget(Class)}
+ * </ul>
+ *
+ * @see org.apache.juneau.svl
+ */
+public class WidgetVar extends SimpleVar {
+
+ /**
+ * The name of the session or context object that identifies the {@link RestRequest} object.
+ */
+ private static final String SESSION_req = "req";
+
+ /**
+ * The name of this variable.
+ */
+ public static final String NAME = "W";
+
+ /**
+ * Constructor.
+ */
+ public WidgetVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) throws Exception {
+ RestRequest req = session.getSessionObject(RestRequest.class, SESSION_req);
+ Widget w = req.getWidgets().get(key);
+ if (w == null)
+ return "unknown-widget-"+key;
+ return w.getHtml(req);
+ }
+}
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/package.html
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/package.html (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/package.html Fri Sep 8 23:25:34 2017
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ /* For viewing in Page Designer */
+ @IMPORT url("../../../../javadoc.css");
+
+ /* For viewing in REST interface */
+ @IMPORT url("../htdocs/javadoc.css");
+ body {
+ margin: 20px;
+ }
+ </style>
+ <script>
+ /* Replace all @code and @link tags. */
+ window.onload = function() {
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+ }
+ </script>
+</head>
+<body>
+<p>Predefined SVL variables</p>
+</body>
+</html>
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/package.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,77 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+
+import java.net.*;
+import java.util.*;
+
+import org.apache.juneau.dto.html5.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Widget that returns back a list of hyperlinks for rendering the contents of a page in a variety of content types.
+ *
+ * <p>
+ * The variable it resolves is <js>"$W{ContentTypeMenuItem}"</js>.
+ *
+ * <p>
+ * An example of this widget can be found in the <code>PetStoreResource</code> in the examples that provides
+ * a drop-down menu item for rendering all other supported content types in plain text:
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * name=<js>"GET"</js>,
+ * path=<js>"/"</js>,
+ * widgets={
+ * ContentTypeMenuItem.<jk>class</jk>,
+ * },
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * links={
+ * <js>"up: ..."</js>,
+ * <js>"options: ..."</js>,
+ * <js>"$W{QueryMenuItem}"</js>,
+ * <js>"$W{ContentTypeMenuItem}"</js>,
+ * <js>"$W{StyleMenuItem}"</js>,
+ * <js>"source: ..."</js>
+ * }
+ * )
+ * )
+ * <jk>public</jk> Collection<Pet> getPets() {
+ * </p>
+ *
+ * <p>
+ * It renders the following popup-box:
+ * <br><img class='bordered' src='doc-files/ContentTypeMenuItem.png'>
+ */
+public class ContentTypeMenuItem extends MenuItemWidget {
+
+ @Override /* MenuItemWidget */
+ public String getLabel(RestRequest req) {
+ return "content-type";
+ }
+
+ @Override /* MenuItemWidget */
+ public Div getContent(RestRequest req) {
+ Div div = div();
+ List<MediaType> l = new ArrayList<MediaType>(req.getSerializerGroup().getSupportedMediaTypes());
+ Collections.sort(l);
+ for (MediaType mt : l) {
+ URI uri = req.getUri(true, new AMap<String,String>().append("plainText","true").append("Accept",mt.toString()));
+ div.children(a(uri, mt), br());
+ }
+ return div;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,131 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import java.io.*;
+
+import org.apache.juneau.html.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * A subclass of widgets for rendering menu items with drop-down windows.
+ *
+ * <p>
+ * Defines some simple CSS and Javascript for enabling drop-down menus in the nav section of the page (although
+ * nothing keeps you from using it in an arbitrary location in the page).
+ *
+ * <p>
+ * The script specifies a <js>"menuClick(element)"</js> function that toggles the visibility of the next sibling of the
+ * element.
+ *
+ * <p>
+ * Subclasses should implement the following two methods:
+ * <ul>
+ * <li>{@link #getLabel(RestRequest)} - The menu item label.
+ * <li>{@link #getContent(RestRequest)} - The menu item content.
+ *
+ * <p>
+ * For example, to render a link that brings up a simple dialog in a div tag:
+ * <p class='bcode'>
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getLabel() {
+ * <jk>return</jk> <js>"my-menu-item"</js>;
+ * };
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> Div getLabel() {
+ * <jk>return</jk> Html5Builder.<jsm>div</jsm>(<js>"Surprise!"</js>).style(<js>"color:red"</js>);
+ * };
+ * </p>
+ *
+ * <p>
+ * The HTML content returned by the {@link #getHtml(RestRequest)} method is added where the <js>"$W{...}"</js> is
+ * referenced in the page.
+ */
+public abstract class MenuItemWidget extends Widget {
+
+ /**
+ * Returns the Javascript needed for the show and hide actions of the menu item.
+ */
+ @Override /* Widget */
+ public String getScript(RestRequest req) throws Exception {
+ return loadScript("MenuItemWidget.js");
+ }
+
+ /**
+ * Defines a <js>"menu-item"</js> class that needs to be used on the outer element of the HTML returned by the
+ * {@link #getHtml(RestRequest)} method.
+ */
+ @Override /* Widget */
+ public String getStyle(RestRequest req) throws Exception {
+ return loadStyle("MenuItemWidget.css");
+ }
+
+ @Override /* Widget */
+ public String getHtml(RestRequest req) throws Exception {
+ StringBuilder sb = new StringBuilder();
+ sb.append(""
+ + "<div class='menu-item'>"
+ + "\n\t<a class='link' onclick='menuClick(this)'>"+getLabel(req)+"</a>"
+ + "\n\t<div class='popup-content'>\n"
+ );
+ Object o = getContent(req);
+ if (o instanceof Reader)
+ IOUtils.pipe((Reader)o, new StringBuilderWriter(sb));
+ else if (o instanceof CharSequence)
+ sb.append((CharSequence)o);
+ else {
+ SerializerSessionArgs args = new SerializerSessionArgs(req.getProperties(), null, req.getLocale(), null, null, req.getUriContext());
+ WriterSerializerSession session = HtmlSerializer.DEFAULT.createSession(args);
+ try {
+ session.indent = 2;
+ session.serialize(sb, o);
+ } finally {
+ session.close();
+ }
+ }
+ sb.append(""
+ + "\n\t</div>"
+ + "\n</div>"
+ );
+ return sb.toString();
+ }
+
+ /**
+ * The label for the menu item as it's rendered in the menu bar.
+ *
+ * @param req The HTTP request object.
+ * @return The menu item label.
+ * @throws Exception
+ */
+ public abstract String getLabel(RestRequest req) throws Exception;
+
+ /**
+ * The content of the popup.
+ *
+ * @param req The HTTP request object.
+ * @return
+ * The content of the popup.
+ * <br>Can be any of the following types:
+ * <ul>
+ * <li>{@link Reader} - Serialized directly to the output.
+ * <li>{@link CharSequence} - Serialized directly to the output.
+ * <li>Other - Serialized as HTML using {@link HtmlSerializer#DEFAULT}.
+ * <br>Note that this includes any of the {@link org.apache.juneau.dto.html5} beans.
+ * </ul>
+ * @throws Exception
+ */
+ public abstract Object getContent(RestRequest req) throws Exception;
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByApache.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByApache.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByApache.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,57 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
+
+/**
+ * Widget that places a powered-by-Apache message on the page.
+ *
+ * <p>
+ * The variable it resolves is <js>"$W{PoweredByApache}"</js>.
+ *
+ * <p>
+ * It produces a simple Apache icon floating on the right.
+ * Typically it's used in the footer of the page, as shown below in the <code>RootResources</code> from the examples:
+ *
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * path=<js>"/"</js>,
+ * title=<js>"Root resources"</js>,
+ * description=<js>"Example of a router resource page."</js>,
+ * widgets={
+ * PoweredByApache.<jk>class</jk>
+ * },
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * footer=<js>"$W{PoweredByApache}"</js>
+ * )
+ * </p>
+ *
+ * <p>
+ * It renders the following image:
+ * <img class='bordered' src='doc-files/PoweredByApacheWidget.png'>
+ */
+public class PoweredByApache extends Widget {
+
+ /**
+ * Returns an Apache image tag hyperlinked to <js>"http://apache.org"</js>
+ */
+ @Override /* Widget */
+ public String getHtml(RestRequest req) throws Exception {
+ UriResolver r = req.getUriResolver();
+ return "<a href='http://apache.org'><img style='float:right;padding-right:20px;height:32px' src='"+r.resolve("servlet:/htdocs/asf.png")+"'>";
+ }
+}
+
+
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByApache.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneau.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneau.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneau.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,56 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
+
+/**
+ * Widget that places a powered-by-Juneau message on the page.
+ *
+ * <p>
+ * The variable it resolves is <js>"$W{PoweredByJuneau}"</js>.
+ *
+ * <p>
+ * It produces a simple Apache Juneau icon floating on the right.
+ * Typically it's used in the footer of the page, as shown below in the <code>AddressBookResource</code> from the examples:
+ *
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * path=<js>"/addressBook"</js>,
+ * widgets={
+ * PoweredByJuneau.<jk>class</jk>
+ * },
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * footer=<js>"$W{PoweredByJuneau}"</js>
+ * )
+ * </p>
+ *
+ * <p>
+ * It renders the following image:
+ * <img class='bordered' src='doc-files/PoweredByJuneauWidget.png'>
+ */
+public class PoweredByJuneau extends Widget {
+
+
+ /**
+ * Returns an Apache Juneau image tag hyperlinked to <js>"http://juneau.apache.org"</js>
+ */
+ @Override /* Widget */
+ public String getHtml(RestRequest req) throws Exception {
+ UriResolver r = req.getUriResolver();
+ return "<a href='http://juneau.apache.org'><img style='float:right;padding-right:20px;height:32px' src='"+r.resolve("servlet:/htdocs/juneau.png")+"'>";
+ }
+}
+
+
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneau.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,88 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.converters.*;
+
+/**
+ * Widget that returns a menu-item drop-down form for entering search/view/sort arguments.
+ *
+ * <p>
+ * The variable it resolves is <js>"$W{QueryMenuItem}"</js>.
+ *
+ * <p>
+ * This widget is designed to be used in conjunction with the {@link Queryable} converter, although implementations
+ * can process the query parameters themselves if they wish to do so by using the {@link RequestQuery#getSearchArgs()}
+ * method to retrieve the arguments and process the data themselves.
+ *
+ * <p>
+ * An example of this widget can be found in the <code>PetStoreResource</code> in the examples that provides
+ * search/view/sort capabilities against the collection of POJOs:
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * name=<js>"GET"</js>,
+ * path=<js>"/"</js>,
+ * widgets={
+ * QueryMenuItem.<jk>class</jk>,
+ * },
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * links={
+ * <js>"up: ..."</js>,
+ * <js>"options: ..."</js>,
+ * <js>"$W{QueryMenuItem}"</js>,
+ * <js>"$W{ContentTypeMenuItem}"</js>,
+ * <js>"$W{StyleMenuItem}"</js>,
+ * <js>"source: ..."</js>
+ * }
+ * ),
+ * converters=Queryable.<jk>class</jk>
+ * )
+ * <jk>public</jk> Collection<Pet> getPets() {
+ * </p>
+ *
+ * <p>
+ * It renders the following popup-box:
+ * <br><img class='bordered' src='doc-files/QueryMenuItem_1.png'>
+ *
+ * <p>
+ * Tooltips are provided by hovering over the field names.
+ * <br><img class='bordered' src='doc-files/QueryMenuItem_2.png'>
+ *
+ * <p>
+ * When submitted, the form submits a GET request against the current URI with special GET search API query parameters.
+ * <br>(e.g. <js>"?s=column1=Foo*&v=column1,column2&o=column1,column2-&p=100&l=100"</js>).
+ * <br>The {@link Queryable} class knows how to perform these filters against collections of POJOs.
+ */
+public class QueryMenuItem extends MenuItemWidget {
+
+ /**
+ * Returns CSS for the tooltips.
+ */
+ @Override
+ public String getStyle(RestRequest req) throws Exception {
+ return super.getStyle(req)
+ + "\n"
+ + loadStyle("QueryMenuItem.css");
+ }
+
+ @Override /* MenuItemWidget */
+ public String getLabel(RestRequest req) throws Exception {
+ return "query";
+ }
+
+ @Override /* MenuItemWidget */
+ public String getContent(RestRequest req) throws Exception {
+ return loadHtml("QueryMenuItem.html");
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/StyleMenuItem.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/StyleMenuItem.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/StyleMenuItem.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+
+import org.apache.juneau.dto.html5.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Widget that returns back a list of hyperlinks for rendering the contents of a page in the various default styles.
+ *
+ * <p>
+ * The variable it resolves is <js>"$W{StyleMenuItem}"</js>.
+ *
+ * <p>
+ * An example of this widget can be found in the <code>PetStoreResource</code> in the examples that provides
+ * a drop-down menu item for rendering all other supported content types in plain text:
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * name=<js>"GET"</js>,
+ * path=<js>"/"</js>,
+ * widgets={
+ * StyleMenuItem.<jk>class</jk>,
+ * },
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * links={
+ * <js>"up: ..."</js>,
+ * <js>"options: ..."</js>,
+ * <js>"$W{QueryMenuItem}"</js>,
+ * <js>"$W{ContentTypeMenuItem}"</js>,
+ * <js>"$W{StyleMenuItem}"</js>,
+ * <js>"source: ..."</js>
+ * }
+ * )
+ * )
+ * <jk>public</jk> Collection<Pet> getPets() {
+ * </p>
+ */
+public class StyleMenuItem extends MenuItemWidget {
+
+ private static final String[] BUILT_IN_STYLES = {"devops", "light", "original", "dark"};
+
+ @Override /* MenuItemWidget */
+ public String getLabel(RestRequest req) {
+ return "styles";
+ }
+ /**
+ * Looks at the supported media types from the request and constructs a list of hyperlinks to render the data
+ * as plain-text.
+ */
+ @Override /* Widget */
+ public Div getContent(RestRequest req) throws Exception {
+ Div div = div();
+ for (String s : BUILT_IN_STYLES) {
+ java.net.URI uri = req.getUri(true, new AMap<String,String>().append("stylesheet", "styles/"+s+".css"));
+ div.children(a(uri, s), br());
+ }
+ return div;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/StyleMenuItem.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Tooltip.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Tooltip.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Tooltip.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,97 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.dto.html5.*;
+
+/**
+ * Simple template for adding tooltips to HTML5 bean constructs, typically in menu item widgets.
+ *
+ * <p>
+ * Tooltips depend on the existence of the <code>tooltip</code> and <code>tooltiptext</code> styles that should be
+ * present in the stylesheet for the document.
+ *
+ * <p>
+ * The following examples shows how tooltips can be added to a menu item widget.
+ *
+ * <p class='bcode'>
+ * <jk>public class</jk> MyFormMenuItem <jk>extends</jk> MenuItemWidget {
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getLabel(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> <js>"myform"</js>;
+ * }
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> Object getContent(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> div(
+ * <jsm>form</jsm>().id(<js>"form"</js>).action(<js>"servlet:/form"</js>).method(<js>"POST"</js>).children(
+ * <jsm>table</jsm>(
+ * <jsm>tr</jsm>(
+ * <jsm>th</jsm>(<js>"Field 1:"</js>),
+ * <jsm>td</jsm>(<jsm>input</jsm>().name(<js>"field1"</js>).type(<js>"text"</js>)),
+ * <jsm>td</jsm>(<jk>new</jk> Tooltip(<js>"(?)"</js>, <js>"This is field #1!"</js>, br(), <js>"(e.g. '"</js>, code(<js>"Foo"</js>), <js>"')"</js>))
+ * ),
+ * <jsm>tr</jsm>(
+ * <jsm>th</jsm>(<js>"Field 2:"</js>),
+ * <jsm>td</jsm>(<jsm>input</jsm>().name(<js>"field2"</js>).type(<js>"text"</js>)),
+ * <jsm>td</jsm>(<jk>new</jk> Tooltip(<js>"(?)"</js>, <js>"This is field #2!"</js>, br(), <js>"(e.g. '"</js>, code(<js>"Bar"</js>), <js>"')"</js>))
+ * )
+ * )
+ * )
+ * );
+ * }
+ * }
+ * </p>
+ */
+public class Tooltip {
+
+ private final String display;
+ private final List<Object> content;
+
+ /**
+ * Constructor.
+ *
+ * @param display
+ * The normal display text.
+ * This is what gets rendered normally.
+ * @param content
+ * The hover contents.
+ * Typically a list of strings, but can also include any HTML5 beans as well.
+ */
+ public Tooltip(String display, Object...content) {
+ this.display = display;
+ this.content = new ArrayList<Object>(Arrays.asList(content));
+ }
+
+ /**
+ * The swap method.
+ *
+ * <p>
+ * Converts this bean into a div tag with contents.
+ *
+ * @param session The bean session.
+ * @return The swapped contents of this bean.
+ */
+ public Div swap(BeanSession session) {
+ return div(
+ small(display),
+ span()._class("tooltiptext").children(content)
+ )._class("tooltip");
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Tooltip.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,273 @@
+// ***************************************************************************************************************************
+// * 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.widget;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Defines an interface for resolvers of <js>"$W{...}"</js> string variables.
+ *
+ * <p>
+ * Widgets are associated with resources through the following
+ * <ul>
+ * <li>{@link HtmlDoc#widgets() @HtmlDoc.widgets}
+ * <li>{@link RestConfig#addHtmlWidget(Class)}
+ * </ul>
+ *
+ * <p>
+ * Widgets allow you to add arbitrary HTML, CSS, and Javascript to the page.
+ *
+ * <p>
+ * The HTML content returned by the {@link #getHtml(RestRequest)} method is added where the <js>"$W{...}"</js> is
+ * referenced in the page.
+ * The Javascript and stylesheet content is added to the header of the page.
+ * They allow you to control the look and behavior of your widgets.
+ *
+ * <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>(
+ * links={
+ * <js>"$W{MyWidget}"</js>
+ * },
+ * aside={
+ * <js>"Check out this widget: $W{MyWidget}"</js>
+ * }
+ * )
+ * )
+ * </p>
+ *
+ * <p>
+ * The following shows an example of a widget that renders an image located in the <code>htdocs</code> static files
+ * directory in your classpath (see {@link RestResource#staticFiles()}):
+ * <p class='bcode'>
+ * <jk>public class</jk> MyWidget <jk>extends</jk> Widget {
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getHtml(RestRequest req) <jk>throws</jk> Exception {
+ * UriResolver r = req.getUriResolver();
+ * <jk>return</jk> <js>"<img class='myimage' onclick='myalert(this)' src='"</js>+r.resolve(<js>"servlet:/htdocs/myimage.png"</js>)+<js>"'>"</js>;
+ * }
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getScript(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> <js>""</js>
+ * + <js>"\n function myalert(imageElement) {"</js>
+ * + <js>"\n alert('cool!');"</js>
+ * + <js>"\n }"</js>;
+ * }
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getStyle(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> <js>""</js>
+ * + <js>"\n .myimage {"</js>
+ * + <js>"\n border: 10px solid red;"</js>
+ * + <js>"\n }"</js>;
+ * }
+ * }
+ * </p>
+ *
+ * <p>
+ * Note the {@link #getResourceAsString(String)} and {@link #getResourceAsString(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.
+ *
+ * <p>
+ * <p class='bcode'>
+ * <jk>public class</jk> MyWidget <jk>extends</jk> Widget {
+ *
+ * ...
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getScript(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> getResourceAsString(<js>"MyWidget.js"</js>);
+ * }
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> String getStyle(RestRequest req) <jk>throws</jk> Exception {
+ * <jk>return</jk> getResourceAsString(<js>"MyWidget.css"</js>);
+ * }
+ * }
+ * </p>
+ */
+public abstract class Widget {
+
+ private final ResourceFinder resourceFinder = new ResourceFinder(getClass());
+
+ /**
+ * The widget key.
+ *
+ * <p>
+ * (i.e. The variable name inside the <js>"$W{...}"</js> variable).
+ *
+ * <p>
+ * The returned value must not be <jk>null</jk>.
+ *
+ * <p>
+ * If not overridden, the default value is the class simple name.
+ *
+ * @return The widget key.
+ */
+ public String getName() {
+ return getClass().getSimpleName();
+ }
+
+ /**
+ * Resolves the HTML content for this widget.
+ *
+ * <p>
+ * A returned value of <jk>null</jk> will cause nothing to be added to the page.
+ *
+ * @param req The HTTP request object.
+ * @return The HTML content of this widget.
+ * @throws Exception
+ */
+ public String getHtml(RestRequest req) throws Exception {
+ return null;
+ }
+
+ /**
+ * Resolves any Javascript that should be added to the <xt><head>/<script></xt> element.
+ *
+ * <p>
+ * A returned value of <jk>null</jk> will cause nothing to be added to the page.
+ *
+ * @param req The HTTP request object.
+ * @return The Javascript needed by this widget.
+ * @throws Exception
+ */
+ public String getScript(RestRequest req) throws Exception {
+ return null;
+ }
+
+ /**
+ * Resolves any CSS styles that should be added to the <xt><head>/<style></xt> element.
+ *
+ * <p>
+ * A returned value of <jk>null</jk> will cause nothing to be added to the page.
+ *
+ * @param req The HTTP request object.
+ * @return The CSS styles needed by this widget.
+ * @throws Exception
+ */
+ public String getStyle(RestRequest req) throws Exception {
+ return null;
+ }
+
+ /**
+ * Retrieves the specified classpath resource and returns the contents as a string.
+ *
+ * <p>
+ * Same as {@link Class#getResourceAsStream(String)} except if it doesn't find the resource on this class, searches
+ * up the parent hierarchy chain.
+ *
+ * <p>
+ * If the resource cannot be found in the classpath, then an attempt is made to look relative to the JVM working directory.
+ * <br>Path traversals outside the working directory are not allowed for security reasons.
+ *
+ * @param name Name of the desired resource.
+ * @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 {
+ return resourceFinder.getResourceAsString(name);
+ }
+
+ /**
+ * Same as {@link #getResourceAsString(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.
+ * <br>For example, if looking for the resource <js>"MyResource.txt"</js> for the Japanese locale, we will look for
+ * files in the following order:
+ * <ol>
+ * <li><js>"MyResource_ja_JP.txt"</js>
+ * <li><js>"MyResource_ja.txt"</js>
+ * <li><js>"MyResource.txt"</js>
+ * </ol>
+ *
+ *
+ * @param name Name of the desired resource.
+ * @param locale The locale. Can be <jk>null</jk>.
+ * @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 {
+ return resourceFinder.getResourceAsString(name, locale);
+ }
+
+ /**
+ * Convenience method for calling {@link #getResourceAsString(String)} except also strips Javascript comments from
+ * the file.
+ *
+ * <p>
+ * Comments are assumed to be Java-style block comments: <js>"/*"</js>.
+ *
+ * @param name Name of the desired resource.
+ * @return The resource converted to a string, or <jk>null</jk> if the resource could not be found.
+ * @throws IOException
+ */
+ protected String loadScript(String name) throws IOException {
+ String s = getResourceAsString(name);
+ if (s != null)
+ s = s.replaceAll("(?s)\\/\\*(.*?)\\*\\/\\s*", "");
+ return s;
+ }
+
+ /**
+ * Convenience method for calling {@link #getResourceAsString(String)} except also strips CSS comments from
+ * the file.
+ *
+ * <p>
+ * Comments are assumed to be Java-style block comments: <js>"/*"</js>.
+ *
+ * @param name Name of the desired resource.
+ * @return The resource converted to a string, or <jk>null</jk> if the resource could not be found.
+ * @throws IOException
+ */
+ protected String loadStyle(String name) throws IOException {
+ String s = getResourceAsString(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
+ * file.
+ *
+ * <p>
+ * Comment are assumed to be <js>"<!-- -->"</js> code blocks.
+ *
+ * @param name Name of the desired resource.
+ * @return The resource converted to a string, or <jk>null</jk> if the resource could not be found.
+ * @throws IOException
+ */
+ protected String loadHtml(String name) throws IOException {
+ String s = getResourceAsString(name);
+ if (s != null)
+ s = s.replaceAll("(?s)<!--(.*?)-->\\s*", "");
+ return s;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/ContentTypeMenuItem.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/ContentTypeMenuItem.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/PoweredByApacheWidget.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/PoweredByApacheWidget.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/PoweredByJuneauWidget.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/PoweredByJuneauWidget.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/QueryMenuItem_1.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/QueryMenuItem_1.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/QueryMenuItem_2.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/doc-files/QueryMenuItem_2.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/resources/org/apache/juneau/rest/htdocs/MethodExampleResource1.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/resources/org/apache/juneau/rest/htdocs/MethodExampleResource1.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/resources/org/apache/juneau/rest/htdocs/asf.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/resources/org/apache/juneau/rest/htdocs/asf.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream