http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaProperty.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaProperty.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaProperty.java new file mode 100755 index 0000000..47c6826 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaProperty.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.dto.jsonschema; + +/** + * Represents a JSON property in the JSON-Schema core specification. + * <p> + * Refer to {@link com.ibm.juno.core.dto.jsonschema} for usage information. + * + * @author James Bognar ([email protected]) + */ +public class SchemaProperty extends Schema { + + /** + * Default constructor. + */ + public SchemaProperty() {} + + /** + * Convenience constructor. + * + * @param name The name of this property. + */ + public SchemaProperty(String name) { + setName(name); + } + + /** + * Convenience constructor. + * + * @param name The name of this property. + * @param type The JSON type of this property. + */ + public SchemaProperty(String name, JsonType type) { + setName(name); + setType(type); + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.class new file mode 100755 index 0000000..6bc08cb Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.java new file mode 100755 index 0000000..d611ca8 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaPropertySimpleArray.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.dto.jsonschema; + +/** + * Convenience class for representing a property that's an array of simple types. + * <p> + * An instance of this object is equivalent to calling... + * + * <p class='bcode'> + * SchemaProperty p = <jk>new</jk> SchemaProperty(name) + * .setType(JsonType.<jsf>ARRAY</jsf>) + * .setItems( + * <jk>new</jk> Schema().setType(elementType) + * ); + * </p> + * + * @author James Bognar ([email protected]) + */ +public class SchemaPropertySimpleArray extends SchemaProperty { + + /** + * Constructor. + * + * @param name The name of the schema property. + * @param elementType The JSON type of the elements in the array. + */ + public SchemaPropertySimpleArray(String name, JsonType elementType) { + setName(name); + setType(JsonType.ARRAY); + setItems( + new Schema().setType(elementType) + ); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.class new file mode 100755 index 0000000..3537129 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.java new file mode 100755 index 0000000..9bbbf03 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/SchemaRef.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.dto.jsonschema; + +import java.net.*; + +/** + * Convenience class for representing a schema reference such as <js>"{'$ref':'/url/to/ref'}"</js>. + * <p> + * An instance of this object is equivalent to calling... + * + * <p class='bcode'> + * Schema s = <jk>new</jk> Schema().setRef(uri); + * </p> + * + * @author James Bognar ([email protected]) + */ +public class SchemaRef extends Schema { + + /** + * Constructor. + * + * @param uri The URI of the target reference. Can be <jk>null</jk>. + */ + public SchemaRef(String uri) { + this.setRef(uri == null ? null : URI.create(uri)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Html.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Html.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Html.png new file mode 100755 index 0000000..3848b4f Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Html.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Json.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Json.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Json.png new file mode 100755 index 0000000..6c8ddd1 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Json.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Options.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Options.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Options.png new file mode 100755 index 0000000..5250d3b Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Options.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Turtle.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Turtle.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Turtle.png new file mode 100755 index 0000000..478de82 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Turtle.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_UrlEncoded.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_UrlEncoded.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_UrlEncoded.png new file mode 100755 index 0000000..86576e7 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_UrlEncoded.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Xml.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Xml.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Xml.png new file mode 100755 index 0000000..0195c5a Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_Xml.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_XmlRdfAbbrev.png ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_XmlRdfAbbrev.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_XmlRdfAbbrev.png new file mode 100755 index 0000000..129f9df Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/doc-files/Example_XmlRdfAbbrev.png differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/package.html ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/package.html new file mode 100755 index 0000000..1034f18 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/jsonschema/package.html @@ -0,0 +1,511 @@ +<!DOCTYPE HTML> +<!-- + Licensed Materials - Property of IBM + (c) Copyright IBM Corporation 2014. All Rights Reserved. + + Note to U.S. Government Users Restricted Rights: + Use, duplication or disclosure restricted by GSA ADP Schedule + Contract with IBM Corp. + --> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type="text/css"> + /* For viewing in Page Designer */ + @IMPORT url("../../../../../../../javadoc.css"); + + /* For viewing in REST interface */ + @IMPORT url("../htdocs/javadoc.css"); + body { + margin: 20px; + } + </style> + <script> + /* Replace all @code and @link tags. */ + window.onload = function() { + document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); + document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); + } + </script> +</head> +<body> +<p>JSON-Schema Data Transfer Objects</p> +<script> + function toggle(x) { + var div = x.nextSibling; + while (div != null && div.nodeType != 1) + div = div.nextSibling; + if (div != null) { + var d = div.style.display; + if (d == 'block' || d == '') { + div.style.display = 'none'; + x.className += " closed"; + } else { + div.style.display = 'block'; + x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' ); + } + } + } +</script> +<a id='TOC'></a><h5 class='toc'>Table of Contents</h5> +<ol class='toc'> + <li><p><a class='doclink' href='#Overview'>Overview</a></p> + <ol> + <li><p><a class='doclink' href='#SchemaDefinition'>JSON-Schema schema definition</a></p> + <li><p><a class='doclink' href='#Serialize'>Creating JSON-Schema documents</a></p> + <ol> + <li><p><a class='doclink' href='#SerializeToOther'>Serializing to other data types</a></p> + </ol> + <li><p><a class='doclink' href='#Parse'>Parsing JSON-Schema documents</a></p> + </ol> +</ol> +<!-- ======================================================================================================== --> +<a id="Overview"></a> +<h2 class='topic' onclick='toggle(this)'>1 - Overview</h2> +<div class='topic'> + <p> + Juno supports serializing and parsing of JSON-Schema documents through the use of beans defined in the <code>com.ibm.juno.core.dto.jsonschema</code> package.<br> + These beans are used with the existing {@link com.ibm.juno.core.json.JsonSerializer} and {@link com.ibm.juno.core.json.JsonParser} classes to produce and consume JSON-Schema documents. + </p> + <p> + <b>NOTE:</b> JSON-Schema is currently in draft form. This API may change as the JSON-Schema specification changes. + </p> + + <!-- ======================================================================================================== --> + <a id="SchemaDefinition"></a> + <h3 class='topic' onclick='toggle(this)'>1.1 - JSON-Schema schema definition</h3> + <div class='topic'> + <p> + The draft JSON-Schema specification that the JSON-Schema beans are modeled after is as follows: + </p> + <p class='bcode'> + { + <js>"id"</js>: <js>"http://json-schema.org/draft-04/schema#"</js>, + <js>"$schema"</js>: <js>"http://json-schema.org/draft-04/schema#"</js>, + <js>"description"</js>: <js>"Core schema meta-schema"</js>, + <js>"definitions"</js>: { + <js>"schemaArray"</js>: { + <js>"type"</js>: <js>"array"</js>, + <js>"minItems"</js>: 1, + <js>"items"</js>: { <js>"$ref"</js>: <js>"#"</js> } + }, + <js>"positiveInteger"</js>: { + <js>"type"</js>: <js>"integer"</js>, + <js>"minimum"</js>: 0 + }, + <js>"positiveIntegerDefault0"</js>: { + <js>"allOf"</js>: [ { <js>"$ref"</js>: <js>"#/definitions/positiveInteger"</js> }, { <js>"default"</js>: 0 } ] + }, + <js>"simpleTypes"</js>: { + <js>"enum"</js>: [ <js>"array"</js>, <js>"boolean"</js>, <js>"integer"</js>, <js>"null"</js>, <js>"number"</js>, <js>"object"</js>, <js>"string"</js> ] + }, + <js>"stringArray"</js>: { + <js>"type"</js>: <js>"array"</js>, + <js>"items"</js>: { <js>"type"</js>: <js>"string"</js> }, + <js>"minItems"</js>: 1, + <js>"uniqueItems"</js>: <jk>true</jk> + } + }, + <js>"type"</js>: <js>"object"</js>, + <js>"properties"</js>: { + <js>"id"</js>: { + <js>"type"</js>: <js>"string"</js>, + <js>"format"</js>: <js>"uri"</js> + }, + <js>"$schema"</js>: { + <js>"type"</js>: <js>"string"</js>, + <js>"format"</js>: <js>"uri"</js> + }, + <js>"title"</js>: { + <js>"type"</js>: <js>"string"</js> + }, + <js>"description"</js>: { + <js>"type"</js>: <js>"string"</js> + }, + <js>"default"</js>: {}, + <js>"multipleOf"</js>: { + <js>"type"</js>: <js>"number"</js>, + <js>"minimum"</js>: 0, + <js>"exclusiveMinimum"</js>: <jk>true</jk> + }, + <js>"maximum"</js>: { + <js>"type"</js>: <js>"number"</js> + }, + <js>"exclusiveMaximum"</js>: { + <js>"type"</js>: <js>"boolean"</js>, + <js>"default"</js>: <jk>false</jk> + }, + <js>"minimum"</js>: { + <js>"type"</js>: <js>"number"</js> + }, + <js>"exclusiveMinimum"</js>: { + <js>"type"</js>: <js>"boolean"</js>, + <js>"default"</js>: <jk>false</jk> + }, + <js>"maxLength"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveInteger"</js> }, + <js>"minLength"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveIntegerDefault0"</js> }, + <js>"pattern"</js>: { + <js>"type"</js>: <js>"string"</js>, + <js>"format"</js>: <js>"regex"</js> + }, + <js>"additionalItems"</js>: { + <js>"anyOf"</js>: [ + { <js>"type"</js>: <js>"boolean"</js> }, + { <js>"$ref"</js>: <js>"#"</js> } + ], + <js>"default"</js>: {} + }, + <js>"items"</js>: { + <js>"anyOf"</js>: [ + { <js>"$ref"</js>: <js>"#"</js> }, + { <js>"$ref"</js>: <js>"#/definitions/schemaArray"</js> } + ], + <js>"default"</js>: {} + }, + <js>"maxItems"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveInteger"</js> }, + <js>"minItems"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveIntegerDefault0"</js> }, + <js>"uniqueItems"</js>: { + <js>"type"</js>: <js>"boolean"</js>, + <js>"default"</js>: <jk>false</jk> + }, + <js>"maxProperties"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveInteger"</js> }, + <js>"minProperties"</js>: { <js>"$ref"</js>: <js>"#/definitions/positiveIntegerDefault0"</js> }, + <js>"required"</js>: { <js>"$ref"</js>: <js>"#/definitions/stringArray"</js> }, + <js>"additionalProperties"</js>: { + <js>"anyOf"</js>: [ + { <js>"type"</js>: <js>"boolean"</js> }, + { <js>"$ref"</js>: <js>"#"</js> } + ], + <js>"default"</js>: {} + }, + <js>"definitions"</js>: { + <js>"type"</js>: <js>"object"</js>, + <js>"additionalProperties"</js>: { <js>"$ref"</js>: <js>"#"</js> }, + <js>"default"</js>: {} + }, + <js>"properties"</js>: { + <js>"type"</js>: <js>"object"</js>, + <js>"additionalProperties"</js>: { <js>"$ref"</js>: <js>"#"</js> }, + <js>"default"</js>: {} + }, + <js>"patternProperties"</js>: { + <js>"type"</js>: <js>"object"</js>, + <js>"additionalProperties"</js>: { <js>"$ref"</js>: <js>"#"</js> }, + <js>"default"</js>: {} + }, + <js>"dependencies"</js>: { + <js>"type"</js>: <js>"object"</js>, + <js>"additionalProperties"</js>: { + <js>"anyOf"</js>: [ + { <js>"$ref"</js>: <js>"#"</js> }, + { <js>"$ref"</js>: <js>"#/definitions/stringArray"</js> } + ] + } + }, + <js>"enum"</js>: { + <js>"type"</js>: <js>"array"</js>, + <js>"minItems"</js>: 1, + <js>"uniqueItems"</js>: <jk>true</jk> + }, + <js>"type"</js>: { + <js>"anyOf"</js>: [ + { <js>"$ref"</js>: <js>"#/definitions/simpleTypes"</js> }, + { + <js>"type"</js>: <js>"array"</js>, + <js>"items"</js>: { <js>"$ref"</js>: <js>"#/definitions/simpleTypes"</js> }, + <js>"minItems"</js>: 1, + <js>"uniqueItems"</js>: <jk>true</jk> + } + ] + }, + <js>"allOf"</js>: { <js>"$ref"</js>: <js>"#/definitions/schemaArray"</js> }, + <js>"anyOf"</js>: { <js>"$ref"</js>: <js>"#/definitions/schemaArray"</js> }, + <js>"oneOf"</js>: { <js>"$ref"</js>: <js>"#/definitions/schemaArray"</js> }, + <js>"not"</js>: { <js>"$ref"</js>: <js>"#"</js> } + }, + <js>"dependencies"</js>: { + <js>"exclusiveMaximum"</js>: [ <js>"maximum"</js> ], + <js>"exclusiveMinimum"</js>: [ <js>"minimum"</js> ] + }, + <js>"default"</js>: {} + } + </p> + <p> + The bean classes that make up the model are as follows: + </p> + <ul> + <li>{@link com.ibm.juno.core.dto.jsonschema.Schema} - Top level schema object. + <li>{@link com.ibm.juno.core.dto.jsonschema.SchemaProperty} - A subclass of <code>Schema</code> for representing properties. + <li>{@link com.ibm.juno.core.dto.jsonschema.SchemaPropertySimpleArray} - A convenience subclass of <code>SchemaProperty</code> for representing properties of simple array types. + <li>{@link com.ibm.juno.core.dto.jsonschema.SchemaRef} - Represents a URI reference to another schema. + <li>{@link com.ibm.juno.core.dto.jsonschema.SchemaArray} - An array of <code>Schema</code> objects. + <li>{@link com.ibm.juno.core.dto.jsonschema.JsonType} - An enum of possible JSON data types. + <li>{@link com.ibm.juno.core.dto.jsonschema.JsonTypeArray} - An array of <code>JsonType</code> objects. + </ul> + </div> + + + <!-- ======================================================================================================== --> + <a id="Serialize"></a> + <h3 class='topic' onclick='toggle(this)'>1.2 - Creating JSON-Schema documents</h3> + <div class='topic'> + <p> + JSON-Schema documents can be constructed using the Juno JSON-Schema beans as a document model object. + These beans are defined with fluent-style setters to make constructing documents as easy as possible. + </p> + <p> + The following is an example JSON-Schema document: + </p> + <p class='bcode'> + { + <js>"title"</js>: <js>"Example Schema"</js>, + <js>"type"</js>: <js>"object"</js>, + <js>"properties"</js>: { + <js>"firstName"</js>: { + <js>"type"</js>: <js>"string"</js> + }, + <js>"lastName"</js>: { + <js>"type"</js>: <js>"string"</js> + }, + <js>"age"</js>: { + <js>"description"</js>: <js>"Age in years"</js>, + <js>"type"</js>: <js>"integer"</js>, + <js>"minimum"</js>: 0 + } + }, + <js>"required"</js>: [<js>"firstName"</js>, <js>"lastName"</js>] + } + </p> + <p> + This document can be constructing using the following code: + </p> + <p class='bcode'> + <jc>// Create the document object model</jc> + Schema s = <jk>new</jk> Schema() + .setTitle(<js>"Example Schema"</js>) + .setType(JsonType.<jsf>OBJECT</jsf>) + .addProperties( + <jk>new</jk> SchemaProperty(<js>"firstName"</js>, JsonType.<jsf>STRING</jsf>), + <jk>new</jk> SchemaProperty(<js>"lastName"</js>, JsonType.<jsf>STRING</jsf>), + <jk>new</jk> SchemaProperty(<js>"age"</js>, JsonType.<jsf>INTEGER</jsf>) + .setDescription(<js>"Age in years"</js>) + .setMinimum(0) + ) + .addRequired(<js>"firstName"</js>, <js>"lastName"</js>); + + <jc>// Serialize to JSON</jc> + String json = JsonSerializer.<jsf>DEFAULT_READABLE</jsf>.serialize(s); + </p> + <p> + The following is a more-complex example showing various kinds of constraints. + </p> + <p class='bcode'> + { + <js>"id"</js>: <js>"http://some.site.somewhere/entry-schema#"</js>, + <js>"$schema"</js>: <js>"http://json-schema.org/draft-04/schema#"</js>, + <js>"description"</js>: <js>"schema for an fstab entry"</js>, + <js>"type"</js>: <js>"object"</js>, + <js>"required"</js>: [ <js>"storage"</js> ], + <js>"properties"</js>: { + <js>"storage"</js>: { + <js>"type"</js>: <js>"object"</js>, + <js>"oneOf"</js>: [ + { <js>"$ref"</js>: <js>"#/definitions/diskDevice"</js> }, + { <js>"$ref"</js>: <js>"#/definitions/diskUUID"</js> }, + { <js>"$ref"</js>: <js>"#/definitions/nfs"</js> }, + { <js>"$ref"</js>: <js>"#/definitions/tmpfs"</js> } + ] + }, + <js>"fstype"</js>: { + <js>"enum"</js>: [ <js>"ext3"</js>, <js>"ext4"</js>, <js>"btrfs"</js> ] + }, + <js>"options"</js>: { + <js>"type"</js>: <js>"array"</js>, + <js>"minItems"</js>: 1, + <js>"items"</js>: { <js>"type"</js>: <js>"string"</js> }, + <js>"uniqueItems"</js>: <jk>true</jk> + }, + <js>"readonly"</js>: { <js>"type"</js>: <js>"boolean"</js> } + }, + <js>"definitions"</js>: { + <js>"diskDevice"</js>: {}, + <js>"diskUUID"</js>: {}, + <js>"nfs"</js>: {}, + <js>"tmpfs"</js>: {} + } + } + </p> + <p> + This document can be constructing using the following code: + </p> + <p class='bcode'> + Schema s = <jk>new</jk> Schema() + .setId(<js>"http://some.site.somewhere/entry-schema#"</js>) + .setSchemaVersionId(<js>"http://json-schema.org/draft-04/schema#"</js>) + .setDescription(<js>"schema for an fstab entry"</js>) + .setType(JsonType.<jsf>OBJECT</jsf>) + .addRequired(<js>"storage"</js>) + .addProperties( + <jk>new</jk> SchemaProperty(<js>"storage"</js>) + .setType(JsonType.<jsf>OBJECT</jsf>) + .addOneOf( + <jk>new</jk> SchemaRef(<js>"#/definitions/diskDevice"</js>), + <jk>new</jk> SchemaRef(<js>"#/definitions/diskUUID"</js>), + <jk>new</jk> SchemaRef(<js>"#/definitions/nsf"</js>), + <jk>new</jk> SchemaRef(<js>"#/definitions/tmpfs"</js>) + ), + <jk>new</jk> SchemaProperty(<js>"fstype"</js>) + .addEnum(<js>"ext3"</js>, <js>"ext4"</js>, <js>"btrfs"</js>), + <jk>new</jk> SchemaPropertySimpleArray(<js>"options"</js>, JsonType.<jsf>STRING</jsf>) + .setMinItems(1) + .setUniqueItems(<jk>true</jk>), + <jk>new</jk> SchemaProperty(<js>"readonly"</js>) + .setType(JsonType.<jsf>BOOLEAN</jsf>) + ) + .addDefinition(<js>"diskDevice"</js>, + <jk>new</jk> Schema() + ) + .addDefinition(<js>"diskUUID"</js>, + <jk>new</jk> Schema() + ) + .addDefinition(<js>"nfs"</js>, + <jk>new</jk> Schema() + ) + .addDefinition(<js>"tmpfs"</js>, + <jk>new</jk> Schema() + ); + + <jc>// Serialize to JSON</jc> + String json = JsonSerializer.<jsf>DEFAULT_READABLE</jsf>.serialize(s); + </p> + + + <!-- ======================================================================================================== --> + <a id="SerializeToOther"></a> + <h4 class='topic' onclick='toggle(this)'>1.2.1 - Serializing to other data types</h4> + <div class='topic'> + <p> + Since the JSON-Schema DTOs are simple beans, they can be used to serialize to a variety of other language types as well as JSON. + This also allows JSON-Schema documents to be easily served up using the Juno REST API. + </p> + <p> + The sample web application includes a REST resource that generates a JSON-Schema document. + We'll use this resource to show what the JSON-Schema document looks like in other languages. + </p> + <p class='bcode'> + <jd>/** + * Sample resource that shows how to serialize JSON-Schema documents. + */</jd> + <ja>@RestResource</ja>( + path=<js>"/jsonSchema"</js>, + messages=<js>"nls/JsonSchemaResource"</js>, + properties={ + <ja>@Property</ja>(name=HtmlDocSerializerProperties.<jsf>HTMLDOC_title</jsf>, value=<js>"Sample JSON-Schema document"</js>), + <ja>@Property</ja>(name=HtmlDocSerializerProperties.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS'}"</js>) + } + ) + <jk>public class</jk> JsonSchemaResource <jk>extends</jk> RestServletJenaDefault { + + <jk>private</jk> Schema <jf>schema</jf>; <jc>// The schema document</jc> + + <jd>/** Servlet initialization */</jd> + <ja>@Override</ja> + <jk>public void</jk> init() { + + <jk>try</jk> { + <jf>schema</jf> = <jk>new</jk> Schema() + .setId(<js>"http://example.com/sample-schema#"</js>) + .setSchemaVersionUri(<js>"http://json-schema.org/draft-04/schema#"</js>) + .setTitle(<js>"Example Schema"</js>) + .setType(JsonType.<jsf>OBJECT</jsf>) + .addProperties( + <jk>new</jk> SchemaProperty(<js>"firstName"</js>, JsonType.<jsf>STRING</jsf>), + <jk>new</jk> SchemaProperty(<js>"lastName"</js>, JsonType.<jsf>STRING</jsf>), + <jk>new</jk> SchemaProperty(<js>"age"</js>, JsonType.<jsf>INTEGER</jsf>) + .setDescription(<js>"Age in years"</js>) + .setMinimum(0) + ) + .addRequired(<js>"firstName"</js>, <js>"lastName"</js>); + } <jk>catch</jk> (Exception e) { + <jk>throw new</jk> RuntimeException(e); + } + } + + <jd>/** GET request handler */</jd> + <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/"</js>) + <jk>public</jk> Schema getSchema() <jk>throws</jk> Exception { + <jk>return</jk> <jf>schema</jf>; + } + + <jd>/** + * PUT request handler. + * Replaces the schema document with the specified content, and then mirrors it as the response. + */</jd> + <ja>@RestMethod</ja>(name=<js>"PUT"</js>, path=<js>"/"</js>) + <jk>public</jk> Schema setSchema(<ja>@Content</ja> Schema schema) <jk>throws</jk> Exception { + <jk>this</jk>.<jf>schema</jf> = schema; + <jk>return</jk> <jk>this</jk>.<jf>schema</jf>; + } + + <jd>/** OPTIONS request handler */</jd> + <ja>@RestMethod</ja>(name=<js>"OPTIONS"</js>, path=<js>"/*"</js>) + <jk>public</jk> ResourceOptions doOptions(RestRequest req) { + <jk>return new</jk> ResourceOptions(<jk>this</jk>, req); + } + } + </p> + <p> + When you point your browser to this resource, the default content type is HTML (since that's what the browser asks for + by default). + </p> + <h6 class='figure'>HTML</h6> + <img class='bordered' src="doc-files/Example_Html.png"> + <p> + The REST API allows you to specify the <code>Accept</code> header as a GET parameter, and the <code>plainText=true</code> + parameter forces the returned <code>Content-Type</code> to be <code>text/plain</code>. + We'll use this to view the JSON-Schema document in other languages. + </p> + + <h6 class='figure'>Normal JSON</h6> + <img class='bordered' src="doc-files/Example_Json.png"> + + <h6 class='figure'>XML</h6> + <img class='bordered' src="doc-files/Example_Xml.png"> + + <h6 class='figure'>URL-Encoded</h6> + <img class='bordered' src="doc-files/Example_UrlEncoded.png"> + + <h6 class='figure'>Abbreviated RDF/XML</h6> + <img class='bordered' src="doc-files/Example_XmlRdfAbbrev.png"> + + <h6 class='figure'>Turtle</h6> + <img class='bordered' src="doc-files/Example_Turtle.png"> + + <p> + The full list of options for this resource can be accessed by the <code>options</code> link on the HTML page. + </p> + + <h6 class='figure'>Resource Options</h6> + <img class='bordered' src="doc-files/Example_Options.png"> + </div> + + <!-- ======================================================================================================== --> + <a id="Parse"></a> + <h3 class='topic' onclick='toggle(this)'>1.3 - Parsing JSON-Schema documents</h3> + <div class='topic'> + <p> + Use the {@link com.ibm.juno.core.json.JsonParser} to parse JSON-Schema documents into DTOs: + </p> + <p class='bcode'> + <jc>// Use parser to load JSON-Schema document into JSON-Schema DTOs</jc> + Schema schema = JsonParser.<jsf>DEFAULT</jsf>.parse(json, Schema.<jk>class</jk>); + </p> + <p> + Schema objects can also be constructed from the other media types using the appropriate parsers. + </p> + </div> + +</div> +<p align="center"><i><b>*** fÃn ***</b></i></p> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/package.html ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/package.html new file mode 100755 index 0000000..9f97884 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/dto/package.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<!-- + Licensed Materials - Property of IBM + (c) Copyright IBM Corporation 2014. All Rights Reserved. + + Note to U.S. Government Users Restricted Rights: + Use, duplication or disclosure restricted by GSA ADP Schedule + Contract with IBM Corp. + --> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type="text/css"> + /* For viewing in Page Designer */ + @IMPORT url("../../../../../../javadoc.css"); + + /* For viewing in REST interface */ + @IMPORT url("../htdocs/javadoc.css"); + body { + margin: 20px; + } + </style> + <script> + /* Replace all @code and @link tags. */ + window.onload = function() { + document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); + document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); + } + </script> +</head> +<body> +<p>Data transfer objects</p> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.class new file mode 100755 index 0000000..79acd6a Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.java new file mode 100755 index 0000000..abe8e5d --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/Encoder.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.encoders; + +import java.io.*; + +/** + * Used for enabling decompression on requests and compression on responses, such as support for GZIP compression. + * + * + * <h6 class='topic'>Description</h6> + * <p> + * Used to wrap input and output streams withing compression/decompression streams. + * <p> + * Encoders are registered with <code>RestServlets</code> through the <ja>@RestResource.encoders()</ja> annotation. + * + * + * @author James Bognar ([email protected]) + */ +public abstract class Encoder { + + /** + * Converts the specified compressed input stream into an uncompressed stream. + * + * @param is The compressed stream. + * @return The uncompressed stream. + * @throws IOException If any errors occur, such as on a stream that's not a valid GZIP input stream. + */ + public abstract InputStream getInputStream(InputStream is) throws IOException; + + /** + * Converts the specified uncompressed output stream into an uncompressed stream. + * + * @param os The uncompressed stream. + * @return The compressed stream stream. + * @throws IOException If any errors occur. + */ + public abstract OutputStream getOutputStream(OutputStream os) throws IOException; + + /** + * Returns the codings in <code>Content-Encoding</code> and <code>Accept-Encoding</code> headers + * that this encoder handles (e.g. <js>"gzip"</js>). + * + * @return The codings that this encoder handles. + */ + public abstract String[] getCodings(); +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup$EncoderEntry.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup$EncoderEntry.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup$EncoderEntry.class new file mode 100755 index 0000000..45e34e1 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup$EncoderEntry.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.class new file mode 100755 index 0000000..b6a78a4 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.java new file mode 100755 index 0000000..0106432 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/EncoderGroup.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.encoders; + +import static com.ibm.juno.core.utils.ArrayUtils.*; + +import java.util.*; + +import com.ibm.juno.core.*; + +/** + * Represents the group of {@link Encoder encoders} keyed by codings. + * + * + * <h6 class='topic'>Description</h6> + * <p> + * Maintains a set of encoders and the codings that they can handle. + * <p> + * The {@link #findMatch(String)} and {@link #getEncoder(String)} methods are then + * used to find appropriate encoders for specific <code>Accept-Encoding</code> + * and <code>Content-Encoding</code> header values. + * + * + * <h6 class='topic'>Match ordering</h6> + * <p> + * Encoders are matched against <code>Accept-Encoding</code> strings in the order they exist in this group. + * <p> + * Adding new entries will cause the entries to be prepended to the group. + * This allows for previous encoders to be overridden through subsequent calls. + * <p> + * For example, calling <code>g.append(E1.<jk>class</jk>,E2.<jk>class</jk>).append(E3.<jk>class</jk>,E4.<jk>class</jk>)</code> + * will result in the order <code>E3, E4, E1, E2</code>. + * + * + * <h6 class='topic'>Example</h6> + * <p class='bcode'> + * <jc>// Create an encoder group with support for gzip compression.</jc> + * EncoderGroup g = <jk>new</jk> EncoderGroup().append(GzipEncoder.<jk>class</jk>); + * + * <jc>// Should return "gzip"</jc> + * String matchedCoding = g.findMatch(<js>"compress;q=1.0, gzip;q=0.8, identity;q=0.5, *;q=0"</js>); + * + * <jc>// Get the encoder</jc> + * IEncoder encoder = g.getEncoder(matchedCoding); + * </p> + * + * + * @author James Bognar ([email protected]) + */ +public final class EncoderGroup { + + private Map<String,EncoderEntry> entryMap = new TreeMap<String,EncoderEntry>(String.CASE_INSENSITIVE_ORDER); + private LinkedList<EncoderEntry> tempEntries = new LinkedList<EncoderEntry>(); + private EncoderEntry[] entries; + + /** + * Returns the coding string for the matching encoder that can handle the specified <code>Accept-Encoding</code> + * or <code>Content-Encoding</code> header value. + * <p> + * Returns <jk>null</jk> if no encoders can handle it. + * <p> + * This method is fully compliant with the RFC2616/14.3 and 14.11 specifications. + * + * @param acceptEncoding The <code>Accept-Encoding</code> or <code>Content-Encoding</code> value. + * @return The coding value (e.g. <js>"gzip"</js>). + */ + public String findMatch(String acceptEncoding) { + if (getEntries().length == 0) + return null; + + MediaRange[] ae = MediaRange.parse(acceptEncoding); + + if (ae.length == 0) + ae = MediaRange.parse("*"); + + for (MediaRange a : ae) + for (EncoderEntry e : getEntries()) + for (MediaRange a2 : e.encodingRanges) + if (a.matches(a2)) + return a2.getType(); + + return null; + } + + /** + * Adds the specified encoders to this group. + * + * @param e The encoders to instantiate and add to this group. + * @return This object (for method chaining). + * @throws Exception If an instantiation error occurred. + */ + public EncoderGroup append(Class<? extends Encoder>...e) throws Exception { + for (Class<? extends Encoder> r : reverse(e)) + append(r.newInstance()); + return this; + } + + /** + * Adds the specified encoders to this group. + * + * @param e The encoder to instantiate and add to this group. + * @return This object (for method chaining). + * @throws Exception If an instantiation error occurred. + */ + public EncoderGroup append(Class<? extends Encoder> e) throws Exception { + append(e.newInstance()); + return this; + } + + /** + * Adds the specified encoders to this group. + * + * @param e The encoders to add to this group. + * @return This object (for method chaining). + */ + public EncoderGroup append(Encoder...e) { + entries = null; + for (Encoder r : reverse(e)) { + EncoderEntry ee = new EncoderEntry(r); + tempEntries.addFirst(ee); + for (String s : ee.encodings) + this.entryMap.put(s, ee); + } + return this; + } + + /** + * Adds the encoders in the specified group to this group. + * + * @param g The group containing the encoders to add to this group. + * @return This object (for method chaining). + */ + public EncoderGroup append(EncoderGroup g) { + for (EncoderEntry e : reverse(g.getEntries())) + append(e.encoder); + return this; + } + + /** + * Returns the encoder registered with the specified coding (e.g. <js>"gzip"</js>). + * + * @param coding The coding string. + * @return The encoder, or <jk>null</jk> if encoder isn't registered with that coding. + */ + public Encoder getEncoder(String coding) { + EncoderEntry e = entryMap.get(coding); + return (e == null ? null : e.encoder); + } + + /** + * Returns the set of codings supported by all encoders in this group. + * + * @return The set of codings supported by all encoders in this group. Never <jk>null</jk>. + */ + public List<String> getSupportedEncodings() { + List<String> l = new ArrayList<String>(); + for (EncoderEntry e : getEntries()) + for (String enc : e.encodings) + if (! l.contains(enc)) + l.add(enc); + return l; + } + + private EncoderEntry[] getEntries() { + if (entries == null) + entries = tempEntries.toArray(new EncoderEntry[tempEntries.size()]); + return entries; + } + + static class EncoderEntry { + Encoder encoder; + MediaRange[] encodingRanges; + String[] encodings; + + EncoderEntry(Encoder e) { + encoder = e; + + encodings = new String[e.getCodings().length]; + int i = 0; + for (String enc : e.getCodings()) + encodings[i++] = enc; + + List<MediaRange> l = new LinkedList<MediaRange>(); + for (i = 0; i < encodings.length; i++) + l.addAll(Arrays.asList(MediaRange.parse(encodings[i]))); + encodingRanges = l.toArray(new MediaRange[l.size()]); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder$1.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder$1.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder$1.class new file mode 100755 index 0000000..9a33700 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder$1.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.class new file mode 100755 index 0000000..c0325ac Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.java new file mode 100755 index 0000000..5b2886a --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/GzipEncoder.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.encoders; + +import java.io.*; +import java.util.zip.*; + +/** + * Encoder for handling <js>"gzip"</js> encoding and decoding. + * + * @author James Bognar ([email protected]) + */ +public class GzipEncoder extends Encoder { + + @Override /* Encoder */ + public OutputStream getOutputStream(OutputStream os) throws IOException { + return new GZIPOutputStream(os) { + @Override /* OutputStream */ + public final void close() throws IOException { + finish(); + super.close(); + } + }; + } + + @Override /* Encoder */ + public InputStream getInputStream(InputStream is) throws IOException { + return new GZIPInputStream(is); + } + + /** + * Returns <code>[<js>"gzip"</js>]</code>. + */ + @Override /* Encoder */ + public String[] getCodings() { + return new String[]{"gzip"}; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.class new file mode 100755 index 0000000..a0b1737 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.java new file mode 100755 index 0000000..7fcfff9 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/IdentityEncoder.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.encoders; + +import java.io.*; + +/** + * Encoder for handling <js>"identity"</js> encoding and decoding (e.g. no encoding at all). + * + * @author James Bognar ([email protected]) + */ +public class IdentityEncoder extends Encoder { + + /** Singleton */ + public static final IdentityEncoder INSTANCE = new IdentityEncoder(); + + /** Constructor. */ + protected IdentityEncoder() {} + + @Override /* Encoder */ + public InputStream getInputStream(InputStream is) throws IOException { + return is; + } + + @Override /* Encoder */ + public OutputStream getOutputStream(OutputStream os) throws IOException { + return os; + } + + /** + * Returns <code>[<js>"identity"</js>]</code>. + */ + @Override /* Encoder */ + public String[] getCodings() { + return new String[]{"identity"}; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/package.html ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/package.html new file mode 100755 index 0000000..c536ac9 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/encoders/package.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<!-- + Licensed Materials - Property of IBM + (c) Copyright IBM Corporation 2014. All Rights Reserved. + + Note to U.S. Government Users Restricted Rights: + Use, duplication or disclosure restricted by GSA ADP Schedule + Contract with IBM Corp. + --> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type="text/css"> + /* For viewing in Page Designer */ + @IMPORT url("../../../../../../javadoc.css"); + + /* For viewing in REST interface */ + @IMPORT url("../htdocs/javadoc.css"); + body { + margin: 20px; + } + </style> + <script> + /* Replace all @code and @link tags. */ + window.onload = function() { + document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); + document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); + } + </script> +</head> +<body> +<p>Encoder API</p> + +<script> + function toggle(x) { + var div = x.nextSibling; + while (div != null && div.nodeType != 1) + div = div.nextSibling; + if (div != null) { + var d = div.style.display; + if (d == 'block' || d == '') { + div.style.display = 'none'; + x.className += " closed"; + } else { + div.style.display = 'block'; + x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' ); + } + } + } +</script> + +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.class new file mode 100755 index 0000000..178f374 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.java new file mode 100755 index 0000000..3199113 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/AnnotationBeanFilter.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.filter; + +import java.util.*; + +import com.ibm.juno.core.annotation.*; + +/** + * Bean filter constructed from a {@link Bean @Bean} annotation found on a class. + * <p> + * <b>*** Internal class - Not intended for external use ***</b> + * + * @author James Bognar ([email protected]) + * @param <T> The class type that this filter applies to. + */ +public final class AnnotationBeanFilter<T> extends BeanFilter<T> { + + /** + * Constructor. + * + * @param annotatedClass The class found to have a {@link Bean @Bean} annotation. + * @param annotations The {@link Bean @Bean} annotations found on the class and all parent classes in child-to-parent order. + */ + public AnnotationBeanFilter(Class<T> annotatedClass, List<Bean> annotations) { + super(annotatedClass); + + ListIterator<Bean> li = annotations.listIterator(annotations.size()); + while (li.hasPrevious()) { + Bean b = li.previous(); + + if (b.properties().length > 0) + setProperties(b.properties()); + + if (b.excludeProperties().length > 0) + setExcludeProperties(b.excludeProperties()); + + setPropertyNamer(b.propertyNamer()); + + if (b.interfaceClass() != Object.class) + setInterfaceClass(b.interfaceClass()); + + if (b.stopClass() != Object.class) + setStopClass(b.stopClass()); + + if (! b.subTypeProperty().isEmpty()) { + setSubTypeProperty(b.subTypeProperty()); + + LinkedHashMap<Class<?>,String> subTypes = new LinkedHashMap<Class<?>,String>(); + for (BeanSubType bst : b.subTypes()) + subTypes.put(bst.type(), bst.id()); + + setSubTypes(subTypes); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.class new file mode 100755 index 0000000..2392596 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.java new file mode 100755 index 0000000..0f91aae --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/BeanFilter.java @@ -0,0 +1,472 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2011, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.filter; + +import java.beans.*; +import java.lang.reflect.*; +import java.util.*; + +import com.ibm.juno.core.*; +import com.ibm.juno.core.annotation.*; + +/** + * Parent class for all bean filters. + * <p> + * Bean filters are used to control aspects of how beans are handled during serialization and parsing. + * <p> + * This class can be considered a programmatic equivalent to using the {@link Bean @Bean} annotation on bean classes. + * Thus, it can be used to perform the same function as the <code>@Bean</code> annotation when you don't have + * the ability to annotate those classes (e.g. you don't have access to the source code). + * <p> + * Note that value returned by the {@link Filter#forClass()} method is automatically determined through reflection + * when the no-arg constructor is used. + * + * <p> + * When defining bean filters, you can either call the setters in the contructor, or override getters. + * + * <h6 class='topic'>Example</h6> + * <p class='bcode'> + * <jc>// Create our serializer with a filter.</jc> + * WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(AddressFilter.<jk>class</jk>); + * + * Address a = <jk>new</jk> Address(); + * String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc> + * + * <jc>// Filter class defined via setters</jc> + * <jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilter<Address> { + * <jk>public</jk> AddressFilter() { + * setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>); + * } + * } + * + * <jc>// Filter class defined by overriding getters</jc> + * <jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilter<Address> { + * <jk>public</jk> String[] getProperties() { + * <jk>return new</jk> String[]{<js>"street"</js>,<js>"city"</js>,<js>"state"</js>}; + * } + * } + * </p> + * <p> + * The examples in this class use the setters approach. + * + * <h6 class='topic'>Additional information</h6> + * See {@link com.ibm.juno.core.filter} for more information. + * + * + * @author James Bognar ([email protected]) + * @param <T> The class type that this filter applies to. + */ +public abstract class BeanFilter<T> extends Filter { + + private String[] properties, excludeProperties; + private LinkedHashMap<Class<?>, String> subTypes; + private String subTypeAttr; + private Class<? extends PropertyNamer> propertyNamer; + private Class<?> interfaceClass, stopClass; + + /** + * Constructor that determines the for-class value using reflection. + */ + @SuppressWarnings("unchecked") + public BeanFilter() { + super(); + this.type = FilterType.BEAN; + + Class<?> c = this.getClass().getSuperclass(); + Type t = this.getClass().getGenericSuperclass(); + while (c != BeanFilter.class) { + t = c.getGenericSuperclass(); + c = c.getSuperclass(); + } + + // Attempt to determine the T and G classes using reflection. + if (t instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType)t; + Type[] pta = pt.getActualTypeArguments(); + if (pta.length > 0) { + Type nType = pta[0]; + if (nType instanceof Class) + this.forClass = (Class<T>)nType; + + else + throw new RuntimeException("Unsupported parameter type: " + nType); + } + } + } + + /** + * Constructor that specifies the for-class explicitly. + * <p> + * This constructor only needs to be called when the class type cannot be inferred through reflection. + * + * <dl> + * <dt>Example:</dt> + * <dd> + * <p class='bcode'> + * <jk>public class</jk> SomeArbitraryFilter <jk>extends</jk> BeanFilter<?> { + * <jk>public</jk> SomeArbitraryFilter(Class<?> forClass) { + * <jk>super</jk>(forClass); + * ... + * } + * } + * </p> + * </dd> + * </dl> + * + * @param forClass The class that this bean filter applies to. + */ + public BeanFilter(Class<T> forClass) { + super(forClass); + this.type = FilterType.BEAN; + } + + /** + * Returns the set and order of names of properties associated with a bean class. + * + * @see #setProperties(String...) + * @return The name of the properties associated with a bean class, or <jk>null</jk> if all bean properties should be used. + */ + public String[] getProperties() { + return properties; + } + + /** + * Specifies the set and order of names of properties associated with a bean class. + * <p> + * The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and related methods. + * <p> + * This method is an alternative to using the {@link Bean#properties()} annotation on a class. + * + * <dl> + * <dt>Example:</dt> + * <dd> + * <p class='bcode'> + * <jc>// Create our serializer with a filter.</jc> + * WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(AddressFilter.<jk>class</jk>); + * + * Address a = <jk>new</jk> Address(); + * String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc> + * + * <jc>// Filter class</jc> + * <jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilter<Address> { + * <jk>public</jk> AddressFilter() { + * setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>); + * } + * } + * </p> + * </dd> + * </dl> + * + * @param properties The name of the properties associated with a bean class. + * @return This object (for method chaining). + */ + public BeanFilter<T> setProperties(String...properties) { + this.properties = properties; + return this; + } + + /** + * Returns the list of properties to ignore on a bean. + * + * @see #setExcludeProperties(String...) + * @return The name of the properties to ignore on a bean, or <jk>null</jk> to not ignore any properties. + */ + public String[] getExcludeProperties() { + return excludeProperties; + } + + /** + * Specifies a list of properties to ignore on a bean. + * <p> + * This method is an alternative to using the {@link Bean#excludeProperties()} annotation on a class. + * + * <dl> + * <dt>Example:</dt> + * <dd> + * <p class='bcode'> + * <jc>// Create our serializer with a filter.</jc> + * WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(NoCityOrStateFilter.<jk>class</jk>); + * + * Address a = <jk>new</jk> Address(); + * String json = s.serialize(a); <jc>// Excludes city and state.</jc> + * + * <jc>// Filter class</jc> + * <jk>public class</jk> NoCityOrStateFilter <jk>extends</jk> BeanFilter<Address> { + * <jk>public</jk> AddressFilter() { + * setExcludeProperties(<js>"city"</js>,<js>"state"</js>); + * } + * } + * </p> + * </dd> + * </dl> + * + * @param excludeProperties The name of the properties to ignore on a bean class. + * @return This object (for method chaining). + */ + public BeanFilter<T> setExcludeProperties(String...excludeProperties) { + this.excludeProperties = excludeProperties; + return this; + } + + /** + * Returns the {@link PropertyNamer} associated with the bean to tailor the names of bean properties. + * + * @see #setPropertyNamer(Class) + * @return The property namer class, or <jk>null</jk> if no property namer is associated with this bean property. + */ + public Class<? extends PropertyNamer> getPropertyNamer() { + return propertyNamer; + } + + /** + * Associates a {@link PropertyNamer} with this bean to tailor the names of the bean properties. + * <p> + * Property namers are used to transform bean property names from standard form to some other form. + * For example, the {@link PropertyNamerDashedLC} will convert property names to dashed-lowercase, and + * these will be used as attribute names in JSON, and element names in XML. + * <p> + * This method is an alternative to using the {@link Bean#propertyNamer()} annotation on a class. + * + * @param propertyNamer The property namer class. + * @return This object (for method chaining). + */ + public BeanFilter<T> setPropertyNamer(Class<? extends PropertyNamer> propertyNamer) { + this.propertyNamer = propertyNamer; + return this; + } + + /** + * Returns the name of the sub type property associated with the bean class. + * + * @see #setSubTypeProperty(String) + * @return The sub type property name, or <jk>null</jk> if bean has no subtypes defined. + */ + public String getSubTypeProperty() { + return subTypeAttr; + } + + /** + * Defines a virtual property on a superclass that identifies bean subtype classes. + * <p> + * In the following example, the abstract class has two subclasses that are differentiated + * by a property called <code>subType</code> + * + * <p class='bcode'> + * <jc>// Abstract superclass</jc> + * <jk>public abstract class</jk> A { + * <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; + * } + * + * <jc>// Subclass 1</jc> + * <jk>public class</jk> A1 <jk>extends</jk> A { + * <jk>public</jk> String <jf>f1</jf>; + * } + * + * <jc>// Subclass 2</jc> + * <jk>public class</jk> A2 <jk>extends</jk> A { + * <jk>public</jk> String <jf>f2</jf>; + * } + * + * <jc>// Filter for defining subtypes</jc> + * <jk>public class</jk> AFilter <jk>extends</jk> BeanFilter<A> { + * <jk>public</jk> AFilter() { + * setSubTypeProperty(<js>"subType"</js>); + * addSubType(Al.<jk>class</jk>, <js>"A1"</js>); + * addSubType(A2.<jk>class</jk>, <js>"A2"</js>); + * } + * } + * </p> + * <p> + * The following shows what happens when serializing a subclassed object to JSON: + * <p class='bcode'> + * JsonSerializer s = <jk>new</jk> JsonSerializer().addFilters(AFilter.<jk>class</jk>); + * A1 a1 = <jk>new</jk> A1(); + * a1.<jf>f1</jf> = <js>"f1"</js>; + * String r = s.serialize(a1); + * <jsm>assertEquals</jsm>(<js>"{subType:'A1',f1:'f1',f0:'f0'}"</js>, r); + * </p> + * <p> + * The following shows what happens when parsing back into the original object. + * <p class='bcode'> + * JsonParser p = <jk>new</jk> JsonParser().addFilters(AFilter.<jk>class</jk>); + * A a = p.parse(r, A.<jk>class</jk>); + * <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1); + * </p> + * <p> + * This method is an alternative to using the {@link Bean#subTypeProperty()} annotation on a class. + * + * @param subTypeAttr The name of the attribute representing the subtype. + * @return This object (for method chaining). + */ + public BeanFilter<T> setSubTypeProperty(String subTypeAttr) { + this.subTypeAttr = subTypeAttr; + return this; + } + + /** + * Returns the subtypes associated with the bean class. + * + * @see #setSubTypeProperty(String) + * @return The set of sub types associated with this bean class, or <jk>null</jk> if bean has no subtypes defined. + */ + public LinkedHashMap<Class<?>, String> getSubTypes() { + return subTypes; + } + + /** + * Specifies the set of subclasses of this bean class in addition to a string identifier for that subclass. + * + * @see #setSubTypeProperty(String) + * @param subTypes the map of subtype classes to subtype identifier strings. + * @return This object (for method chaining). + */ + public BeanFilter<T> setSubTypes(LinkedHashMap<Class<?>, String> subTypes) { + this.subTypes = subTypes; + return this; + } + + /** + * Convenience method for adding a single subtype in leu of using {@link #setSubTypes(LinkedHashMap)} in one call. + * + * @see #setSubTypeProperty(String) + * @param c The subtype class. + * @param id The subtype identifier string for the specified subtype class. + * @return This object (for method chaining). + */ + public BeanFilter<T> addSubType(Class<?> c, String id) { + if (subTypes == null) + subTypes = new LinkedHashMap<Class<?>, String>(); + subTypes.put(c, id); + return this; + } + + /** + * Returns the interface class associated with this class. + * + * @see #setInterfaceClass(Class) + * @return The interface class associated with this class, or <jk>null</jk> if no interface class is associated. + */ + public Class<?> getInterfaceClass() { + return interfaceClass; + } + + /** + * Identifies a class to be used as the interface class for this and all subclasses. + * <p> + * Functionally equivalent to using the {@link Bean#interfaceClass()} annotation. + * <p> + * When specified, only the list of properties defined on the interface class will be used during serialization. + * Additional properties on subclasses will be ignored. + * <p class='bcode'> + * <jc>// Parent class</jc> + * <jk>public abstract class</jk> A { + * <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; + * } + * + * <jc>// Sub class</jc> + * <jk>public class</jk> A1 <jk>extends</jk> A { + * <jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>; + * } + * + * <jc>// Filter class</jc> + * <jk>public class</jk> AFilter <jk>extends</jk> BeanFilter<A> { + * <jk>public</jk> AFilter() { + * setInterfaceClass(A.<jk>class</jk>); + * } + * } + * + * JsonSerializer s = new JsonSerializer().addFilters(AFilter.<jk>class</jk>); + * A1 a1 = <jk>new</jk> A1(); + * String r = s.serialize(a1); + * <jsm>assertEquals</jsm>(<js>"{f0:'f0'}"</js>, r); <jc>// Note f1 is not serialized</jc> + * </p> + * <p> + * Note that this filter can be used on the parent class so that it filters to all child classes, + * or can be set individually on the child classes. + * <p> + * This method is an alternative to using the {@link Bean#interfaceClass()}} annotation. + * + * @param interfaceClass The interface class. + * @return This object (for method chaining). + */ + public BeanFilter<T> setInterfaceClass(Class<?> interfaceClass) { + this.interfaceClass = interfaceClass; + return this; + } + + /** + * Returns the stop class associated with this class. + * + * @see #setStopClass(Class) + * @return The stop class associated with this class, or <jk>null</jk> if no stop class is associated. + */ + public Class<?> getStopClass() { + return stopClass; + } + + /** + * Identifies a stop class for this class and all subclasses. + * <p> + * Functionally equivalent to using the {@link Bean#stopClass()} annotation. + * <p> + * Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}. + * Any properties in the stop class or in its baseclasses will be ignored during analysis. + * <p> + * For example, in the following class hierarchy, instances of <code>C3</code> will include property <code>p3</code>, but + * not <code>p1</code> or <code>p2</code>. + * <p class='bcode'> + * <jk>public class</jk> C1 { + * <jk>public int</jk> getP1(); + * } + * + * <jk>public class</jk> C2 <jk>extends</jk> C1 { + * <jk>public int</jk> getP2(); + * } + * + * <ja>@Bean</ja>(stopClass=C2.<jk>class</jk>) + * <jk>public class</jk> C3 <jk>extends</jk> C2 { + * <jk>public int</jk> getP3(); + * } + * </p> + * + * @param stopClass The stop class. + * @return This object (for method chaining). + */ + public BeanFilter<T> setStopClass(Class<?> stopClass) { + this.stopClass = stopClass; + return this; + } + + /** + * Subclasses can override this property to convert property values to some other + * object just before serialization. + * + * @param bean The bean from which the property was read. + * @param name The property name. + * @param value The value just extracted from calling the bean getter. + * @return The value to serialize. Default is just to return the existing value. + */ + public Object readProperty(Object bean, String name, Object value) { + return value; + } + + /** + * Subclasses can override this property to convert property values to some other + * object just before calling the bean setter. + * + * @param bean The bean from which the property was read. + * @param name The property name. + * @param value The value just parsed. + * @return <jk>true</jk> if we set the property, <jk>false</jk> if we should allow the + * framework to call the setter. + */ + public boolean writeProperty(Object bean, String name, Object value) { + return false; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$FilterType.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$FilterType.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$FilterType.class new file mode 100755 index 0000000..c5fe96d Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$FilterType.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$NULL.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$NULL.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$NULL.class new file mode 100755 index 0000000..8f2d92b Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter$NULL.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.class new file mode 100755 index 0000000..96e2efc Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.java new file mode 100755 index 0000000..153b679 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/Filter.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.filter; + +import com.ibm.juno.core.*; + +/** + * Parent class for all bean and POJO filters. + * + * + * <h6 class='topic'>Description</h6> + * <p> + * Filters are used to alter how POJOs are handled by bean contexts (and subsequently serializers and parsers). + * The are a very powerful feature of the Juno framework that allows virtually any POJO to be serialized and parsed. + * For example, they can be used to... + * <ul> + * <li>Convert a non-serializable POJO into a serializable POJO during serialization (and optionally vis-versa during parsing). + * <li>Control various aspects of beans, such as what properties are visible, bean subclasses, etc... + * </ul> + * <p> + * There are 2 subclasses of filters: + * <ul> + * <li>{@link PojoFilter} - Non-bean filters for converting POJOs into serializable equivalents. + * <li>{@link BeanFilter} - Bean filters for configuring how beans are handled. + * </ul> + * <p> + * Filters are associated with bean contexts (and serializers/parsers) through the {@link BeanContextFactory#addFilters(Class[])} + * and {@link CoreApi#addFilters(Class[])} methods. + * + * + * <h6 class='topic'>Additional information</h6> + * See {@link com.ibm.juno.core.filter} for more information. + * + * + * @author James Bognar ([email protected]) + */ +public class Filter { + + /** Represents no filter. */ + public static class NULL extends Filter {} + + /** The filter subtype */ + public static enum FilterType { + /** PojoFilter */ + POJO, + /** BeanFilter */ + BEAN + } + + /** The class that this filter applies to. */ + protected Class<?> forClass; + + /** The bean context that this filter instance belongs to. */ + protected BeanContext beanContext; + + /** Whether this is a BeanFilter or PojoFilter. */ + protected FilterType type = FilterType.POJO; + + Filter() {} + + Filter(Class<?> forClass) { + this.forClass = forClass; + } + + + /** + * Returns the class that this filter applies to. + * + * @return The class that this filter applies to. + */ + public Class<?> forClass() { + return forClass; + } + + /** + * Returns the implementation class. + * Useful for debugging when calling {@link BeanContext#toString()}. + * + * @return The implementation class of this filter. + */ + public Class<?> getImplClass() { + return this.getClass(); + } + + /** + * Returns whether this is an instance of {@link PojoFilter} or {@link BeanFilter}. + * + * @return The filter type. + */ + public FilterType getType() { + return type; + } + + /** + * Returns the {@link BeanContext} that created this filter. + * + * @return The bean context that created this filter. + */ + protected BeanContext getBeanContext() { + return beanContext; + } + + /** + * Sets the bean context that this filter instance was created by. + * + * @param beanContext The bean context that created this filter. + * @return This object (for method chaining). + */ + public Filter setBeanContext(BeanContext beanContext) { + this.beanContext = beanContext; + return this; + } + + @Override /* Object */ + public int hashCode() { + return getClass().getName().hashCode() + forClass().getName().hashCode(); + } + + /** + * Checks if the specified filter class is the same as this one. + * + * @param f The filter to check. + * @return <jk>true</jk> if the specified filter is equivalent to this one. + */ + public boolean isSameAs(Filter f) { + return f.getClass().equals(getClass()) && f.forClass().equals(forClass()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.class new file mode 100755 index 0000000..6df5a7d Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.java ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.java new file mode 100755 index 0000000..4496c79 --- /dev/null +++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/InterfaceBeanFilter.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Licensed Materials - Property of IBM + * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved. + * + * The source code for this program is not published or otherwise + * divested of its trade secrets, irrespective of what has been + * deposited with the U.S. Copyright Office. + *******************************************************************************/ +package com.ibm.juno.core.filter; + +import com.ibm.juno.core.*; + + +/** + * Simple bean filter that simply identifies a class to be used as an interface + * class for all child classes. + * <p> + * These objects are created when you pass in non-<code>Filter</code> classes to {@link BeanContextFactory#addFilters(Class...)}, + * and are equivalent to adding a <code><ja>@Bean</ja>(interfaceClass=Foo.<jk>class</jk>)</code> annotation on the <code>Foo</code> class. + * + * @author James Bognar ([email protected]) + * @param <T> The class type that this filter applies to. + */ +public class InterfaceBeanFilter<T> extends BeanFilter<T> { + + /** + * Constructor. + * + * @param interfaceClass The class to use as an interface on all child classes. + */ + public InterfaceBeanFilter(Class<T> interfaceClass) { + super(interfaceClass); + setInterfaceClass(interfaceClass); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter$NULL.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter$NULL.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter$NULL.class new file mode 100755 index 0000000..d072bf8 Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter$NULL.class differ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.class ---------------------------------------------------------------------- diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.class new file mode 100755 index 0000000..8893adc Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.class differ
