Enhancements to HTML Doc rendering. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/f4812b7c Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/f4812b7c Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/f4812b7c
Branch: refs/heads/master Commit: f4812b7ce2d5f6115f62b0045f8f7983f406c597 Parents: 3bdc0d8 Author: JamesBognar <[email protected]> Authored: Tue Jun 6 20:27:36 2017 -0400 Committer: JamesBognar <[email protected]> Committed: Tue Jun 6 20:27:36 2017 -0400 ---------------------------------------------------------------------- .../apache/juneau/jena/RdfParserBuilder.java | 4 +- .../juneau/jena/RdfSerializerBuilder.java | 4 +- .../java/org/apache/juneau/jena/package.html | 4 +- .../org/apache/juneau/CoreObjectBuilder.java | 5 +- .../main/java/org/apache/juneau/ObjectMap.java | 7 +- .../java/org/apache/juneau/PropertyStore.java | 34 ++ .../org/apache/juneau/csv/CsvParserBuilder.java | 4 +- .../apache/juneau/csv/CsvSerializerBuilder.java | 4 +- .../apache/juneau/dto/jsonschema/package.html | 4 +- .../juneau/encoders/EncoderGroupBuilder.java | 2 +- .../juneau/html/HtmlBeanPropertyMeta.java | 3 +- .../org/apache/juneau/html/HtmlClassMeta.java | 12 + .../apache/juneau/html/HtmlDocSerializer.java | 101 +----- .../juneau/html/HtmlDocSerializerContext.java | 289 +++++++++++++-- .../juneau/html/HtmlDocSerializerSession.java | 126 +++++-- .../org/apache/juneau/html/HtmlDocTemplate.java | 164 +++++++++ .../juneau/html/HtmlDocTemplateBasic.java | 188 ++++++++++ .../apache/juneau/html/HtmlParserBuilder.java | 4 +- .../java/org/apache/juneau/html/HtmlRender.java | 2 +- .../org/apache/juneau/html/HtmlSerializer.java | 17 +- .../juneau/html/HtmlSerializerBuilder.java | 4 +- .../java/org/apache/juneau/html/HtmlWriter.java | 1 - .../org/apache/juneau/html/annotation/Html.java | 2 +- .../java/org/apache/juneau/http/MediaType.java | 7 +- .../org/apache/juneau/internal/ClassUtils.java | 36 +- .../org/apache/juneau/internal/ObjectUtils.java | 3 + .../org/apache/juneau/jso/JsoParserBuilder.java | 4 +- .../apache/juneau/jso/JsoSerializerBuilder.java | 4 +- .../apache/juneau/json/JsonParserBuilder.java | 4 +- .../json/JsonSchemaSerializerBuilder.java | 4 +- .../juneau/json/JsonSerializerBuilder.java | 4 +- .../java/org/apache/juneau/json/package.html | 4 +- .../juneau/msgpack/MsgPackParserBuilder.java | 4 +- .../msgpack/MsgPackSerializerBuilder.java | 4 +- .../org/apache/juneau/parser/ParserBuilder.java | 4 +- .../juneau/parser/ParserGroupBuilder.java | 5 +- .../plaintext/PlainTextParserBuilder.java | 4 +- .../plaintext/PlainTextSerializerBuilder.java | 4 +- .../juneau/remoteable/RemoteMethodArg.java | 2 +- .../juneau/serializer/SerializerBuilder.java | 4 +- .../serializer/SerializerGroupBuilder.java | 7 +- .../apache/juneau/soap/SoapXmlSerializer.java | 4 +- .../juneau/soap/SoapXmlSerializerBuilder.java | 4 +- .../org/apache/juneau/uon/UonParserBuilder.java | 4 +- .../apache/juneau/uon/UonSerializerBuilder.java | 4 +- .../java/org/apache/juneau/uon/package.html | 4 +- .../urlencoding/UrlEncodingParserBuilder.java | 4 +- .../UrlEncodingSerializerBuilder.java | 4 +- .../org/apache/juneau/urlencoding/package.html | 4 +- .../org/apache/juneau/xml/XmlParserBuilder.java | 4 +- .../juneau/xml/XmlSchemaSerializerBuilder.java | 4 +- .../apache/juneau/xml/XmlSerializerBuilder.java | 4 +- .../java/org/apache/juneau/xml/package.html | 4 +- .../main/javadoc/doc-files/NewExamplesPage.png | Bin 0 -> 426946 bytes juneau-core/src/main/javadoc/overview.html | 221 +++++++++--- .../juneau/examples/rest/AtomFeedResource.java | 14 +- .../examples/rest/CodeFormatterResource.java | 57 ++- .../juneau/examples/rest/DirectoryResource.java | 4 +- .../examples/rest/DockerRegistryResource.java | 9 +- .../juneau/examples/rest/FileSpaceResource.java | 8 +- .../examples/rest/HelloWorldResource.java | 13 +- .../examples/rest/JsonSchemaResource.java | 13 +- .../examples/rest/MethodExampleResource.java | 9 +- .../juneau/examples/rest/PhotosResource.java | 41 ++- .../examples/rest/RequestEchoResource.java | 12 +- .../juneau/examples/rest/RootResources.java | 21 +- .../examples/rest/SampleRemoteableServlet.java | 13 +- .../juneau/examples/rest/SqlQueryResource.java | 15 +- .../examples/rest/SystemPropertiesResource.java | 155 ++++---- .../juneau/examples/rest/TempDirResource.java | 9 +- .../examples/rest/TumblrParserResource.java | 15 +- .../examples/rest/UrlEncodedFormResource.java | 9 +- .../rest/addressbook/AddressBookResource.java | 49 ++- .../examples/rest/CodeFormatterResource.html | 68 ---- .../juneau/examples/rest/RootResourcesTest.java | 14 +- .../apache/juneau/microservice/Resource.java | 4 +- .../juneau/microservice/ResourceGroup.java | 4 +- .../juneau/microservice/ResourceJena.java | 4 +- .../microservice/resources/ConfigResource.java | 60 ++-- .../resources/DirectoryResource.java | 4 +- .../microservice/resources/LogsResource.java | 47 ++- .../org/apache/juneau/rest/client/RestCall.java | 5 +- .../juneau/rest/client/RestClientBuilder.java | 8 +- .../org/apache/juneau/rest/client/package.html | 2 +- .../rest/test/HtmlPropertiesResource.java | 103 ++++-- .../apache/juneau/rest/test/NlsResource.java | 76 ++-- .../juneau/rest/test/HtmlPropertiesTest.java | 24 -- .../apache/juneau/rest/test/RestTestcase.java | 2 +- .../java/org/apache/juneau/rest/CallMethod.java | 111 ++++-- .../java/org/apache/juneau/rest/RestConfig.java | 352 ++++++++++++++++-- .../org/apache/juneau/rest/RestContext.java | 200 +++++++++-- .../apache/juneau/rest/RestInfoProvider.java | 37 +- .../org/apache/juneau/rest/RestRequest.java | 73 +--- .../org/apache/juneau/rest/RestResponse.java | 355 +++++++++++++++++-- .../apache/juneau/rest/RestServletDefault.java | 11 +- .../apache/juneau/rest/annotation/HtmlDoc.java | 339 ++++++++++++++++++ .../juneau/rest/annotation/MethodSwagger.java | 161 +++++++++ .../juneau/rest/annotation/Parameter.java | 10 +- .../juneau/rest/annotation/ResourceSwagger.java | 177 +++++++++ .../apache/juneau/rest/annotation/Response.java | 22 +- .../juneau/rest/annotation/RestMethod.java | 159 +-------- .../juneau/rest/annotation/RestResource.java | 314 ++++------------ .../rest/jena/RestServletJenaDefault.java | 7 +- .../java/org/apache/juneau/rest/package.html | 41 ++- .../juneau/rest/response/DefaultHandler.java | 21 +- .../org/apache/juneau/rest/vars/UrlVar.java | 59 +++ .../org/apache/juneau/rest/vars/WidgetVar.java | 63 ++++ .../rest/widget/ContentTypeLinksWidget.java | 48 +++ .../rest/widget/PoweredByJuneauWidget.java | 35 ++ .../org/apache/juneau/rest/widget/Widget.java | 44 +++ .../org/apache/juneau/rest/styles/devops.css | 151 ++++---- 111 files changed, 3726 insertions(+), 1317 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java index f5ddfdc..05687fa 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java @@ -680,8 +680,8 @@ public class RdfParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public RdfParserBuilder debug(boolean value) { - super.debug(value); + public RdfParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java index 6bc1a50..f254734 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java @@ -855,8 +855,8 @@ public class RdfSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public RdfSerializerBuilder debug(boolean value) { - super.debug(value); + public RdfSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html index c3073ec..c81d3fd 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html @@ -1064,7 +1064,9 @@ messages=<js>"nls/AddressBookResource"</js>, title=<js>"$L{title}"</js>, description=<js>"$L{description}"</js>, - pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>, + htmldoc=<ja>@HtmlDoc</ja>( + links=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js> + ), properties={ <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), <ja>@Property</ja>(name=RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java index f1fb525..5c67e6d 100644 --- a/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java @@ -1406,12 +1406,11 @@ public abstract class CoreObjectBuilder { * <li>This is equivalent to calling <code>property(<jsf>BEAN_debug</jsf>, value)</code>. * </ul> * - * @param value The new value for this property. * @return This object (for method chaining). * @see BeanContext#BEAN_debug */ - public CoreObjectBuilder debug(boolean value) { - return property(BEAN_debug, value); + public CoreObjectBuilder debug() { + return property(BEAN_debug, true); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java index 8b057ed..3f6fe6f 100644 --- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java @@ -376,11 +376,16 @@ public class ObjectMap extends LinkedHashMap<String,Object> { * @param def The default value if the entry doesn't exist. * @return The value, or the default value if the entry doesn't exist. */ + @SuppressWarnings("unchecked") public <T> T get(Class<T> type, String key, T def) { Object o = get(key); if (o == null) return def; - T t = session.convertToType(o, type); + T t = null; + if (session != null) + t = session.convertToType(o, type); + else if (ClassUtils.isParentClass(type, o.getClass())) + t = (T)o; if (t == null) return def; return t; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java index dc5f064..9e2a33c 100644 --- a/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java +++ b/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java @@ -645,6 +645,40 @@ public final class PropertyStore { } /** + * Returns a property value either cast to the specified type, or a new instance of the specified type. + * <p> + * It's assumed that the current property value is either an instance of that type, or a <code>Class</code> that's + * a subclass of the type to be instantiated. + * + * @param name The full name of the property (e.g. <js>"BeanContext.sortProperties"</js>) + * @param type The class type to convert the property value to. + * @param def The type to instantiate if the property is not set. + * @param args The arguments to pass to the default type constructor. + * + * @return The property either cast to the specified type, or instantiated from a <code>Class</code> object. + * @throws ConfigException If property has a value that cannot be converted to a boolean. + */ + @SuppressWarnings("unchecked") + public <T> T getTypedProperty(String name, Class<T> type, Class<? extends T> def, Object...args) { + rl.lock(); + try { + Object o = null; + PropertyMap pm = getPropertyMap(prefix(name)); + if (pm != null) + o = pm.get(name, type, null); + if (o == null && def != null) + o = ClassUtils.newInstance(type, def, args); + if (o == null) + return null; + if (ClassUtils.isParentClass(type, o.getClass())) + return (T)o; + throw new FormattedRuntimeException("Invalid object of type {0} found in call to PropertyStore.getTypeProperty({1},{2},{3},...)", o.getClass(), name, type, def); + } finally { + rl.unlock(); + } + } + + /** * Returns a property value converted to a {@link LinkedHashMap} with the specified * key and value types. * http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java index a33f9d6..6124708 100644 --- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java @@ -408,8 +408,8 @@ public class CsvParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public CsvParserBuilder debug(boolean value) { - super.debug(value); + public CsvParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java index e752a82..098e9df 100644 --- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java @@ -493,8 +493,8 @@ public class CsvSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public CsvSerializerBuilder debug(boolean value) { - super.debug(value); + public CsvSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html index 8353a46..1551244 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html +++ b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/package.html @@ -407,7 +407,9 @@ path=<js>"/jsonSchema"</js>, messages=<js>"nls/JsonSchemaResource"</js>, title=<js>"Sample JSON-Schema document"</js>, - pageLinks=<js>"{options:'?method=OPTIONS'}"</js> + htmldoc=<ja>@HtmlDoc</ja>( + links=<js>"{options:'?method=OPTIONS'}"</js> + ) ) <jk>public class</jk> JsonSchemaResource <jk>extends</jk> RestServletJenaDefault { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java index 4f4de06..2d9a8ed 100644 --- a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java @@ -95,7 +95,7 @@ public class EncoderGroupBuilder { public EncoderGroup build() { List<Encoder> l = new ArrayList<Encoder>(); for (Object e : encoders) - l.add(e instanceof Class ? newInstance(Encoder.class, (Class<?>)e) : (Encoder)e); + l.add(newInstance(Encoder.class, e)); Collections.reverse(l); return new EncoderGroup(l.toArray(new Encoder[l.size()])); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlBeanPropertyMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlBeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlBeanPropertyMeta.java index 63ecbb4..ce0be74 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlBeanPropertyMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlBeanPropertyMeta.java @@ -14,6 +14,7 @@ package org.apache.juneau.html; import org.apache.juneau.*; import org.apache.juneau.html.annotation.*; +import org.apache.juneau.internal.*; /** * Metadata on bean properties specific to the HTML serializers and parsers pulled from the {@link Html @Html} annotation on the bean property. @@ -45,7 +46,7 @@ public final class HtmlBeanPropertyMeta extends BeanPropertyMetaExtended { this.noTables = b.noTables; this.noTableHeaders = b.noTableHeaders; this.asPlainText = b.asPlainText; - this.render = b.render.newInstance(); + this.render = ClassUtils.newInstance(HtmlRender.class, b.render); this.link = b.link; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlClassMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlClassMeta.java index 0ea336e..5442a2d 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlClassMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlClassMeta.java @@ -23,6 +23,7 @@ public class HtmlClassMeta extends ClassMetaExtended { private final Html html; private final boolean asXml, noTables, noTableHeaders, asPlainText; + private final HtmlRender<?> render; /** * Constructor. @@ -37,11 +38,13 @@ public class HtmlClassMeta extends ClassMetaExtended { noTables = html.noTables(); noTableHeaders = html.noTableHeaders(); asPlainText = html.asPlainText(); + render = ClassUtils.newInstance(HtmlRender.class, html.render()); } else { asXml = false; noTables = false; noTableHeaders = false; asPlainText = false; + render = null; } } @@ -89,4 +92,13 @@ public class HtmlClassMeta extends ClassMetaExtended { public boolean isNoTableHeaders() { return noTableHeaders; } + + /** + * Returns the {@link Html#render()} annotation defined on the class. + * + * @return The value of the {@link Html#render()} annotation. + */ + public HtmlRender<?> getRender() { + return render; + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java index b51c8d6..65c980a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java @@ -17,7 +17,6 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; -import org.apache.juneau.dto.*; import org.apache.juneau.http.*; import org.apache.juneau.serializer.*; @@ -47,10 +46,6 @@ import org.apache.juneau.serializer.*; @SuppressWarnings("hiding") public class HtmlDocSerializer extends HtmlStrippedDocSerializer { - // Properties defined in RestServletProperties - private static final String - REST_method = "RestServlet.method"; - /** Default serializer, all default settings. */ public static final HtmlDocSerializer DEFAULT = new HtmlDocSerializer(PropertyStore.create()); @@ -81,89 +76,25 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer { HtmlDocSerializerSession s = (HtmlDocSerializerSession)session; HtmlWriter w = s.getWriter(); - UriResolver uriResolver = s.getUriResolver(); - - boolean isOptionsPage = session.getProperty(REST_method, "").equalsIgnoreCase("OPTIONS"); + HtmlDocTemplate t = s.getTemplate(); - // Render the header. w.sTag("html").nl(); - w.sTag("head").nl(); - - String cssUrl = s.getCssUrl(); - if (cssUrl == null) - cssUrl = "servlet:/style.css"; - cssUrl = uriResolver.resolve(cssUrl); - - w.oTag(1, "style") - .attr("type", "text/css") - .appendln(">") - .append(2, "@import ").q().append(cssUrl).q().appendln(";"); - if (s.isNoWrap()) - w.appendln("\n* {white-space:nowrap;}"); - if (s.getCssImports() != null) - for (String cssImport : s.getCssImports()) - w.append(2, "@import ").q().append(cssImport).q().appendln(";"); - w.eTag(1, "style").nl(); - w.eTag("head").nl(); - w.sTag("body").nl(); - // Write the title of the page. - String title = s.getTitle(); - if (title == null && isOptionsPage) - title = "Options"; - String description = s.getText(); - if (title != null) - w.oTag(1, "h3").attr("class", "title").append('>').text(title).eTag("h3").nl(); - if (description != null) - w.oTag(1, "h5").attr("class", "description").append('>').text(description).eTag("h5").nl(); - - // Write the action links that render above the results. - List<Link> actions = new LinkedList<Link>(); - - // If this is an OPTIONS request, provide a 'back' link to return to the GET request page. - if (! isOptionsPage) { - Map<String,String> htmlLinks = s.getLinks(); - if (htmlLinks != null) { - for (Map.Entry<String,String> e : htmlLinks.entrySet()) { - String uri = uriResolver.resolve(e.getValue()); - actions.add(new Link(e.getKey(), uri)); - } - } - } - - if (actions.size() > 0) { - w.oTag(1, "p").attr("class", "links").append('>').nl(); - for (Iterator<Link> i = actions.iterator(); i.hasNext();) { - Link h = i.next(); - w.oTag(2, "a").attr("class", "link").attr("href", h.getHref(), true).append('>').append(h.getName()).eTag("a").nl(); - if (i.hasNext()) - w.append(3, " - ").nl(); - } - w.eTag(1, "p").nl(); - } - - s.indent = 3; - - // To allow for page formatting using CSS, we encapsulate the data inside two div tags: - // <div class='outerdata'><div class='data' id='data'>...</div></div> - w.oTag(1, "div").attr("class","outerdata").append('>').nl(); - w.oTag(2, "div").attr("class","data").attr("id", "data").append('>').nl(); - if (isEmptyList(o)) - w.oTag(3, "p").append('>').append("no results").eTag("p"); - else - super.doSerialize(s, o); - w.eTag(2, "div").nl(); - w.eTag(1, "div").nl(); - - w.eTag("body").nl().eTag("html").nl(); + w.sTag(1, "head").nl(); + t.head(s, w, this, o); + w.eTag(1, "head").nl(); + w.sTag(1, "body").nl(); + t.body(s, w, this, o); + w.eTag(1, "body").nl(); + w.eTag("html").nl(); } - private static boolean isEmptyList(Object o) { - if (o == null) - return false; - if (o instanceof Collection && ((Collection<?>)o).size() == 0) - return true; - if (o.getClass().isArray() && Array.getLength(o) == 0) - return true; - return false; + /** + * Calls the parent {@link #doSerialize(SerializerSession, Object)} method which invokes just the HTML serializer. + * @param session The serializer session. + * @param o The object being serialized. + * @throws Exception + */ + public void parentSerialize(SerializerSession session, Object o) throws Exception { + super.doSerialize(session, o); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java index f2dc494..3d7616a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java @@ -39,11 +39,12 @@ import org.apache.juneau.*; * <p class='bcode'> * <ja>@RestResource</ja>( * messages=<js>"nls/AddressBookResource"</js>, - * title=<js>"$L{title}"</js>, <jc>// or pageTitle</jc> - * description=<js>"$L{description}"</js>, <jc>// or pageText</jc> - * pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js> + * htmldoc=<ja>@HtmlDoc</ja>( + * title=<js>"$L{title}"</js>, + * description=<js>"$L{description}"</js>, + * links=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js> + * ) * ) - * <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault { * </p> * * <p> @@ -101,12 +102,23 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { * <p> * Shortcuts on <ja>@RestResource</ja> are also provided for this setting: * <p class='bcode'> + * <jc>// Example if you want the swagger doc and HTML doc to share the same title.</jc> * <ja>@RestResource</ja>( * messages=<js>"nls/AddressBookResource"</js>, - * title=<js>"My title"</js>, <jc>// or pageTitle</jc> + * title=<js>"My title"</js> + * ) + * + * <jc>// Example if you want the swagger doc and HTML doc to share the same title.</jc> + * <ja>@RestResource</ja>( + * messages=<js>"nls/AddressBookResource"</js>, + * title=<js>"My title in Swagger"</js>, + * htmldoc=<ja>@HtmlDoc</ja>( + * title=<js>"My title in HTML"</js> + * ) * ) - * <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault { * </p> + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. */ public static final String HTMLDOC_title = "HtmlSerializer.title"; @@ -147,14 +159,54 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { * <p> * Shortcuts on <ja>@RestResource</ja> are also provided for this setting: * <p class='bcode'> + * <jc>// Example if you want the swagger doc and HTML doc to share the same description.</jc> * <ja>@RestResource</ja>( * messages=<js>"nls/AddressBookResource"</js>, - * description=<js>"My description"</js>, <jc>// or pageText</jc> + * description=<js>"My description"</js> + * ) + * + * <jc>// Example if you want the swagger doc and HTML doc to share the same description.</jc> + * <ja>@RestResource</ja>( + * messages=<js>"nls/AddressBookResource"</js>, + * description=<js>"My description in Swagger"</js>, + * htmldoc=<ja>@HtmlDoc</ja>( + * description=<js>"My description in HTML"</js> + * ) + * ) + * </p> + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. + */ + public static final String HTMLDOC_description = "HtmlSerializer.description"; + + /** + * <b>Configuration property:</b> Header section contents. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.header"</js> + * <li><b>Data type:</b> <code>String</code> + * <li><b>Default:</b> <jk>null</jk> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Allows you to override the contents of the header section on the HTML page. + * The header section normally contains the title and description at the top of the page. + * <p> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * nav=<js>"<:p class='special-navigation'>This is my special navigation content<:/p>"</js> + * ) * ) - * <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault { * </p> + * <p> + * When this property is specified, the {@link #HTMLDOC_title} and {@link #HTMLDOC_description} properties are ignored. + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. */ - public static final String HTMLDOC_text = "HtmlSerializer.description"; + public static final String HTMLDOC_header = "HtmlDocSerializer.header"; /** * <b>Configuration property:</b> Page links. @@ -184,7 +236,6 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { * </p> * <p class='bcode'> * <ja>@RestResource</ja>( - * messages=<js>"nls/AddressBookResource"</js>, * properties={ * <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>) * } @@ -199,8 +250,9 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { * A shortcut on <ja>@RestResource</ja> is also provided for this setting: * <p class='bcode'> * <ja>@RestResource</ja>( - * messages=<js>"nls/AddressBookResource"</js>, - * pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js> + * htmldoc=@HtmlDoc( + * links=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js> + * ) * ) * <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault { * </p> @@ -213,6 +265,133 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { public static final String HTMLDOC_links_put = "HtmlDocSerializer.links.map.put"; /** + * <b>Configuration property:</b> Nav section contents. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.nav"</js> + * <li><b>Data type:</b> <code>String</code> + * <li><b>Default:</b> <jk>null</jk> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Allows you to override the contents of the nav section on the HTML page. + * The nav section normally contains the page links at the top of the page. + * <p> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * nav=<js>"<:p class='special-navigation'>This is my special navigation content<:/p>"</js> + * ) + * ) + * </p> + * <p> + * When this property is specified, the {@link #HTMLDOC_links} property is ignored. + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. + */ + public static final String HTMLDOC_nav = "HtmlDocSerializer.nav"; + + /** + * <b>Configuration property:</b> Aside section contents. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.aside"</js> + * <li><b>Data type:</b> <code>String</code> + * <li><b>Default:</b> <jk>null</jk> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Allows you to specifigy the contents of the aside section on the HTML page. + * The aside section floats on the right of the page for providing content supporting the serialized content of + * the page. + * <p> + * By default, the aside section is empty. + * <p> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * aside=<js>"<:ul><:li>Item 1<:li>Item 2<:li>Item 3<:/ul>"</js> + * ) + * ) + * </p> + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. + */ + public static final String HTMLDOC_aside = "HtmlDocSerializer.aside"; + + /** + * <b>Configuration property:</b> Footer section contents. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.footer"</js> + * <li><b>Data type:</b> <code>String</code> + * <li><b>Default:</b> <jk>null</jk> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Allows you to specify the contents of the footer section on the HTML page. + * <p> + * By default, the footer section is empty. + * <p> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * footer=<js>"<b>This interface is great!</b>"</js> + * ) + * ) + * </p> + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. + */ + public static final String HTMLDOC_footer = "HtmlDocSerializer.footer"; + + /** + * <b>Configuration property:</b> No-results message. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.noResultsMessage"</js> + * <li><b>Data type:</b> <code>String</code> + * <li><b>Default:</b> <js>"<p>no results</p>"</js> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Allows you to specify the string message used when trying to serialize an empty array or empty list. + * <p> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=<ja>@HtmlDoc</ja>( + * =<js>"<b>This interface is great!</b>"</js> + * ) + * ) + * </p> + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. + */ + public static final String HTMLDOC_noResultsMessage = "HtmlDocSerializer.noResultsMessage"; + + /** + * <b>Configuration property:</b> Prevent word wrap on page. + * <p> + * <ul> + * <li><b>Name:</b> <js>"HtmlDocSerializer.nowrap"</js> + * <li><b>Data type:</b> <code>Boolean</code> + * <li><b>Default:</b> <jk>false</jk> + * <li><b>Session-overridable:</b> <jk>true</jk> + * </ul> + * <p> + * Adds <js>"* {white-space:nowrap}"</js> to the CSS instructions on the page to prevent word wrapping. + */ + public static final String HTMLDOC_nowrap = "HtmlDocSerializer.nowrap"; + + /** * <b>Configuration property:</b> Stylesheet URL. * <p> * <ul> @@ -226,46 +405,80 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { * <p> * If not specified, defaults to the built-in stylesheet located at <js>"style.css"</js>. * Note that this stylesheet is controlled by the <code><ja>@RestResource</ja>.stylesheet()</code> annotation. + * <p> + * A value of <js>"NONE"</js> can be used to represent no value to differentiate it from an empty string. */ public static final String HTMLDOC_cssUrl = "HtmlDocSerializer.cssUrl"; /** - * <b>Configuration property:</b> CSS imports. + * <b>Configuration property:</b> CSS code. * <p> * <ul> - * <li><b>Name:</b> <js>"HtmlDocSerializer.cssImports.list"</js> + * <li><b>Name:</b> <js>"HtmlDocSerializer.css.list"</js> * <li><b>Data type:</b> <code>List<String></code> * <li><b>Default:</b> empty list * <li><b>Session-overridable:</b> <jk>true</jk> * </ul> * <p> - * Imports the specified CSS page URLs into the page. + * Adds the specified CSS instructions to the HTML page. + * + * <h5 class='section'>Example:</h5> + * </p> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * properties={ + * <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_css</jsf>, value=<js>"h3 { color: red; }\nh5 { font-weight: bold; }"</js>) + * } + * ) + * </p> + * A shortcut on <ja>@RestResource</ja> is also provided for this setting: + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=@HtmlDoc( + * css=<js>"h3 { color: red; }\nh5 { font-weight: bold; }"</js> + * ) + * ) + * </p> */ - public static final String HTMLDOC_cssImports = "HtmlDocSerializer.cssImports.list"; + public static final String HTMLDOC_css = "HtmlDocSerializer.css.list"; /** - * <b>Configuration property:</b> Add to the {@link #HTMLDOC_cssImports} property. + * <b>Configuration property:</b> Add to the {@link #HTMLDOC_css} property. */ - public static final String HTMLDOC_cssImports_add = "HtmlDocSerializer.cssImports.list.add"; + public static final String HTMLDOC_css_add = "HtmlDocSerializer.css.list.add"; /** - * <b>Configuration property:</b> Prevent word wrap on page. + * <b>Configuration property:</b> HTML document template. * <p> * <ul> - * <li><b>Name:</b> <js>"HtmlDocSerializer.nowrap"</js> - * <li><b>Data type:</b> <code>Boolean</code> - * <li><b>Default:</b> <jk>false</jk> + * <li><b>Name:</b> <js>"HtmlDocSerializer.template"</js> + * <li><b>Data type:</b> <code>Class<? <jk>extends</jk> HtmlDocTemplate></code> or {@link HtmlDocTemplate} + * <li><b>Default:</b> <code>HtmlDocTemplateBasic.<jk>class</jk></code> * <li><b>Session-overridable:</b> <jk>true</jk> * </ul> * <p> - * Adds <js>"* {white-space:nowrap}"</js> to the style header to prevent word wrapping. + * Specifies the template to use for serializing the page. + * <p> + * By default, the {@link HtmlDocTemplateBasic} class is used to construct the contents of the HTML page, but + * can be overridden with your own custom implementation class. + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <ja>@RestResource</ja>( + * htmldoc=@HtmlDoc( + * template=MySpecialDocTemplate.<jk>class</jk> + * ) + * ) + * </p> */ - public static final String HTMLDOC_nowrap = "HtmlDocSerializer.nowrap"; + public static final String HTMLDOC_template = "HtmlDocSerializer.template"; + - final String[] cssImports; + final String[] css; final Map<String,String> links; - final String title, text, cssUrl; + final String title, description, header, nav, aside, footer, cssUrl, noResultsMessage; final boolean nowrap; + final HtmlDocTemplate template; /** * Constructor. @@ -276,24 +489,36 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext { */ public HtmlDocSerializerContext(PropertyStore ps) { super(ps); - cssImports = ps.getProperty(HTMLDOC_cssImports, String[].class, new String[0]); + css = ps.getProperty(HTMLDOC_css, String[].class, new String[0]); title = ps.getProperty(HTMLDOC_title, String.class, null); - text = ps.getProperty(HTMLDOC_text, String.class, null); + description = ps.getProperty(HTMLDOC_description, String.class, null); + header = ps.getProperty(HTMLDOC_header, String.class, null); + nav = ps.getProperty(HTMLDOC_nav, String.class, null); + aside = ps.getProperty(HTMLDOC_aside, String.class, null); + footer = ps.getProperty(HTMLDOC_footer, String.class, null); cssUrl = ps.getProperty(HTMLDOC_cssUrl, String.class, null); nowrap = ps.getProperty(HTMLDOC_nowrap, boolean.class, false); - links = ps.getMap(HTMLDOC_links, String.class, String.class, Collections.<String,String>emptyMap()); + links = ps.getMap(HTMLDOC_links, String.class, String.class, null); + noResultsMessage = ps.getProperty(HTMLDOC_noResultsMessage, String.class, "<p>no results</p>"); + template = ps.getTypedProperty(HTMLDOC_template, HtmlDocTemplate.class, HtmlDocTemplateBasic.class); } @Override /* Context */ public ObjectMap asMap() { return super.asMap() .append("HtmlDocSerializerContext", new ObjectMap() - .append("cssImports", cssImports) + .append("cssImports", css) .append("title", title) - .append("text", text) + .append("text", description) + .append("header", header) + .append("nav", nav) + .append("links", links) + .append("aside", aside) + .append("footer", footer) .append("cssUrl", cssUrl) .append("nowrap", nowrap) - .append("links", links) + .append("template", template) + .append("noResultsMessage", noResultsMessage) ); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java index c9c69b7..5cb8d91 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java @@ -20,6 +20,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.http.*; +import org.apache.juneau.internal.*; import org.apache.juneau.json.*; import org.apache.juneau.serializer.*; @@ -32,10 +33,11 @@ import org.apache.juneau.serializer.*; */ public final class HtmlDocSerializerSession extends HtmlSerializerSession { - private final String title, text, cssUrl; - private final String[] cssImports; + private final String title, description, header, nav, aside, footer, cssUrl, noResultsMessage; + private final String[] css; private final Map<String,String> links; private final boolean nowrap; + private final HtmlDocTemplate template; /** * Create a new session using properties specified in the context. @@ -59,73 +61,139 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession { super(ctx, op, output, javaMethod, locale, timeZone, mediaType, uriContext); if (op == null || op.isEmpty()) { title = ctx.title; - text = ctx.text; + description = ctx.description; + header = ctx.header; + nav = ctx.nav; + aside = ctx.aside; + footer = ctx.footer; links = ctx.links; cssUrl = ctx.cssUrl; - cssImports = ctx.cssImports; + css = ctx.css; nowrap = ctx.nowrap; + noResultsMessage = ctx.noResultsMessage; + template = ClassUtils.newInstance(HtmlDocTemplate.class, ctx.template); } else { title = op.getString(HTMLDOC_title, ctx.title); - text = op.getString(HTMLDOC_text, ctx.text); - links = new LinkedHashMap(op.getMap(HTMLDOC_links, ctx.links)); + description = op.getString(HTMLDOC_description, ctx.description); + header = op.getString(HTMLDOC_header, ctx.nav); + nav = op.getString(HTMLDOC_nav, ctx.nav); + aside = op.getString(HTMLDOC_aside, ctx.aside); + footer = op.getString(HTMLDOC_footer, ctx.footer); + Map m = op.getMap(HTMLDOC_links, ctx.links); + links = ObjectUtils.isEmpty(m) ? null : new LinkedHashMap(m); cssUrl = op.getString(HTMLDOC_cssUrl, ctx.cssUrl); - cssImports = split(op.getString(HTMLDOC_cssImports, null), ','); + css = split(op.getString(HTMLDOC_css, null), ','); nowrap = op.getBoolean(HTMLDOC_cssUrl, ctx.nowrap); + noResultsMessage = op.getString(HTMLDOC_noResultsMessage, ctx.noResultsMessage); + template = ClassUtils.newInstance(HtmlDocTemplate.class, op.get(HTMLDOC_template, ctx.template)); } } /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_cssUrl} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_cssUrl} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. + */ + public final String getCssUrl() { + return cssUrl; + } + + /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_css} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_css} setting value in this context. + * <jk>null</jk> if not specified. Never an empty array. + */ + public final String[] getCss() { + return css; + } + + /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_nowrap} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_nowrap} setting value in this context. + */ + public final boolean isNoWrap() { + return nowrap; + } + + /** * Returns the {@link HtmlDocSerializerContext#HTMLDOC_title} setting value in this context. - * * @return The {@link HtmlDocSerializerContext#HTMLDOC_title} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. */ public final String getTitle() { return title; } /** - * Returns the {@link HtmlDocSerializerContext#HTMLDOC_text} setting value in this context. - * - * @return The {@link HtmlDocSerializerContext#HTMLDOC_text} setting value in this context. + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_description} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_description} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. + */ + public final String getDescription() { + return description; + } + + /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_header} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_header} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. */ - public final String getText() { - return text; + public final String getHeader() { + return header; } /** * Returns the {@link HtmlDocSerializerContext#HTMLDOC_links} setting value in this context. - * * @return The {@link HtmlDocSerializerContext#HTMLDOC_links} setting value in this context. + * <jk>null</jk> if not specified. Never an empty map. */ public final Map<String,String> getLinks() { return links; } /** - * Returns the {@link HtmlDocSerializerContext#HTMLDOC_cssUrl} setting value in this context. - * - * @return The {@link HtmlDocSerializerContext#HTMLDOC_cssUrl} setting value in this context. + * Returns the template to use for generating the HTML page. + * @return The HTML page generator. + * Never <jk>null</jk>. */ - public final String getCssUrl() { - return cssUrl; + public final HtmlDocTemplate getTemplate() { + return template; } /** - * Returns the {@link HtmlDocSerializerContext#HTMLDOC_cssImports} setting value in this context. - * - * @return The {@link HtmlDocSerializerContext#HTMLDOC_cssImports} setting value in this context. + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_nav} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_nav} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. */ - public final String[] getCssImports() { - return cssImports; + public final String getNav() { + return nav; } /** - * Returns the {@link HtmlDocSerializerContext#HTMLDOC_nowrap} setting value in this context. - * - * @return The {@link HtmlDocSerializerContext#HTMLDOC_nowrap} setting value in this context. + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_aside} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_aside} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. */ - public final boolean isNoWrap() { - return nowrap; + public final String getAside() { + return aside; + } + + /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_footer} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_footer} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. + */ + public final String getFooter() { + return footer; + } + + /** + * Returns the {@link HtmlDocSerializerContext#HTMLDOC_noResultsMessage} setting value in this context. + * @return The {@link HtmlDocSerializerContext#HTMLDOC_noResultsMessage} setting value in this context. + * <jk>null</jk> if not specified. Never an empty string. + */ + public final String getNoResultsMessage() { + return noResultsMessage; } @Override /* XmlSerializerSession */ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplate.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplate.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplate.java new file mode 100644 index 0000000..f850b6b --- /dev/null +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplate.java @@ -0,0 +1,164 @@ +// *************************************************************************************************************************** +// * 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.html; + +/** + * Defines the interface for rendering the contents of an HTML page produced by the {@link HtmlDocSerializer} serializer. + * <p> + * The HTML doc serializer produces the following document structure with the typical contents: + * <p class='bcode'> + * <xt><html> + * <head> + * <style <xa>type</xa>=<xs>'text/css'</xs>> + * <xv>CSS styles and links to stylesheets</xv> + * </style> + * </head> + * <body> + * <header> + * <xv>Page title and description</xv> + * </header> + * <nav> + * <xv>Page links</xv> + * </nav> + * <aside> + * <xv>Side-bar page links</xv> + * </aside> + * <article> + * <xv>Contents of serialized object</xv> + * </article> + * <footer> + * <xv>Footer message</xv> + * </footer> + * </body> + * </html></xt> + * </p> + * <p> + * This interface allows you to control how these sections get rendered. + */ +public interface HtmlDocTemplate { + + /** + * Renders the contents of the <code><xt><head></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void head(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><head></xt> / <xt><style</xt> <xa>type</xa>=<xs>"text/css"</xs><xt>></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void css(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void body(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt> / <xt><header></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void header(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt> / <xt><nav></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void nav(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt> / <xt><article></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void article(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt> / <xt><aside></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void aside(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Renders the contents of the <code><xt><body></xt> / <xt><footer></xt></code> element. + * @param session The current serializer session. + * @param w The writer being written to. + * @param s The serializer calling this method. + * @param o The object being serialized. + * @throws Exception Any exception can be thrown. + */ + public void footer(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception; + + /** + * Returns <jk>true</jk> if this page should render a <code><xt><head></xt> / <xt><style</xt> <xa>type</xa>=<xs>"text/css"</xs><xt>></xt></code> element. + * @param session The current serializer session. + * @return A boolean flag. + */ + public boolean hasCss(HtmlDocSerializerSession session); + + /** + * Returns <jk>true</jk> if this page should render a <code><xt><body></xt> / <xt>header</xt></code> element. + * @param session The current serializer session. + * @return A boolean flag. + */ + public boolean hasHeader(HtmlDocSerializerSession session); + + /** + * Returns <jk>true</jk> if this page should render a <code><xt><body></xt> / <xt>nav</xt></code> element. + * @param session The current serializer session. + * @return A boolean flag. + */ + public boolean hasNav(HtmlDocSerializerSession session); + + /** + * Returns <jk>true</jk> if this page should render a <code><xt><body></xt> / <xt>aside</xt></code> element. + * @param session The current serializer session. + * @return A boolean flag. + */ + public boolean hasAside(HtmlDocSerializerSession session); + + /** + * Returns <jk>true</jk> if this page should render a <code><xt><body></xt> / <xt>footer</xt></code> element. + * @param session The current serializer session. + * @return A boolean flag. + */ + public boolean hasFooter(HtmlDocSerializerSession session); +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplateBasic.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplateBasic.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplateBasic.java new file mode 100644 index 0000000..6553fdb --- /dev/null +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocTemplateBasic.java @@ -0,0 +1,188 @@ +// *************************************************************************************************************************** +// * 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.html; + +import java.util.Map; + +import org.apache.juneau.internal.*; + +/** + * A basic template for the HTML doc serializer. + * <p> + * This class can be subclassed to customize page rendering. + */ +public class HtmlDocTemplateBasic implements HtmlDocTemplate { + + @Override /* HtmlDocTemplate */ + public void head(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + if (hasCss(session)) { + w.oTag(1, "style").attr("type", "text/css").appendln(">").nl(); + css(session, w, s, o); + w.eTag(1, "style").nl(); + } + } + + @Override /* HtmlDocTemplate */ + public void css(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + + String cssUrl = session.getCssUrl(); + if (cssUrl == null) + cssUrl = "servlet:/style.css"; + cssUrl = session.resolveUri(cssUrl); + + w.append(2, "@import ").q().append(cssUrl).q().appendln(";"); + if (session.isNoWrap()) + w.appendln("\n* {white-space:nowrap;}"); + if (session.getCss() != null) + for (String css : session.getCss()) + w.appendln(css); + } + + @Override /* HtmlDocTemplate */ + public void body(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + + if (hasHeader(session)) { + w.sTag(1, "header").nl(); + header(session, w, s, o); + w.eTag(1, "header").nl(); + } + + if (hasNav(session)) { + w.sTag(1, "nav").nl(); + nav(session, w, s, o); + w.eTag(1, "nav").nl(); + } + + w.sTag(1, "section").nl(); + + w.sTag(2, "article").nl(); + article(session, w, s, o); + w.eTag(2, "article").nl(); + + if (hasAside(session)) { + w.sTag(2, "aside").nl(); + aside(session, w, s, o); + w.eTag(2, "aside").nl(); + } + + w.eTag(1, "section").nl(); + + if (hasFooter(session)) { + w.sTag(1, "footer").nl(); + footer(session, w, s, o); + w.eTag(1, "footer").nl(); + } + } + + @Override /* HtmlDocTemplate */ + public void header(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + // Write the title of the page. + String header = session.getHeader(); + if (header != null) { + if (exists(header)) + w.append(header).nl(); + } else { + String title = session.getTitle(); + String description = session.getDescription(); + if (exists(title)) + w.oTag(1, "h3").attr("class", "title").append('>').text(title).eTag("h3").nl(); + if (exists(description)) + w.oTag(1, "h5").attr("class", "description").append('>').text(description).eTag("h5").nl(); + } + } + + + @Override /* HtmlDocTemplate */ + public void nav(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + String nav = session.getNav(); + if (nav != null) { + if (exists(nav)) + w.append(nav).nl(); + } else { + Map<String,String> htmlLinks = session.getLinks(); + boolean first = true; + if (htmlLinks != null) { + for (Map.Entry<String,String> e : htmlLinks.entrySet()) { + if (! first) + w.append(3, " - ").nl(); + first = false; + w.oTag("a").attr("class", "link").attr("href", session.resolveUri(e.getValue()), true).cTag().text(e.getKey(), true).eTag("a"); + } + } + } + } + + @Override /* HtmlDocTemplate */ + public void aside(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + String aside = session.getAside(); + if (exists(aside)) + w.append(aside); + } + + @Override /* HtmlDocTemplate */ + public void article(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + // To allow for page formatting using CSS, we encapsulate the data inside two div tags: + // <div class='outerdata'><div class='data' id='data'>...</div></div> + w.oTag(3, "div").attr("class","outerdata").append('>').nl(); + w.oTag(4, "div").attr("class","data").attr("id", "data").append('>').nl(); + + if (o == null) { + w.append("<null/>").nl(); + } else if (ObjectUtils.isEmpty(o)){ + String m = session.getNoResultsMessage(); + if (exists(m)) + w.append(m).nl(); + } else { + s.parentSerialize(session, o); + } + + w.eTag(4, "div").nl(); + w.eTag(3, "div").nl(); + } + + @Override /* HtmlDocTemplate */ + public void footer(HtmlDocSerializerSession session, HtmlWriter w, HtmlDocSerializer s, Object o) throws Exception { + String footer = session.getFooter(); + if (exists(footer)) + w.append(footer); + } + + @Override /* HtmlDocTemplate */ + public boolean hasCss(HtmlDocSerializerSession session) { + return true; + } + + @Override /* HtmlDocTemplate */ + public boolean hasHeader(HtmlDocSerializerSession session) { + return exists(session.getHeader()) || exists(session.getTitle()) || exists(session.getDescription()); + } + + @Override /* HtmlDocTemplate */ + public boolean hasNav(HtmlDocSerializerSession session) { + return exists(session.getNav()) || session.getLinks() != null; + } + + @Override /* HtmlDocTemplate */ + public boolean hasAside(HtmlDocSerializerSession session) { + return exists(session.getAside()); + } + + @Override /* HtmlDocTemplate */ + public boolean hasFooter(HtmlDocSerializerSession session) { + return exists(session.getFooter()); + } + + private static boolean exists(String s) { + return s != null && ! "NONE".equals(s); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java index 4c2c283..7418e1b 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java @@ -437,8 +437,8 @@ public class HtmlParserBuilder extends XmlParserBuilder { } @Override /* CoreObjectBuilder */ - public HtmlParserBuilder debug(boolean value) { - super.debug(value); + public HtmlParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlRender.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlRender.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlRender.java index b30c67e..b31fea7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlRender.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlRender.java @@ -118,7 +118,7 @@ import org.apache.juneau.serializer.*; * </p> * @param <T> The bean property type. */ -public class HtmlRender<T> { +public abstract class HtmlRender<T> { /** * Returns the CSS style of the element containing the bean property value. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java index 0bb39b8..f17f7d7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java @@ -424,6 +424,8 @@ public class HtmlSerializer extends XmlSerializer { HtmlBeanPropertyMeta hbpMeta = pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class); String link = hbpMeta.getLink(); HtmlRender render = hbpMeta.getRender(); + if (render == null) + render = cMeta.getExtendedMeta(HtmlClassMeta.class).getRender(); String key = p.getName(); Object value = p.getValue(); @@ -437,7 +439,7 @@ public class HtmlSerializer extends XmlSerializer { out.sTag(i+1, "tr").nl(); out.sTag(i+2, "td").text(key).eTag("td").nl(); out.oTag(i+2, "td"); - String style = render.getStyle(session, value); + String style = render == null ? null : render.getStyle(session, value); if (style != null) out.attr("style", style); out.cTag(); @@ -445,7 +447,7 @@ public class HtmlSerializer extends XmlSerializer { try { if (link != null) out.oTag(i+3, "a").attrUri("href", m.resolveVars(link)).cTag(); - ContentResult cr = serializeAnything(session, out, render.getContent(session, value), cMeta, key, 2, pMeta, false); + ContentResult cr = serializeAnything(session, out, render == null ? value : render.getContent(session, value), cMeta, key, 2, pMeta, false); if (cr == CR_NORMAL) out.i(i+2); if (link != null) @@ -548,17 +550,22 @@ public class HtmlSerializer extends XmlSerializer { BeanPropertyMeta pMeta = p.getMeta(); HtmlBeanPropertyMeta hpMeta = pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class); String link = hpMeta.getLink(); - HtmlRender render = hpMeta.getRender(); Object value = p.getValue(); + ClassMeta<?> cMeta = session.getClassMetaForObject(value); + + HtmlRender render = hpMeta.getRender(); + if (render == null) + render = cMeta.getExtendedMeta(HtmlClassMeta.class).getRender(); + out.oTag(i+2, "td"); - String style = render.getStyle(session, value); + String style = render == null ? null : render.getStyle(session, value); if (style != null) out.attr("style", style); out.cTag(); if (link != null) out.oTag(i+3, "a").attrUri("href", m2.resolveVars(link)).cTag(); - ContentResult cr = serializeAnything(session, out, render.getContent(session, value), pMeta.getClassMeta(), p.getKey().toString(), 2, pMeta, false); + ContentResult cr = serializeAnything(session, out, render == null ? value : render.getContent(session, value), pMeta.getClassMeta(), p.getKey().toString(), 2, pMeta, false); if (cr == CR_NORMAL) out.i(i+2); if (link != null) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java index c2f4112..13aa762 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java @@ -671,8 +671,8 @@ public class HtmlSerializerBuilder extends XmlSerializerBuilder { } @Override /* CoreObjectBuilder */ - public HtmlSerializerBuilder debug(boolean value) { - super.debug(value); + public HtmlSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java index d8648b4..192a73b 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java @@ -347,5 +347,4 @@ public class HtmlWriter extends XmlWriter { super.append(c); return this; } - } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/html/annotation/Html.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/annotation/Html.java b/juneau-core/src/main/java/org/apache/juneau/html/annotation/Html.java index dcfc53c..3ada90e 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/annotation/Html.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/annotation/Html.java @@ -57,7 +57,7 @@ public @interface Html { /** * Associates an {@link HtmlRender} with a bean property for custom HTML rendering of the property. * <p> - * This annotation applies to bean properties only. + * This annotation applies to bean properties and classes. */ @SuppressWarnings("rawtypes") Class<? extends HtmlRender> render() default HtmlRender.class; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/http/MediaType.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/http/MediaType.java b/juneau-core/src/main/java/org/apache/juneau/http/MediaType.java index a11d658..fc6452a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/http/MediaType.java +++ b/juneau-core/src/main/java/org/apache/juneau/http/MediaType.java @@ -32,7 +32,7 @@ import org.apache.juneau.json.*; */ @BeanIgnore @SuppressWarnings("unchecked") -public class MediaType { +public class MediaType implements Comparable<MediaType> { private static final boolean nocache = Boolean.getBoolean("juneau.nocache"); private static final ConcurrentHashMap<String,MediaType> cache = new ConcurrentHashMap<String,MediaType>(); @@ -280,4 +280,9 @@ public class MediaType { public boolean equals(Object o) { return this == o; } + + @Override + public int compareTo(MediaType o) { + return mediaType.compareTo(o.mediaType); + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java index ef46ffc..f4ebf10 100644 --- a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java +++ b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java @@ -301,6 +301,16 @@ public final class ClassUtils { } /** + * Returns <jk>true</jk> if the specified class is abstract. + * + * @param c The class. + * @return <jk>true</jk> if the specified class is abstract. + */ + public static boolean isAbstract(Class<?> c) { + return Modifier.isAbstract(c.getModifiers()); + } + + /** * Returns <jk>true</jk> if the specified method is public. * * @param m The method. @@ -745,20 +755,30 @@ public final class ClassUtils { * * @param c The class to cast to. * @param c2 The class to instantiate. + * Can also be an instance of the class. * @param args The arguments to pass to the constructor. - * @return The new class instance, or <jk>null</jk> if the class was <jk>null</jk>. + * @return The new class instance, or <jk>null</jk> if the class was <jk>null</jk> or is abstract or an interface. * @throws RuntimeException if constructor could not be found or called. */ @SuppressWarnings("unchecked") - public static <T> T newInstance(Class<T> c, Class<?> c2, Object...args) { + public static <T> T newInstance(Class<T> c, Object c2, Object...args) { if (c2 == null) return null; - try { - if (args.length == 0) - return (T)c2.newInstance(); - return (T)c2.getConstructor(getClasses(args)).newInstance(args); - } catch (Exception e) { - throw new RuntimeException("Could not instantiate class " + c.getName(), e); + if (c2 instanceof Class) { + try { + Class<?> c3 = (Class<?>)c2; + if (c3.isInterface() || isAbstract(c3)) + return null; + if (args.length == 0) + return (T)c3.newInstance(); + return (T)c3.getConstructor(getClasses(args)).newInstance(args); + } catch (Exception e) { + throw new FormattedRuntimeException(e, "Could not instantiate class {0}", c.getName()); + } + } else if (isParentClass(c, c2.getClass())) { + return (T)c2; + } else { + throw new FormattedRuntimeException("Object of type {0} found but was expecting {1}.", c2.getClass(), c.getClass()); } } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java index 699b0fc..73f73d4 100644 --- a/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java +++ b/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java @@ -44,6 +44,7 @@ public class ObjectUtils { * <ul> * <li><jk>null</jk> * <li>An empty Collection + * <li>An empty Map * <li>An empty array * <li>An empty CharSequence * <li>An empty String when serialized to a string using {@link Object#toString()}. @@ -58,6 +59,8 @@ public class ObjectUtils { return true; if (o instanceof Collection) return ((Collection)o).isEmpty(); + if (o instanceof Map) + return ((Map)o).isEmpty(); if (o.getClass().isArray()) return (Array.getLength(o) == 0); return o.toString().isEmpty(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java index aa5e448..2052f42 100644 --- a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java @@ -409,8 +409,8 @@ public class JsoParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public JsoParserBuilder debug(boolean value) { - super.debug(value); + public JsoParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java index 1da92e6..bd2e498 100644 --- a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java @@ -493,8 +493,8 @@ public class JsoSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public JsoSerializerBuilder debug(boolean value) { - super.debug(value); + public JsoSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java index 40cfd30..94b3340 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java @@ -409,8 +409,8 @@ public class JsonParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public JsonParserBuilder debug(boolean value) { - super.debug(value); + public JsonParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java index d58aca2..e9ee47f 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java @@ -511,8 +511,8 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder { } @Override /* CoreObjectBuilder */ - public JsonSchemaSerializerBuilder debug(boolean value) { - super.debug(value); + public JsonSchemaSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java index 98ed08c..92adbd4 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java @@ -558,8 +558,8 @@ public class JsonSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public JsonSerializerBuilder debug(boolean value) { - super.debug(value); + public JsonSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/json/package.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/package.html b/juneau-core/src/main/java/org/apache/juneau/json/package.html index 960ea0b..c32bd3c 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/package.html +++ b/juneau-core/src/main/java/org/apache/juneau/json/package.html @@ -1004,7 +1004,9 @@ messages=<js>"nls/AddressBookResource"</js>, title=<js>"$L{title}"</js>, description=<js>"$L{description}"</js>, - pageLinks=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>, + htmldoc=<ja>@HtmlDoc</ja>( + links=<js>"{options:'?method=OPTIONS'}"</js> + ), properties={ <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>), <ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java index 38d2841..de0744c 100644 --- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java @@ -409,8 +409,8 @@ public class MsgPackParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public MsgPackParserBuilder debug(boolean value) { - super.debug(value); + public MsgPackParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java index fc4935f..d0e79b7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java @@ -493,8 +493,8 @@ public class MsgPackSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public MsgPackSerializerBuilder debug(boolean value) { - super.debug(value); + public MsgPackSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java index dbc9d86..b15ab39 100644 --- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java @@ -537,8 +537,8 @@ public class ParserBuilder extends CoreObjectBuilder { } @Override /* CoreObjectBuilder */ - public ParserBuilder debug(boolean value) { - super.debug(value); + public ParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java index 0eb2e92..1731af9 100644 --- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java @@ -860,12 +860,11 @@ public class ParserGroupBuilder { /** * Sets the {@link BeanContext#BEAN_debug} property on all parsers in this group. * - * @param value The new value for this property. * @return This object (for method chaining). * @see BeanContext#BEAN_debug */ - public ParserGroupBuilder debug(boolean value) { - return property(BEAN_debug, value); + public ParserGroupBuilder debug() { + return property(BEAN_debug, true); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java index 9f9177d..3540188 100644 --- a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java @@ -409,8 +409,8 @@ public class PlainTextParserBuilder extends ParserBuilder { } @Override /* CoreObjectBuilder */ - public PlainTextParserBuilder debug(boolean value) { - super.debug(value); + public PlainTextParserBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java index 883053a..8995da2 100644 --- a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java @@ -493,8 +493,8 @@ public class PlainTextSerializerBuilder extends SerializerBuilder { } @Override /* CoreObjectBuilder */ - public PlainTextSerializerBuilder debug(boolean value) { - super.debug(value); + public PlainTextSerializerBuilder debug() { + super.debug(); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/f4812b7c/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java index cf2326b..140d9f8 100644 --- a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java +++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java @@ -55,6 +55,6 @@ public class RemoteMethodArg { this.name = name.isEmpty() ? name2 : name; this.index = index; this.skipIfNE = skipIfNE; - this.serializer = (serializer == PartSerializer.class ? null : newInstance(PartSerializer.class, serializer)); + this.serializer = newInstance(PartSerializer.class, serializer); } }
