http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 3b97926..d8f3864 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 @@ -24,6 +24,7 @@ import org.apache.juneau.microservice.*; import org.apache.juneau.rest.*; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.rest.annotation.Body; +import org.apache.juneau.rest.widget.*; @RestResource( path="/systemProperties", @@ -33,17 +34,22 @@ import org.apache.juneau.rest.annotation.Body; title="System properties resource", description="REST interface for performing CRUD operations on system properties.", + // Widget used for content-type pull-down menu. + widgets={ + ContentTypeMenuItem.class + }, + // Links on the HTML rendition page. // "request:/..." URIs are relative to the request URI. // "servlet:/..." URIs are relative to the servlet URI. // "$C{...}" variables are pulled from the config file. htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS',form:'servlet:/formPage',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java'}", + links="{up:'request:/..',options:'servlet:/?method=OPTIONS',form:'servlet:/formPage',contentTypes:'$W{contentTypeMenuItem}',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java'}", aside="" + "<div style='max-width:800px' class='text'>" + " <p>Shows standard GET/PUT/POST/DELETE operations and use of Swagger annotations.</p>" + "</div>", - css="aside {display:table-caption;}" + style="aside {display:table-caption;}" ), // Properties that get applied to all serializers and parsers. @@ -52,9 +58,6 @@ import org.apache.juneau.rest.annotation.Body; @Property(name=SERIALIZER_quoteChar, value="'") }, - // Our stylesheet for the HTML rendition. - stylesheet="styles/devops.css", - // Support GZIP encoding on Accept-Encoding header. encoders=GzipEncoder.class, @@ -65,7 +68,7 @@ import org.apache.juneau.rest.annotation.Body; termsOfService="You're on your own.", tags="[{name:'Java',description:'Java utility',externalDocs:{description:'Home page',url:'http://juneau.apache.org'}}]", externalDocs="{description:'Home page',url:'http://juneau.apache.org'}" - ) + ) ) public class SystemPropertiesResource extends Resource { private static final long serialVersionUID = 1L; @@ -191,7 +194,7 @@ public class SystemPropertiesResource extends Resource { + "<div style='max-width:400px' class='text'>" + " <p>Shows how HTML5 beans can be used to quickly create arbitrary HTML.</p>" + "</div>", - css="aside {display:table-cell;}" + style="aside {display:table-cell;}" ) ) public Form getFormPage() {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 9116112..6529474 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 @@ -21,6 +21,7 @@ import org.apache.commons.fileupload.servlet.*; import org.apache.juneau.dto.html5.*; import org.apache.juneau.rest.*; import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.widget.*; import org.apache.juneau.utils.*; /** @@ -30,8 +31,11 @@ import org.apache.juneau.utils.*; path="/tempDir", title="Temp Directory View Service", description="View and download files in the '$S{java.io.tmpdir}' directory.", + widgets={ + ContentTypeMenuItem.class + }, htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS',upload:'servlet:/upload',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TempDirResource.java'}", + links="{up:'request:/..',options:'servlet:/?method=OPTIONS',upload:'servlet:/upload',contentTypes:'$W{contentTypeMenuItem}',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/TempDirResource.java'}", aside="" + "<div style='max-width:400px' class='text'>" + " <p>Shows how to use the predefined DirectoryResource class.</p>" @@ -43,8 +47,7 @@ import org.apache.juneau.utils.*; @Property(name="allowViews", value="true"), @Property(name="allowDeletes", value="true"), @Property(name="allowPuts", value="false") - }, - stylesheet="styles/devops.css" + } ) public class TempDirResource extends DirectoryResource { private static final long serialVersionUID = 1L; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 0bade0e..bcbe585 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 @@ -43,12 +43,18 @@ import org.apache.juneau.utils.*; path="/addressBook", messages="nls/AddressBookResource", + // Widgets for $W variables above. + widgets={ + PoweredByJuneauWidget.class, + ContentTypeMenuItem.class + }, + // Links on the HTML rendition page. // "request:/..." URIs are relative to the request URI. // "servlet:/..." URIs are relative to the servlet URI. // "$C{...}" variables are pulled from the config file. htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java'}", + links="{up:'request:/..',options:'servlet:/?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java',contentTypes:'$W{contentTypeMenuItem}'}", aside="" + "<div style='max-width:400px;min-width:200px'>" + " <p>Proof-of-concept resource that shows off the capabilities of working with POJO resources.</p>" @@ -58,18 +64,10 @@ import org.apache.juneau.utils.*; + " <li>Swagger documentation" + " <li>Widgets" + " </ul>" - + " <p style='text-weight:bold;text-decoration:underline;'>Available Content Types</p>" - + " $W{contentTypeLinksColumn}" + "</div>", footer="$W{poweredByJuneau}" ), - // Widgets for $W variables above. - widgets={ - PoweredByJuneauWidget.class, - ContentTypeLinksColumnWidget.class - }, - // Properties that get applied to all serializers and parsers. properties={ @@ -92,9 +90,6 @@ import org.apache.juneau.utils.*; @Property(name=HTML_uriAnchorText, value="SERVLET_RELATIVE") }, - // Our stylesheet for the HTML rendition. - stylesheet="styles/devops.css", - // Support GZIP encoding on Accept-Encoding header. encoders=GzipEncoder.class, http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java index 24d3f8a..f743513 100644 --- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java +++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java @@ -89,19 +89,6 @@ public class RootResourcesTest extends RestTestcase { } //==================================================================================================== - // /htdoces/styles.css - //==================================================================================================== - @Test - public void testStyleSheet() throws Exception { - RestClient client = SamplesMicroservice.client().accept("text/css").build(); - RestCall r = client.doGet("/style.css"); - String css = r.getResponseAsString(); - if (debug) System.err.println(css); - assertTrue(css, css.indexOf("table {") != -1); - client.closeQuietly(); - } - - //==================================================================================================== // application/json+schema //==================================================================================================== @Test http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-examples/juneau-examples-core/.settings/org.eclipse.jdt.ui.prefs ---------------------------------------------------------------------- diff --git a/juneau-examples/juneau-examples-core/.settings/org.eclipse.jdt.ui.prefs b/juneau-examples/juneau-examples-core/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..bf038d1 --- /dev/null +++ b/juneau-examples/juneau-examples-core/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +formatter_profile=_juneau-code-rules +formatter_settings_version=12 http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-microservice-template/microservice.cfg ---------------------------------------------------------------------- diff --git a/juneau-microservice-template/microservice.cfg b/juneau-microservice-template/microservice.cfg index c3eb1d0..7459ee1 100755 --- a/juneau-microservice-template/microservice.cfg +++ b/juneau-microservice-template/microservice.cfg @@ -71,11 +71,10 @@ authRealm = # Stylesheet to use for HTML views. # The default options are: -# - styles/juneau.css -# - styles/devops.css -# Other stylesheets can be referenced relative to the servlet package or working -# directory. -stylesheet = styles/devops.css +# - servlet:/styles/juneau.css +# - servlet:/styles/devops.css +# Other stylesheets can be referenced relative to the servlet package or working directory. +stylesheet = servlet:/styles/devops.css # What to do when the config file is saved. # Possible values: http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 ef0eea1..ec634e1 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 @@ -43,10 +43,10 @@ import org.apache.juneau.svl.vars.*; @SuppressWarnings("serial") @RestResource( htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}" + links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}", + styleImport="$C{REST/stylesheet,servlet:/styles/devops.css}" ), - config="$S{juneau.configFile}", - stylesheet="$C{REST/stylesheet,styles/juneau.css}" + config="$S{juneau.configFile}" ) public abstract class Resource extends RestServletDefault { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 ce27cef..d476bf2 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 @@ -44,10 +44,10 @@ import org.apache.juneau.svl.vars.*; @SuppressWarnings("serial") @RestResource( htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}" + links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}", + styleImport="$C{REST/stylesheet,servlet:/styles/devops.css}" ), - config="$S{juneau.configFile}", - stylesheet="$C{REST/stylesheet,styles/juneau.css}" + config="$S{juneau.configFile}" ) public abstract class ResourceGroup extends RestServletGroupDefault { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 efe3cd5..458f858 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 @@ -21,9 +21,9 @@ import org.apache.juneau.rest.jena.*; @SuppressWarnings("serial") @RestResource( htmldoc=@HtmlDoc( - links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}" + links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}", + styleImport="$C{REST/stylesheet,servlet:/styles/devops.css}" ), - config="$S{juneau.configFile}", - stylesheet="$C{REST/stylesheet,styles/juneau.css}" + config="$S{juneau.configFile}" ) public abstract class ResourceJena extends RestServletJenaDefault {} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJenaGroup.java ---------------------------------------------------------------------- diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJenaGroup.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJenaGroup.java new file mode 100644 index 0000000..f9e1b96 --- /dev/null +++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceJenaGroup.java @@ -0,0 +1,63 @@ +// *************************************************************************************************************************** +// * 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.microservice; + +import org.apache.juneau.rest.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.jena.*; +import org.apache.juneau.svl.vars.*; + +/** + * Superclass for all REST resource groups. + * + * <p> + * In additional to the functionality of the {@link RestServletGroupDefault} group, + * augments the {@link RestContext#getVarResolver()} method with the following additional variable types: + * <ul class='spaced-list'> + * <li> + * <jk>$ARG{...}</jk> - Command line arguments. + * <br>Resolves values from {@link Microservice#getArgs()}. + * + * <h6>Example:</h6> + * <p class='bcode'> + * String firstArg = request.getVarResolver().resolve(<js>"$ARG{0}"</js>); <jc>// First argument.</jc> + * String namedArg = request.getVarResolver().resolve(<js>"$ARG{myarg}"</js>); <jc>// Named argument (e.g. "myarg=foo"). </jc> + * </p> + * <li> + * <jk>$MF{...}</jk> - Manifest file entries. + * + * <h6>Example:</h6> + * <p class='bcode'> + * String mainClass = request.getVarResolver().resolve(<js>"$MF{Main-Class}"</js>); <jc>// Main class. </jc> + * </p> + * </ul> + */ +@SuppressWarnings("serial") +@RestResource( + htmldoc=@HtmlDoc( + links="{up:'request:/..',options:'servlet:/?method=OPTIONS'}", + styleImport="$C{REST/stylesheet,servlet:/styles/devops.css}" + ), + config="$S{juneau.configFile}" +) +public abstract class ResourceJenaGroup extends RestServletJenaGroupDefault { + + @Override /* RestServlet */ + public synchronized void init(RestConfig config) throws Exception { + config + .addVars(ArgsVar.class, ManifestFileVar.class) + .addVarContextObject(ArgsVar.SESSION_args, Microservice.getArgs()) + .addVarContextObject(ManifestFileVar.SESSION_manifest, Microservice.getManifest()); + super.init(config); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-releng/eclipse-preferences/user-dictionary.txt ---------------------------------------------------------------------- diff --git a/juneau-releng/eclipse-preferences/user-dictionary.txt b/juneau-releng/eclipse-preferences/user-dictionary.txt index e287b97..44e7542 100644 --- a/juneau-releng/eclipse-preferences/user-dictionary.txt +++ b/juneau-releng/eclipse-preferences/user-dictionary.txt @@ -474,3 +474,9 @@ yyyy zip zipped zzz +mylink +myimage +myalert +onclick +popup +hyperlinked http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 8022e1d..04d60a2 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 @@ -69,7 +69,7 @@ class CallMethod implements Comparable<CallMethod> { private final RestContext context; private final BeanContext beanContext; private final String htmlTitle, htmlDescription, htmlBranding, htmlHeader, htmlLinks, htmlNav, htmlAside, - htmlFooter, htmlCss, htmlCssUrl, htmlNoResultsMessage; + htmlFooter, htmlStyle, htmlStyleImport, htmlScript, htmlNoResultsMessage; private final boolean htmlNoWrap; private final HtmlDocTemplate htmlTemplate; private final Map<String,Widget> widgets; @@ -112,8 +112,9 @@ class CallMethod implements Comparable<CallMethod> { this.htmlNav = b.htmlNav; this.htmlAside = b.htmlAside; this.htmlFooter = b.htmlFooter; - this.htmlCss = b.htmlCss; - this.htmlCssUrl = b.htmlCssUrl; + this.htmlStyle = b.htmlStyle; + this.htmlStyleImport = b.htmlStyleImport; + this.htmlScript = b.htmlScript; this.htmlNoWrap = b.htmlNoWrap; this.htmlTemplate = b.htmlTemplate; this.htmlNoResultsMessage = b.htmlNoResultsMessage; @@ -122,7 +123,7 @@ class CallMethod implements Comparable<CallMethod> { private static class Builder { private String httpMethod, defaultCharset, description, tags, summary, externalDocs, htmlTitle, htmlDescription, - htmlBranding, htmlLinks, htmlNav, htmlAside, htmlFooter, htmlCssUrl, htmlCss, htmlHeader, htmlNoResultsMessage; + htmlBranding, htmlLinks, htmlNav, htmlAside, htmlFooter, htmlStyle, htmlStyleImport, htmlScript, htmlHeader, htmlNoResultsMessage; private boolean htmlNoWrap; private HtmlDocTemplate htmlTemplate; private UrlPathPattern pathPattern; @@ -188,8 +189,9 @@ class CallMethod implements Comparable<CallMethod> { htmlNav = hd.nav().isEmpty() ? context.getHtmlNav() : hd.nav(); htmlAside = hd.aside().isEmpty() ? context.getHtmlAside() : hd.aside(); htmlFooter = hd.footer().isEmpty() ? context.getHtmlFooter() : hd.footer(); - htmlCss = hd.css().isEmpty() ? context.getHtmlCss() : hd.css(); - htmlCssUrl = hd.cssUrl().isEmpty() ? context.getHtmlCssUrl() : hd.cssUrl(); + htmlStyle = hd.style().isEmpty() ? context.getHtmlStyle() : hd.style(); + htmlStyleImport = hd.styleImport().isEmpty() ? context.getHtmlStyleImport() : hd.styleImport(); + htmlScript = hd.script().isEmpty() ? context.getHtmlScript() : hd.script(); htmlNoWrap = hd.nowrap() ? hd.nowrap() : context.getHtmlNoWrap(); htmlNoResultsMessage = hd.noResultsMessage().isEmpty() ? context.getHtmlNoResultsMessage() : hd.header(); htmlTemplate = @@ -935,10 +937,40 @@ class CallMethod implements Comparable<CallMethod> { return htmlAside == null ? null : req.resolveVars(htmlAside); if (k.equals(HTMLDOC_footer)) return htmlFooter == null ? null : req.resolveVars(htmlFooter); - if (k.equals(HTMLDOC_css)) - return htmlCss == null ? null : req.resolveVars(htmlCss); - if (k.equals(HTMLDOC_cssUrl)) - return htmlCssUrl == null ? null : req.resolveVars(htmlCssUrl); + if (k.equals(HTMLDOC_style)) { + Set<String> l = new LinkedHashSet<String>(); + if (htmlStyle != null) + l.add(req.resolveVars(htmlStyle)); + for (Widget w : req.getWidgets().values()) { + String style; + try { + style = w.getStyle(req); + } catch (Exception e) { + style = e.getLocalizedMessage(); + } + if (style != null) + l.add(req.resolveVars(style)); + } + return l; + } + if (k.equals(HTMLDOC_script)) { + Set<String> l = new LinkedHashSet<String>(); + if (htmlScript != null) + l.add(req.resolveVars(htmlScript)); + for (Widget w : req.getWidgets().values()) { + String script; + try { + script = w.getScript(req); + } catch (Exception e) { + script = e.getLocalizedMessage(); + } + if (script != null) + l.add(req.resolveVars(script)); + } + return l; + } + if (k.equals(HTMLDOC_styleImport)) + return htmlStyleImport == null ? null : req.resolveVars(htmlStyleImport); if (k.equals(HTMLDOC_template)) return htmlTemplate; if (k.equals(HTMLDOC_nowrap)) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/RestCallHandler.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestCallHandler.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestCallHandler.java index 3e8b6da..07e6dfa 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestCallHandler.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestCallHandler.java @@ -143,8 +143,6 @@ public class RestCallHandler { String p = pathInfo.substring(1); if (p.equals("favicon.ico")) r = context.getFavIcon(); - else if (p.equals("style.css")) - r = context.getStyleSheet(); else if (context.isStaticFile(p)) r = context.resolveStaticFile(p); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 dee6d29..3c43a8a 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 @@ -109,12 +109,11 @@ public class RestConfig implements ServletConfig { List<Object> responseHandlers = new ArrayList<Object>(); List<Object> childResources = new ArrayList<Object>(); List<MediaType> supportedContentTypes, supportedAcceptTypes; - List<Object> styleSheets; Object favIcon; List<Object> staticFiles; RestContext parentContext; String path, htmlTitle, htmlDescription, htmlBranding, htmlLinks, htmlHeader, htmlNav, htmlAside, htmlFooter, - htmlCss, htmlCssUrl, htmlNoResultsMessage; + htmlStyle, htmlStyleImport, htmlScript, htmlNoResultsMessage; String clientVersionHeader = "X-Client-Version"; Object resourceResolver = RestResourceResolver.class; @@ -202,8 +201,6 @@ public class RestConfig implements ServletConfig { addParamResolvers(r.paramResolvers()); serializerListener(r.serializerListener()); parserListener(r.parserListener()); - if (! r.stylesheet().isEmpty()) - setStyleSheet(c, r.stylesheet()); if (! r.favicon().isEmpty()) setFavIcon(c, r.favicon()); if (! r.staticFiles().isEmpty()) @@ -242,10 +239,10 @@ public class RestConfig implements ServletConfig { setHtmlAside(hd.aside()); if (! hd.footer().isEmpty()) setHtmlFooter(hd.footer()); - if (! hd.css().isEmpty()) - setHtmlCss(hd.css()); - if (! hd.cssUrl().isEmpty()) - setHtmlCssUrl(hd.cssUrl()); + if (! hd.style().isEmpty()) + setHtmlStyle(hd.style()); + if (! hd.styleImport().isEmpty()) + setHtmlStyleImport(hd.styleImport()); if (! hd.noResultsMessage().isEmpty()) setHtmlNoResultsMessage(hd.noResultsMessage()); if (hd.nowrap()) @@ -967,89 +964,6 @@ public class RestConfig implements ServletConfig { } /** - * Specifies the stylesheets that make up the contents of the page <js>"/resource-path/styles.css"</js>. - * - * <p> - * This is the programmatic equivalent to the {@link RestResource#stylesheet() @RestResource.stylesheet()} annotation. - * - * <p> - * The object types can be any of the following: - * <ul> - * <li>{@link InputStream} - * <li>{@link Reader} - * <li>{@link File} - * <li>{@link CharSequence} - * <li><code><jk>byte</jk>[]</code> - * </ul> - * - * <p> - * The contents of all these stylesheets will be aggregated into a single page in the order they are specified in - * this list. - * - * @param styleSheets The new list of style sheets that make up the <code>styles.css</code> page. - * @return This object (for method chaining). - */ - public RestConfig setStyleSheet(Object...styleSheets) { - this.styleSheets = new ArrayList<Object>(Arrays.asList(styleSheets)); - return this; - } - - /** - * Specifies the stylesheet that make up the contents of the page <js>"/resource-path/styles.css"</js>. - * - * <p> - * This is the programmatic equivalent to the {@link RestResource#stylesheet() @RestResource.stylesheet()} annotation. - * - * <p> - * Use this method to specify a resource located in the classpath. - * This call uses the {@link Class#getResourceAsStream(String)} method to retrieve the stylesheet contents. - * - * @param resourceClass The resource class used to resolve the resource stream. - * @param resourcePath - * The path passed to the {@link Class#getResourceAsStream(String)} method. - * Can also be a path starting with <js>"file://"</js> denoting a location to pull from the file system. - * @return This object (for method chaining). - */ - public RestConfig setStyleSheet(Class<?> resourceClass, String resourcePath) { - this.styleSheets = new ArrayList<Object>(); - this.styleSheets.add(new Pair<Class<?>,String>(resourceClass, resourcePath)); - return this; - } - - /** - * Adds to the stylesheet that make up the contents of the page <js>"/resource-path/styles.css"</js>. - * - * <p> - * Same as {@link #setStyleSheet(Object...)} except appends to the existing list instead of replacing. - * - * @param styleSheets The list of style sheets to add that make up the <code>styles.css</code> page. - * @return This object (for method chaining). - */ - public RestConfig addStyleSheet(Object...styleSheets) { - if (this.styleSheets == null) - this.styleSheets = new ArrayList<Object>(); - this.styleSheets.addAll(Arrays.asList(styleSheets)); - return this; - } - - /** - * Adds to the stylesheet that make up the contents of the page <js>"/resource-path/styles.css"</js>. - * - * <p> - * Same as {@link #setStyleSheet(Class,String)} except appends to the existing list instead of replacing. - * - * @param resourceClass The resource class used to resolve the resource stream. - * @param resourcePath The path passed to the {@link Class#getResourceAsStream(String)} method. - * @return This object (for method chaining). - */ - public RestConfig addStyleSheet(Class<?> resourceClass, String resourcePath) { - if (this.styleSheets == null) - this.styleSheets = new ArrayList<Object>(); - this.styleSheets.add(new Pair<Class<?>,String>(resourceClass, resourcePath)); - return this; - } - - /** * Specifies the icon contents that make up the contents of the page <js>"/resource-path/favicon.ico"</js>. * * <p> @@ -1458,13 +1372,13 @@ public class RestConfig implements ServletConfig { * A value of <js>"NONE"</js> can be used to force no value. * * <p> - * This is the programmatic equivalent to the {@link HtmlDoc#css() @HtmlDoc.css()} annotation. + * This is the programmatic equivalent to the {@link HtmlDoc#style() @HtmlDoc.style()} annotation. * * @param value The HTML CSS style section contents. * @return This object (for method chaining). */ - public RestConfig setHtmlCss(String value) { - this.htmlCss = value; + public RestConfig setHtmlStyle(String value) { + this.htmlStyle = value; return this; } @@ -1485,13 +1399,36 @@ public class RestConfig implements ServletConfig { * by {@link UriResolver}. * * <p> - * This is the programmatic equivalent to the {@link HtmlDoc#cssUrl() @HtmlDoc.cssUrl()} annotation. + * This is the programmatic equivalent to the {@link HtmlDoc#styleImport() @HtmlDoc.styleImport()} annotation. * * @param value The CSS URL in the HTML CSS style section. * @return This object (for method chaining). */ - public RestConfig setHtmlCssUrl(String value) { - this.htmlCssUrl = value; + public RestConfig setHtmlStyleImport(String value) { + this.htmlStyleImport = value; + return this; + } + + /** + * Sets the HTML script section contents. + * + * <p> + * The format of this value is Javascript. + * + * <p> + * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>). + * + * <p> + * A value of <js>"NONE"</js> can be used to force no value. + * + * <p> + * This is the programmatic equivalent to the {@link HtmlDoc#script() @HtmlDoc.script()} annotation. + * + * @param value The HTML script section contents. + * @return This object (for method chaining). + */ + public RestConfig setHtmlScript(String value) { + this.htmlScript = value; return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 bb6e970..cd41c80 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 @@ -15,7 +15,6 @@ package org.apache.juneau.rest; import static javax.servlet.http.HttpServletResponse.*; import static org.apache.juneau.internal.ArrayUtils.*; import static org.apache.juneau.internal.ClassUtils.*; -import static org.apache.juneau.internal.FileUtils.*; import static org.apache.juneau.internal.IOUtils.*; import static org.apache.juneau.internal.ReflectionUtils.*; import static org.apache.juneau.internal.StringUtils.*; @@ -358,8 +357,9 @@ public final class RestContext extends Context { htmlLinks, htmlNav, htmlAside, - htmlCss, - htmlCssUrl, + htmlStyle, + htmlStyleImport, + htmlScript, htmlFooter, htmlNoResultsMessage; private final boolean htmlNoWrap; @@ -388,7 +388,7 @@ public final class RestContext extends Context { private final RestGuard[] guards; private final ResponseHandler[] responseHandlers; private final MimetypesFileTypeMap mimetypesFileTypeMap; - private final StreamResource styleSheet, favIcon; + private final StreamResource favIcon; private final Map<String,String> staticFilesMap; private final String[] staticFilesPrefixes; private final MessageBundle msgs; @@ -405,8 +405,8 @@ public final class RestContext extends Context { // In-memory cache of images and stylesheets in the org.apache.juneau.rest.htdocs package. private final Map<String,StreamResource> staticFilesCache = new ConcurrentHashMap<String,StreamResource>(); - private final Map<String,byte[]> resourceStreams = new ConcurrentHashMap<String,byte[]>(); - private final Map<String,String> resourceStrings = new ConcurrentHashMap<String,String>(); + + private final ResourceFinder resourceFinder; private final ConcurrentHashMap<Integer,AtomicInteger> stackTraceHashes = new ConcurrentHashMap<Integer,AtomicInteger>(); @@ -424,6 +424,7 @@ public final class RestContext extends Context { try { this.resource = resource; this.config = config; + this.resourceFinder = new ResourceFinder(resource.getClass()); this.parentContext = config.parentContext; Builder b = new Builder(resource, config); @@ -455,7 +456,6 @@ public final class RestContext extends Context { this.guards = b.guards.toArray(new RestGuard[b.guards.size()]); this.responseHandlers = toObjectArray(b.responseHandlers, ResponseHandler.class); this.mimetypesFileTypeMap = b.mimetypesFileTypeMap; - this.styleSheet = b.styleSheet; this.favIcon = b.favIcon; this.staticFilesMap = Collections.unmodifiableMap(b.staticFilesMap); this.staticFilesPrefixes = b.staticFilesPrefixes; @@ -472,8 +472,9 @@ public final class RestContext extends Context { this.htmlLinks = b.htmlLinks; this.htmlNav = b.htmlNav; this.htmlAside = b.htmlAside; - this.htmlCss = b.htmlCss; - this.htmlCssUrl = b.htmlCssUrl; + this.htmlStyle = b.htmlStyle; + this.htmlStyleImport = b.htmlStyleImport; + this.htmlScript = b.htmlScript; this.htmlFooter = b.htmlFooter; this.htmlNoWrap = b.htmlNoWrap; this.htmlNoResultsMessage = b.htmlNoResultsMessage; @@ -652,7 +653,7 @@ public final class RestContext extends Context { UrlEncodingParser urlEncodingParser; EncoderGroup encoders; String clientVersionHeader = "", defaultCharset, paramFormat, htmlTitle, htmlDescription, htmlBranding, - htmlHeader, htmlLinks, htmlNav, htmlAside, htmlCss, htmlCssUrl, htmlFooter, htmlNoResultsMessage; + htmlHeader, htmlLinks, htmlNav, htmlAside, htmlStyle, htmlStyleImport, htmlScript, htmlFooter, htmlNoResultsMessage; boolean htmlNoWrap; HtmlDocTemplate htmlTemplate; @@ -664,7 +665,7 @@ public final class RestContext extends Context { List<RestGuard> guards = new ArrayList<RestGuard>(); List<ResponseHandler> responseHandlers = new ArrayList<ResponseHandler>(); MimetypesFileTypeMap mimetypesFileTypeMap; - StreamResource styleSheet, favIcon; + StreamResource favIcon; Map<String,String> staticFilesMap; String[] staticFilesPrefixes; MessageBundle messageBundle; @@ -752,23 +753,6 @@ public final class RestContext extends Context { VarResolver vr = sc.getVarResolverBuilder().build(); - if (sc.styleSheets != null) { - List<InputStream> contents = new ArrayList<InputStream>(); - for (Object o : sc.styleSheets) { - if (o instanceof Pair) { - Pair<Class<?>,String> p = (Pair<Class<?>,String>)o; - for (String path : split(vr.resolve(StringUtils.toString(p.second())))) - if (path.startsWith("file://")) - contents.add(new FileInputStream(path)); - else - contents.add(ReflectionUtils.getResource(p.first(), path)); - } else { - contents.add(toInputStream(o)); - } - } - styleSheet = new StreamResource(MediaType.forString("text/css"), contents.toArray()); - } - if (sc.favIcon != null) { Object o = sc.favIcon; InputStream is = null; @@ -809,8 +793,9 @@ public final class RestContext extends Context { htmlLinks = sc.htmlLinks; htmlNav = sc.htmlNav; htmlAside = sc.htmlAside; - htmlCss = sc.htmlCss; - htmlCssUrl = sc.htmlCssUrl; + htmlStyle = sc.htmlStyle; + htmlStyleImport = sc.htmlStyleImport; + htmlScript = sc.htmlScript; htmlFooter = sc.htmlFooter; htmlNoWrap = sc.htmlNoWrap; htmlNoResultsMessage = sc.htmlNoResultsMessage; @@ -948,28 +933,7 @@ public final class RestContext extends Context { * @throws IOException */ protected InputStream getResource(String name, Locale locale) throws IOException { - String n = (locale == null || locale.toString().isEmpty() ? name : name + '|' + locale); - if (! resourceStreams.containsKey(n)) { - InputStream is = getLocalizedResource(resource.getClass(), name, locale); - if (is == null && name.indexOf("..") == -1) { - for (String n2 : getCandidateFileNames(name, locale)) { - File f = new File(n2); - if (f.exists() && f.canRead()) { - is = new FileInputStream(f); - break; - } - } - } - if (is != null) { - try { - resourceStreams.put(n, ByteArrayCache.DEFAULT.cache(is)); - } finally { - is.close(); - } - } - } - byte[] b = resourceStreams.get(n); - return b == null ? null : new ByteArrayInputStream(b); + return resourceFinder.getResourceAsStream(name, locale); } /** @@ -981,14 +945,7 @@ public final class RestContext extends Context { * @throws IOException If resource could not be found. */ public String getResourceAsString(String name, Locale locale) throws IOException { - String n = (locale == null || locale.toString().isEmpty() ? name : name + '|' + locale); - if (! resourceStrings.containsKey(n)) { - String s = read(getResource(name, locale)); - if (s == null) - throw new IOException("Resource '"+name+"' not found."); - resourceStrings.put(n, s); - } - return resourceStrings.get(n); + return resourceFinder.getResourceAsString(name, locale); } /** @@ -1140,27 +1097,39 @@ public final class RestContext extends Context { } /** - * The HTML page CSS URL. + * The HTML page stylesheet URL. * * <p> - * Defined by the {@link HtmlDoc#cssUrl()} annotation or {@link RestConfig#setHtmlCssUrl(String)} method. + * Defined by the {@link HtmlDoc#styleImport()} annotation or {@link RestConfig#setHtmlStyleImport(String)} method. * * @return The HTML page CSS URL. */ - public String getHtmlCssUrl() { - return htmlCssUrl; + public String getHtmlStyleImport() { + return htmlStyleImport; } /** * The HTML page CSS contents. * * <p> - * Defined by the {@link HtmlDoc#css()} annotation or {@link RestConfig#setHtmlCss(String)} method. + * Defined by the {@link HtmlDoc#style()} annotation or {@link RestConfig#setHtmlStyle(String)} method. * * @return The HTML page CSS contents. */ - public String getHtmlCss() { - return htmlCss; + public String getHtmlStyle() { + return htmlStyle; + } + + /** + * The HTML page Javascript contents. + * + * <p> + * Defined by the {@link HtmlDoc#script()} annotation or {@link RestConfig#setHtmlScript(String)} method. + * + * @return The HTML page Javascript contents. + */ + public String getHtmlScript() { + return htmlScript; } /** @@ -1815,25 +1784,6 @@ public final class RestContext extends Context { } /** - * Returns the stylesheet for use in the HTML views of the resource. - * - * <p> - * This is the contents of the page served up under <js>"/styles.css"</jk>. - * - * <p> - * The stylesheet is defined via one of the following: - * <ul> - * <li>{@link RestResource#stylesheet() @RestResource.stylesheet()} annotation. - * <li>{@link RestConfig#setStyleSheet(Object...)}/{@link RestConfig#setStyleSheet(Class, String)} methods. - * </ul> - * - * @return The aggregated stylesheet of this resource. Never <jk>null</jk>. - */ - protected StreamResource getStyleSheet() { - return styleSheet; - } - - /** * Returns <jk>true</jk> if the specified path refers to a static file. * * <p> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 1d85c9e..9aa6672 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 @@ -767,7 +767,7 @@ public final class RestResponse extends HttpServletResponseWrapper { * A value of <js>"NONE"</js> can be used to force no value. * * <p> - * This is the programmatic equivalent to the {@link HtmlDoc#css() @HtmlDoc.css()} annotation. + * This is the programmatic equivalent to the {@link HtmlDoc#style() @HtmlDoc.style()} annotation. * * @param value * The HTML CSS style section contents. @@ -780,8 +780,8 @@ public final class RestResponse extends HttpServletResponseWrapper { * </ul> * @return This object (for method chaining). */ - public RestResponse setHtmlCss(Object value) { - properties.put(HtmlDocSerializerContext.HTMLDOC_css, value); + public RestResponse setHtmlStyle(Object value) { + properties.put(HtmlDocSerializerContext.HTMLDOC_style, value); return this; } @@ -789,7 +789,7 @@ public final class RestResponse extends HttpServletResponseWrapper { * Sets the CSS URL in the HTML CSS style section. * * <p> - * The format of this value is a URL. + * The format of this value is a comma-delimited list of URLs. * * <p> * Specifies the URL to the stylesheet to add as a link in the style tag in the header. @@ -802,7 +802,7 @@ public final class RestResponse extends HttpServletResponseWrapper { * by {@link UriResolver}. * * <p> - * This is the programmatic equivalent to the {@link HtmlDoc#cssUrl() @HtmlDoc.cssUrl()} annotation. + * This is the programmatic equivalent to the {@link HtmlDoc#styleImport() @HtmlDoc.styleImport()} annotation. * * @param value * The CSS URL in the HTML CSS style section. @@ -815,8 +815,39 @@ public final class RestResponse extends HttpServletResponseWrapper { * </ul> * @return This object (for method chaining). */ - public RestResponse setHtmlCssUrl(Object value) { - properties.put(HtmlDocSerializerContext.HTMLDOC_cssUrl, value); + public RestResponse setHtmlStyleImport(Object value) { + properties.put(HtmlDocSerializerContext.HTMLDOC_styleImport, value); + return this; + } + + /** + * Sets the HTML script section contents. + * + * <p> + * The format of this value is Javascript. + * + * <p> + * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>). + * + * <p> + * A value of <js>"NONE"</js> can be used to force no value. + * + * <p> + * This is the programmatic equivalent to the {@link HtmlDoc#script() @HtmlDoc.script()} annotation. + * + * @param value + * The HTML script section contents. + * Object will be converted to a string using {@link Object#toString()}. + * <p> + * <ul class='doctree'> + * <li class='info'> + * <b>Tip:</b> Use {@link StringMessage} to generate value with delayed serialization so as not to + * waste string concatenation cycles on non-HTML views. + * </ul> + * @return This object (for method chaining). + */ + public RestResponse setHtmlScript(Object value) { + properties.put(HtmlDocSerializerContext.HTMLDOC_script, value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 dc5f7ed..32f2b18 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 @@ -148,7 +148,7 @@ import org.apache.juneau.xml.*; * <h6 class='topic'>Other Notes</h6> * <ul class='spaced-list'> * <li> - * Provides a default HTML stylesheet by setting {@link RestResource#stylesheet() @RestResource.stylesheet()} + * Provides a default HTML stylesheet by setting {@link HtmlDoc#styleImport() @HtmlDoc.styleImport()} * to <js>"styles/juneau.css"</js>. * <li> * Provides a default favicon by setting {@link RestResource#favicon() @RestResource.favicon()} to @@ -189,12 +189,16 @@ import org.apache.juneau.xml.*; // Allow &method parameter on safe HTTP methods. @Property(name=REST_allowMethodParam, value="OPTIONS"), }, - stylesheet="styles/juneau.css", htmldoc=@HtmlDoc( - branding="<a href='http://juneau.apache.org'><img src='$U{servlet:/htdocs/juneau.png}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'></a>" + branding="<a href='http://juneau.apache.org'><img src='$U{servlet:/htdocs/juneau.png}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'></a>", + styleImport="servlet:/styles/devops.css" ), + + // The location on the classpath or file system of the fav-icon. favicon="htdocs/juneau.png", - staticFiles="{htdocs:'htdocs'}" + + // These are static files that are served up by the servlet under the specified sub-paths. + staticFiles="{htdocs:'htdocs',styles:'styles'}" ) public abstract class RestServletDefault extends RestServlet { private static final long serialVersionUID = 1L; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java index 8b4fbb9..fe1a5de 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java @@ -360,7 +360,7 @@ public @interface HtmlDoc { * <p class='bcode'> * <ja>@RestResource</ja>( * htmldoc=<ja>@HtmlDoc</ja>( - * css=<js>".red{color:red;}\n.blue{color:blue}"</js> + * style=<js>".red{color:red;}\n.blue{color:blue}"</js> * ) * ) * </p> @@ -373,9 +373,9 @@ public @interface HtmlDoc { * * <p> * The programmatic equivalent to this annotation are the - * {@link RestConfig#setHtmlCss(String)}/{@link RestResponse#setHtmlCss(Object)} methods. + * {@link RestConfig#setHtmlStyle(String)}/{@link RestResponse#setHtmlStyle(Object)} methods. */ - String css() default ""; + String style() default ""; /** * Sets the CSS URL in the HTML CSS style section. @@ -404,9 +404,36 @@ public @interface HtmlDoc { * * <p> * The programmatic equivalent to this annotation are the - * {@link RestConfig#setHtmlCssUrl(String)}/{@link RestResponse#setHtmlCssUrl(Object)} methods. + * {@link RestConfig#setHtmlStyleImport(String)}/{@link RestResponse#setHtmlStyleImport(Object)} methods. */ - String cssUrl() default "servlet:/style.css"; + String styleImport() default ""; + + /** + * Sets the HTML script section contents. + * + * <p> + * The format of this value is Javascript. + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * script=<js>"alert('Hello!')"</js> + * ) + * ) + * </p> + * + * <p> + * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>). + * + * <p> + * A value of <js>"NONE"</js> can be used to force no value. + * + * <p> + * The programmatic equivalent to this annotation are the + * {@link RestConfig#setHtmlScript(String)}/{@link RestResponse#setHtmlScript(Object)} methods. + */ + String script() default ""; /** * Shorthand method for forcing the rendered HTML content to be no-wrap. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 5db9ae5..9c82c3e 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 @@ -479,75 +479,10 @@ public @interface RestResource { String config() default ""; /** - * The stylesheet to use for HTML views. - * - * <p> - * The name is a path to a stylesheet located in either the classpath or working directory. - * The resulting stylesheet becomes available through the servlet via the URL <js>"[servlet-path]/style.css"</js>. - * - * <p> - * The default set of styles located in the <code>org.apache.juneau.rest.styles</code> package are: - * <ul class='spaced-list'> - * <li> - * <js>"styles/juneau.css"</js> - Theme based on Jazz look-and-feel. - * <li> - * <js>"styles/devops.css"</js> - Theme based on IBM DevOps look-and-feel. - * </ul> - * - * <p> - * The classpath search starts with the child servlet class and proceeds up the class hierarchy chain. - * Since the {@link RestServlet} class is in the <code>org.apache.juneau.rest</code> package and the predefined - * styles are in the <code>org.apache.juneau.rest.styles</code> package, the paths to the predefined styles are - * prefixed with <js>"styles/"</js>. - * - * <p> - * If the stylesheet cannot be found on the classpath, an attempt to look in the working directory for it will be - * made. - * This allows for stylesheets to be placed on the file system in the working directory. - * - * <p> - * If the file cannot be located, the request to <js>"[servlet-path]/style.css"</js> will return - * {@link HttpServletResponse#SC_NOT_FOUND}. - * - * <h5 class='section'>Example:</h5> - * <p class='bcode'> - * <jk>package</jk> com.foo.mypackage; - * - * <ja>@RestResource</ja>( - * stylesheet=<js>"mystyles/mycss.css"</js> - * ) - * <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { - * } - * </p> - * - * <p> - * In this example, the servlet will attempt to find the <code>mycss.css</code> file in the following ordered - * locations: - * </p> - * <ol> - * <li><code>com.foo.mypackage.mystyles</code> package. - * <li><code>org.apache.juneau.rest.mystyles</code> package (since <code>RestServletDefault</code> is in - * <code>org.apache.juneau.rest</code>). - * <li><code>[working-dir]/mystyles</code> directory. - * </ol> - * - * <p> - * Multiple stylesheets can be specified as a comma-delimited list. - * When multiple stylesheets are specified, their contents will be concatenated and return in the order specified - * in the list. - * - * <p> - * The programmatic equivalent to this annotation are the {@link RestConfig#addStyleSheet(Object...)}/ - * {@link RestConfig#addStyleSheet(Class, String)} methods. - */ - String stylesheet() default ""; - - /** * The favicon to use for HTML views. * * <p> - * The name is a path to an icon file located in either the classpath or working directory in a similar way to how - * the {@link #stylesheet()} stylesheet is resolved. + * The name is a path to an icon file located in either the classpath or working directory. * The resulting favicon becomes available in the servlet via the URL <js>"[servlet-path]/favicon.ico"</js>. * * <p> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 01a47d1..2f9e420 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 @@ -244,9 +244,12 @@ import org.apache.juneau.xml.*; // Allow &method parameter on safe HTTP methods. @Property(name=REST_allowMethodParam, value="OPTIONS") }, - stylesheet="styles/juneau.css", - favicon="juneau.ico", - staticFiles="{htdocs:'htdocs'}" + htmldoc=@HtmlDoc( + branding="<a href='http://juneau.apache.org'><img src='$U{servlet:/htdocs/juneau.png}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'></a>", + styleImport="servlet:/styles/devops.css" + ), + favicon="htdocs/juneau.png", + staticFiles="{htdocs:'htdocs',styles:'styles'}" ) public abstract class RestServletJenaDefault extends RestServlet { private static final long serialVersionUID = 1L; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/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 0e0940c..c2a7328 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 @@ -2503,61 +2503,7 @@ <a id="RestResources.Stylesheet"></a> <h3 class='topic' onclick='toggle(this)'>4.17 - Stylesheet</h3> <div class='topic'> - <p> - The {@link org.apache.juneau.rest.annotation.RestResource#stylesheet @RestResource.stylesheet()} annotation - is used to identify the stylesheet to use when rendering POJOs as HTML. - </p> - <p> - The value is a path to a stylesheet located in either the classpath or working directory. - The resulting stylesheet becomes available as a static file through the servlet via the URL - <js>"[servletpath]/style.css"</js>. - </p> - <p> - The default set of styles located in the <l>org.apache.juneau.rest.styles</l> package are: - </p> - <ul class='spaced-list'> - <li> - <l>"styles/devops.css"</l> - Theme based on IBM DevOps look-and-feel. - <li> - <l>"styles/juneau.css"</l> - Theme based on Jazz look-and-feel. - </ul> - <p> - The DevOps look-and-feel is the newer style: - </p> - <img class='bordered' src='doc-files/AddressBook.png'> - <p> - The Juneau look-and-feel is an older style based on the Jazz Framework: - </p> - <img class='bordered' src='doc-files/AddressBook_juneaustyle.png'> - <p> - Stylesheets are first found in the classpath relative to the servlet class. - If the stylesheet cannot be found on the classpath, an attempt to look in the working directory. - </p> - <p> - If the file cannot be located, the request to <l>"[servletpath]/style.css"</l> will return - {@link javax.servlet.http.HttpServletResponse#SC_NOT_FOUND}. - </p> - <p> - Custom stylesheets can be defined by specifying your own stylesheet annotation value: - </p> - <p class='bcode'> - <jk>package</jk> com.foo.mypackage; - <ja>@RestResource</ja>( - stylesheet=<js>"mystyles/mycss.css"</js> - ) - <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { - } - </p> - <p> - In this example, the servlet will attempt to find the <l>mycss.css</l> file in the following ordered - locations: - </p> - <ol> - <li><l>com.foo.mypackage.mystyles</l> package. - <li><l>org.apache.juneau.rest.mystyles</l> package (since <l>RestServletDefault</l> is in - <l>org.apache.juneau.rest</l>). - <li><l>[working-dir]/mystyles</l> directory. - </ol> + TODO </div> <!-- ======================================================================================================== --> @@ -2770,8 +2716,10 @@ </p> <p class='bcode'> <ja>@RestResource</ja>( - <jc>// Get stylesheet from myconfig.cfg, but default to juneau.css if it's not specified</jc> - stylesheet=<js>"$C{MyServlet/stylesheet,styles/juneau.css}"</js>, + <jc>// Get stylesheet from myconfig.cfg, but default to devops.css if it's not specified</jc> + htmldoc=<ja>@HtmlDoc</ja>( + styleImport=<js>"$C{MyServlet/stylesheet,servlet:/styles/devops.css}"</js>, + ) ... ) <jk>public</jk> MyRestServlet <jk>extends</jk> RestServlet { @@ -2983,12 +2931,6 @@ </td> </tr> <tr> - <td>{@link org.apache.juneau.rest.annotation.RestResource#stylesheet() stylesheet()}</td> - <td> - Stylesheet is searched for in child-to-parent order. - </td> - </tr> - <tr> <td>{@link org.apache.juneau.rest.annotation.RestResource#favicon() favicon()}</td> <td> Favicon is searched for in child-to-parent order. @@ -3495,6 +3437,9 @@ // "$C{...}" variables are pulled from the config file.</jc> htmldoc=<ja>@HtmlDoc</ja>( links=<js>"{up:'request:/..', options:'servlet:/?method=OPTIONS', source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java'}"</js> + + <jc>// Our stylesheet for the HTML rendition.</jc> + styleImport=<js>"servlet:/styles/devops.css"</js>, ), <jc>// Properties that get applied to all serializers and parsers.</jc> @@ -3519,19 +3464,18 @@ <ja>@Property</ja>(name=<jsf>HTML_uriAnchorText</jsf>, value=<js>"SERVLET_RELATIVE"</js>) }, - <jc>// Our stylesheet for the HTML rendition.</jc> - stylesheet=<js>"styles/devops.css"</js>, - <jc>// Support GZIP encoding on Accept-Encoding header.</jc> encoders=GzipEncoder.<jk>class</jk>, <jc>// Swagger info.</jc> - contact=<js>"{name:'John Smith',email:'[email protected]'}"</js>, - license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>, - version=<js>"2.0"</js>, - termsOfService=<js>"You're on your own."</js>, - tags=<js>"[{name:'Java',description:'Java utility',externalDocs:{description:'Home page',url:'http://juneau.apache.org'}}]"</js>, - externalDocs=<js>"{description:'Home page',url:'http://juneau.apache.org'}"</js> + swagger=<ja>@ResourceSwagger</ja>( + contact=<js>"{name:'John Smith',email:'[email protected]'}"</js>, + license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>, + version=<js>"2.0"</js>, + termsOfService=<js>"You're on your own."</js>, + tags=<js>"[{name:'Java',description:'Java utility',externalDocs:{description:'Home page',url:'http://juneau.apache.org'}}]"</js>, + externalDocs=<js>"{description:'Home page',url:'http://juneau.apache.org'}"</js> + ) ) <jk>public class</jk> AddressBookResource <jk>extends</jk> ResourceJena { <jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java index 670811a..f43b059 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/WidgetVar.java @@ -59,7 +59,7 @@ public class WidgetVar extends SimpleVar { if (w == null) return "unknown-widget-"+key; try { - return w.resolve(req); + return w.getHtml(req); } catch (Exception e) { return "widget-error-"+e.getLocalizedMessage(); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksColumnWidget.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksColumnWidget.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksColumnWidget.java deleted file mode 100644 index 7ef4982..0000000 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksColumnWidget.java +++ /dev/null @@ -1,49 +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.rest.widget; - -import static org.apache.juneau.dto.html5.HtmlBuilder.*; - -import java.util.*; - -import org.apache.juneau.*; -import org.apache.juneau.dto.html5.*; -import org.apache.juneau.html.*; -import org.apache.juneau.http.*; -import org.apache.juneau.rest.*; - -/** - * 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{contentTypeLinksColumn}"</js>. - */ -public class ContentTypeLinksColumnWidget extends Widget { - - @Override /* Widget */ - public String getName() { - return "contentTypeLinksColumn"; - } - - @Override /* Widget */ - public String resolve(RestRequest req) throws Exception { - UriResolver uriResolver = req.getUriResolver(); - P p = p(); - List<MediaType> l = new ArrayList<MediaType>(req.getSerializerGroup().getSupportedMediaTypes()); - Collections.sort(l); - for (MediaType mt : l) - p.child(a()._class("link").href(uriResolver.resolve("request:/?plainText=true&Accept="+mt)).child(mt)).child(br()); - return HtmlSerializer.DEFAULT_SQ.serialize(p); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksRowWidget.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksRowWidget.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksRowWidget.java deleted file mode 100644 index d395028..0000000 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeLinksRowWidget.java +++ /dev/null @@ -1,49 +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.rest.widget; - -import static org.apache.juneau.dto.html5.HtmlBuilder.*; - -import java.util.*; - -import org.apache.juneau.*; -import org.apache.juneau.dto.html5.*; -import org.apache.juneau.html.*; -import org.apache.juneau.http.*; -import org.apache.juneau.rest.*; - -/** - * 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{contentTypeLinksRow}"</js>. - */ -public class ContentTypeLinksRowWidget extends Widget { - - @Override /* Widget */ - public String getName() { - return "contentTypeLinksRow"; - } - - @Override /* Widget */ - public String resolve(RestRequest req) throws Exception { - UriResolver uriResolver = req.getUriResolver(); - P p = p(); - List<MediaType> l = new ArrayList<MediaType>(req.getSerializerGroup().getSupportedMediaTypes()); - Collections.sort(l); - for (MediaType mt : l) - p.style("max-width:1200px").child(a()._class("link").href(uriResolver.resolve("request:/?plainText=true&Accept="+mt)).children(mt)).child("\u00AD"); - return HtmlSerializer.DEFAULT_SQ.serialize(p); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java new file mode 100644 index 0000000..64c0daf --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java @@ -0,0 +1,82 @@ +// *************************************************************************************************************************** +// * 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.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.http.*; +import org.apache.juneau.rest.*; + +/** + * 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:'...',options:'...',query:'...',contentTypes:'$W{contentTypeMenuItem}',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 { + + /** + * Returns <js>"contentTypeMenuItem"</js>. + */ + @Override /* Widget */ + public String getName() { + return "contentTypeMenuItem"; + } + + /** + * 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 String getHtml(RestRequest req) throws Exception { + UriResolver r = req.getUriResolver(); + StringBuilder sb = new StringBuilder(); + sb.append("" + + "<div class='menu-item'>" + + "\n\t<a class='link' onclick='menuClick(this)'>content-types</a>" + + "\n\t<div class='popup-content'>" + ); + List<MediaType> l = new ArrayList<MediaType>(req.getSerializerGroup().getSupportedMediaTypes()); + Collections.sort(l); + for (MediaType mt : l) + sb.append("\n\t\t<a class='link' href='").append(r.resolve("request:/?plainText=true&Accept="+mt)) + .append("'>").append(mt).append("</a><br>"); + sb.append("" + + "\n\t</div>" + + "\n</div>" + ); + return sb.toString(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java new file mode 100644 index 0000000..67c89ae --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java @@ -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 org.apache.juneau.rest.*; + +/** + * 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 arbirary 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 a {@link #getHtml(RestRequest)} that returns the following content: + * <p class='bcode'> + * <xt><div</xt> <xa>class</xa>=<xs>'menu-item'</xs><xt>></xt> + * <xc><!-- Normally visible content with onclick='menuClick(this)' --></xc> + * <xt><div</xt> <xa>class</xa>=<xs>'popup-content'</xs><xt>></xt> + * <xc><!-- Normally hidden popup-content --></xc> + * <xt></div></xt> + * <xt></div></xt> + * </p> + * + * <p> + * For example, to render a link that brings up a simple dialog: + * <p class='bcode'> + * <xt><div</xt> <xa>class</xa>=<xs>'menu-item'</xs><xt>></xt> + * <xt><a</xt> <xa>class</xa>=<xs>'link'</xs> <xa>onclick</xa>=<xs>'menuClick(this)'</xs><xt>></xt>my-menu-item<xt></a></xt> + * <xt><div</xt> <xa>class</xa>=<xs>'popup-content'</xs><xt>></xt> + * Surprise! + * <xt></div></xt> + * <xt></div></xt> + * </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 + public String getScript(RestRequest req) throws Exception { + return getResourceAsString("MenuItemWidget.js").replaceAll("(?s)\\/\\*{2}(.*?)\\/\\*\\s*", ""); + } + + /** + * 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 + public String getStyle(RestRequest req) throws Exception { + return getResourceAsString("MenuItemWidget.css").replaceAll("(?s)\\/\\*{2}(.*?)\\/\\*\\s*", ""); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByApacheWidget.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByApacheWidget.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByApacheWidget.java index e322439..cd6da66 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByApacheWidget.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByApacheWidget.java @@ -12,6 +12,7 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.widget; +import org.apache.juneau.*; import org.apache.juneau.rest.*; /** @@ -19,17 +20,45 @@ import org.apache.juneau.rest.*; * * <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={ + * PoweredByApacheWidget.<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 PoweredByApacheWidget extends Widget { + /** + * Returns <js>"poweredByApache"</js>. + */ @Override /* Widget */ public String getName() { return "poweredByApache"; } + /** + * Returns an Apache image tag hyperlinked to <js>"http://apache.org"</js> + */ @Override /* Widget */ - public String resolve(RestRequest req) throws Exception { - return "<a href='http://apache.org'><img style='float:right;padding-right:20px;height:32px' src='"+req.getUriResolver().resolve("servlet:/htdocs/asf.png")+"'>"; + 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")+"'>"; } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneauWidget.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneauWidget.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneauWidget.java index f42f0c5..55c339b 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneauWidget.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/PoweredByJuneauWidget.java @@ -12,6 +12,7 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.widget; +import org.apache.juneau.*; import org.apache.juneau.rest.*; /** @@ -19,17 +20,43 @@ import org.apache.juneau.rest.*; * * <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={ + * PoweredByJuneauWidget.<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 PoweredByJuneauWidget extends Widget { + /** + * Returns <js>"poweredByJuneau"</js>. + */ @Override /* Widget */ public String getName() { return "poweredByJuneau"; } + /** + * Returns an Apache Juneau image tag hyperlinked to <js>"http://juneau.apache.org"</js> + */ @Override /* Widget */ - public String resolve(RestRequest req) throws Exception { - return "<a href='http://apache.org'><img style='float:right;padding-right:20px;height:32px' src='"+req.getUriResolver().resolve("servlet:/htdocs/juneau.png")+"'>"; + 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")+"'>"; } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ada4053b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java new file mode 100644 index 0000000..fcef7ff --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/widget/QueryMenuItem.java @@ -0,0 +1,87 @@ +// *************************************************************************************************************************** +// * 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:'...',options:'...',query:'$W{queryMenuItem}',contentTypes:'...',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 <js>"queryMenuItem"</js>. + */ + @Override /* Widget */ + public String getName() { + return "queryMenuItem"; + } + + /** + * Returns CSS for the tooltips. + */ + @Override + public String getStyle(RestRequest req) throws Exception { + return super.getStyle(req) + + "\n" + + getResourceAsString("QueryMenuItem.css").replaceFirst("(?s)\\/\\*{2}(.*?)\\/\\*\\s*", ""); + } + + /** + * Returns the HTML for rendering the query form and tooltips. + */ + @Override /* Widget */ + public String getHtml(RestRequest req) throws Exception { + return getResourceAsString("QueryMenuItem.html").replaceFirst("(?s)<!--(.*?)-->\\s*", ""); + } +}
