001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.json; 014 015import org.apache.juneau.*; 016import org.apache.juneau.annotation.*; 017import org.apache.juneau.jsonschema.*; 018import org.apache.juneau.serializer.*; 019 020/** 021 * Serializes POJO metadata to HTTP responses as JSON-Schema. 022 * 023 * <h5 class='topic'>Media types</h5> 024 * 025 * Handles <c>Accept</c> types: <bc>application/json+schema, text/json+schema</bc> 026 * <p> 027 * Produces <c>Content-Type</c> types: <bc>application/json</bc> 028 * 029 * <h5 class='topic'>Description</h5> 030 * 031 * Produces the JSON-schema for the JSON produced by the {@link JsonSerializer} class with the same properties. 032 */ 033@ConfigurableContext 034public class JsonSchemaSerializer extends JsonSerializer { 035 036 //------------------------------------------------------------------------------------------------------------------- 037 // Configurable properties 038 //------------------------------------------------------------------------------------------------------------------- 039 040 static final String PREFIX = "JsonSchemaSerializer"; 041 042 //------------------------------------------------------------------------------------------------------------------- 043 // Predefined instances 044 //------------------------------------------------------------------------------------------------------------------- 045 046 /** Default serializer, all default settings.*/ 047 public static final JsonSchemaSerializer DEFAULT = new JsonSchemaSerializer(PropertyStore.DEFAULT); 048 049 /** Default serializer, all default settings.*/ 050 public static final JsonSchemaSerializer DEFAULT_READABLE = new Readable(PropertyStore.DEFAULT); 051 052 /** Default serializer, single quotes, simple mode. */ 053 public static final JsonSchemaSerializer DEFAULT_SIMPLE = new Simple(PropertyStore.DEFAULT); 054 055 /** Default serializer, single quotes, simple mode, with whitespace. */ 056 public static final JsonSchemaSerializer DEFAULT_SIMPLE_READABLE = new SimpleReadable(PropertyStore.DEFAULT); 057 058 059 //------------------------------------------------------------------------------------------------------------------- 060 // Predefined subclasses 061 //------------------------------------------------------------------------------------------------------------------- 062 063 /** Default serializer, with whitespace. */ 064 public static class Readable extends JsonSchemaSerializer { 065 066 /** 067 * Constructor. 068 * 069 * @param ps The property store containing all the settings for this object. 070 */ 071 public Readable(PropertyStore ps) { 072 super( 073 ps.builder().set(WSERIALIZER_useWhitespace, true).build() 074 ); 075 } 076 } 077 078 /** Default serializer, single quotes, simple mode. */ 079 public static class Simple extends JsonSchemaSerializer { 080 081 /** 082 * Constructor. 083 * 084 * @param ps The property store containing all the settings for this object. 085 */ 086 public Simple(PropertyStore ps) { 087 super( 088 ps.builder() 089 .set(JSON_simpleMode, true) 090 .set(WSERIALIZER_quoteChar, '\'') 091 .build() 092 ); 093 } 094 } 095 096 /** Default serializer, single quotes, simple mode, with whitespace. */ 097 public static class SimpleReadable extends JsonSchemaSerializer { 098 099 /** 100 * Constructor. 101 * 102 * @param ps The property store containing all the settings for this object. 103 */ 104 public SimpleReadable(PropertyStore ps) { 105 super( 106 ps.builder() 107 .set(JSON_simpleMode, true) 108 .set(WSERIALIZER_quoteChar, '\'') 109 .set(WSERIALIZER_useWhitespace, true) 110 .build() 111 ); 112 } 113 } 114 115 116 //------------------------------------------------------------------------------------------------------------------- 117 // Instance 118 //------------------------------------------------------------------------------------------------------------------- 119 120 private final JsonSchemaGenerator generator; 121 122 /** 123 * Constructor. 124 * 125 * @param ps Initialize with the specified config property store. 126 */ 127 public JsonSchemaSerializer(PropertyStore ps) { 128 super( 129 ps.builder() 130 .set(BEANTRAVERSE_detectRecursions, true) 131 .set(BEANTRAVERSE_ignoreRecursions, true) 132 .build(), 133 "application/json", "application/json+schema,text/json+schema" 134 ); 135 136 generator = JsonSchemaGenerator.create().apply(getPropertyStore()).build(); 137 } 138 139 @Override /* Context */ 140 public JsonSchemaSerializerBuilder builder() { 141 return new JsonSchemaSerializerBuilder(getPropertyStore()); 142 } 143 144 /** 145 * Instantiates a new clean-slate {@link JsonSerializerBuilder} object. 146 * 147 * <p> 148 * This is equivalent to simply calling <code><jk>new</jk> JsonSerializerBuilder()</code>. 149 * 150 * @return A new {@link JsonSerializerBuilder} object. 151 */ 152 public static JsonSchemaSerializerBuilder create() { 153 return new JsonSchemaSerializerBuilder(); 154 } 155 156 @Override /* Context */ 157 public JsonSchemaSerializerSession createSession() { 158 return createSession(createDefaultSessionArgs()); 159 } 160 161 @Override /* Serializer */ 162 public JsonSchemaSerializerSession createSession(SerializerSessionArgs args) { 163 return new JsonSchemaSerializerSession(this, args); 164 } 165 166 JsonSchemaGenerator getGenerator() { 167 return generator; 168 } 169 170 //----------------------------------------------------------------------------------------------------------------- 171 // Other methods 172 //----------------------------------------------------------------------------------------------------------------- 173 174 @Override /* Context */ 175 public ObjectMap toMap() { 176 return super.toMap() 177 .append("JsonSchemaSerializer", new DefaultFilteringObjectMap() 178 .append("generator", generator) 179 ); 180 } 181}