• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.jsonschema;
2 
3 import java.math.BigDecimal;
4 import java.math.BigInteger;
5 import java.util.Collection;
6 import java.util.Map;
7 
8 import com.fasterxml.jackson.annotation.*;
9 import com.fasterxml.jackson.databind.JsonNode;
10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import com.fasterxml.jackson.databind.node.ObjectNode;
12 import com.fasterxml.jackson.databind.ser.FilterProvider;
13 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
14 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
15 
16 /**
17  * @author Ryan Heaton
18  */
19 @SuppressWarnings("deprecation")
20 public class TestGenerateJsonSchema
21     extends com.fasterxml.jackson.databind.BaseMapTest
22 {
23     /*
24     /**********************************************************
25     /* Helper classes
26     /**********************************************************
27      */
28 
29     public static class SimpleBean
30     {
31         private int property1;
32         private String property2;
33         private String[] property3;
34         private Collection<Float> property4;
35         @JsonProperty(required=true)
36         private String property5;
37 
getProperty1()38         public int getProperty1()
39         {
40             return property1;
41         }
42 
setProperty1(int property1)43         public void setProperty1(int property1)
44         {
45             this.property1 = property1;
46         }
47 
getProperty2()48         public String getProperty2()
49         {
50             return property2;
51         }
52 
setProperty2(String property2)53         public void setProperty2(String property2)
54         {
55             this.property2 = property2;
56         }
57 
getProperty3()58         public String[] getProperty3()
59         {
60             return property3;
61         }
62 
setProperty3(String[] property3)63         public void setProperty3(String[] property3)
64         {
65             this.property3 = property3;
66         }
67 
getProperty4()68         public Collection<Float> getProperty4()
69         {
70             return property4;
71         }
72 
setProperty4(Collection<Float> property4)73         public void setProperty4(Collection<Float> property4)
74         {
75             this.property4 = property4;
76         }
77 
getProperty5()78         public String getProperty5()
79         {
80             return property5;
81         }
82 
setProperty5(String property5)83         public void setProperty5(String property5)
84         {
85             this.property5 = property5;
86         }
87     }
88 
89     public class TrivialBean {
90         public String name;
91     }
92 
93     @JsonSerializableSchema(id="myType")
94     public class BeanWithId {
95         public String value;
96     }
97 
98     static class UnwrappingRoot
99     {
100         public int age;
101 
102         @JsonUnwrapped(prefix="name.")
103         public Name name;
104     }
105 
106     static class Name {
107         public String first, last;
108     }
109 
110     @JsonPropertyOrder({ "dec", "bigInt" })
111     static class Numbers {
112         public BigDecimal dec;
113         public BigInteger bigInt;
114     }
115 
116     /*
117     /**********************************************************
118     /* Unit tests
119     /**********************************************************
120      */
121 
122     private final ObjectMapper MAPPER = new ObjectMapper();
123 
124     /**
125      * tests generating json-schema stuff.
126      */
testOldSchemaGeneration()127     public void testOldSchemaGeneration() throws Exception
128     {
129         JsonSchema jsonSchema = MAPPER.generateJsonSchema(SimpleBean.class);
130 
131         assertNotNull(jsonSchema);
132 
133         // test basic equality, and that equals() handles null, other obs
134         assertTrue(jsonSchema.equals(jsonSchema));
135         assertFalse(jsonSchema.equals(null));
136         assertFalse(jsonSchema.equals("foo"));
137 
138         // other basic things
139         assertNotNull(jsonSchema.toString());
140         assertNotNull(JsonSchema.getDefaultSchemaNode());
141 
142         ObjectNode root = jsonSchema.getSchemaNode();
143         assertEquals("object", root.get("type").asText());
144         assertEquals(false, root.path("required").booleanValue());
145         JsonNode propertiesSchema = root.get("properties");
146         assertNotNull(propertiesSchema);
147         JsonNode property1Schema = propertiesSchema.get("property1");
148         assertNotNull(property1Schema);
149         assertEquals("integer", property1Schema.get("type").asText());
150         assertEquals(false, property1Schema.path("required").booleanValue());
151         JsonNode property2Schema = propertiesSchema.get("property2");
152         assertNotNull(property2Schema);
153         assertEquals("string", property2Schema.get("type").asText());
154         assertEquals(false, property2Schema.path("required").booleanValue());
155         JsonNode property3Schema = propertiesSchema.get("property3");
156         assertNotNull(property3Schema);
157         assertEquals("array", property3Schema.get("type").asText());
158         assertEquals(false, property3Schema.path("required").booleanValue());
159         assertEquals("string", property3Schema.get("items").get("type").asText());
160         JsonNode property4Schema = propertiesSchema.get("property4");
161         assertNotNull(property4Schema);
162         assertEquals("array", property4Schema.get("type").asText());
163         assertEquals(false, property4Schema.path("required").booleanValue());
164         assertEquals("number", property4Schema.get("items").get("type").asText());
165     }
166 
167     @JsonFilter("filteredBean")
168     protected static class FilteredBean {
169 
170     	@JsonProperty
171     	private String secret = "secret";
172 
173     	@JsonProperty
174     	private String obvious = "obvious";
175 
getSecret()176     	public String getSecret() { return secret; }
setSecret(String s)177     	public void setSecret(String s) { secret = s; }
178 
getObvious()179     	public String getObvious() { return obvious; }
setObvious(String s)180     	public void setObvious(String s) {obvious = s; }
181     }
182 
183     final static FilterProvider secretFilterProvider = new SimpleFilterProvider()
184         .addFilter("filteredBean", SimpleBeanPropertyFilter.filterOutAllExcept(new String[]{"obvious"}));
185 
testGeneratingJsonSchemaWithFilters()186     public void testGeneratingJsonSchemaWithFilters() throws Exception {
187     	ObjectMapper mapper = new ObjectMapper();
188     	mapper.setFilters(secretFilterProvider);
189     	JsonSchema schema = mapper.generateJsonSchema(FilteredBean.class);
190     	JsonNode node = schema.getSchemaNode().get("properties");
191     	assertTrue(node.has("obvious"));
192     	assertFalse(node.has("secret"));
193     }
194 
195     /**
196      * Additional unit test for verifying that schema object itself
197      * can be properly serialized
198      */
testSchemaSerialization()199     public void testSchemaSerialization() throws Exception
200     {
201         JsonSchema jsonSchema = MAPPER.generateJsonSchema(SimpleBean.class);
202         Map<String,Object> result = writeAndMap(MAPPER, jsonSchema);
203         assertNotNull(result);
204         // no need to check out full structure, just basics...
205         assertEquals("object", result.get("type"));
206         // only add 'required' if it is true...
207         assertNull(result.get("required"));
208         assertNotNull(result.get("properties"));
209     }
210 
testThatObjectsHaveNoItems()211     public void testThatObjectsHaveNoItems() throws Exception
212     {
213         JsonSchema jsonSchema = MAPPER.generateJsonSchema(TrivialBean.class);
214         String json = jsonSchema.toString().replaceAll("\"", "'");
215         // can we count on ordering being stable? I think this is true with current ObjectNode impl
216         // as perh [JACKSON-563]; 'required' is only included if true
217         assertEquals("{'type':'object','properties':{'name':{'type':'string'}}}",
218                 json);
219     }
220 
testSchemaId()221     public void testSchemaId() throws Exception
222     {
223         JsonSchema jsonSchema = MAPPER.generateJsonSchema(BeanWithId.class);
224         String json = jsonSchema.toString().replaceAll("\"", "'");
225         assertEquals("{'type':'object','id':'myType','properties':{'value':{'type':'string'}}}",
226                 json);
227     }
228 
229     // [databind#271]
testUnwrapping()230     public void testUnwrapping()  throws Exception
231     {
232         JsonSchema jsonSchema = MAPPER.generateJsonSchema(UnwrappingRoot.class);
233         String json = jsonSchema.toString().replaceAll("\"", "'");
234         String EXP = "{'type':'object',"
235                 +"'properties':{'age':{'type':'integer'},"
236                 +"'name.first':{'type':'string'},'name.last':{'type':'string'}}}";
237         assertEquals(EXP, json);
238     }
239 
240     //
testNumberTypes()241     public void testNumberTypes()  throws Exception
242     {
243         JsonSchema jsonSchema = MAPPER.generateJsonSchema(Numbers.class);
244         String json = quotesToApos(jsonSchema.toString());
245         String EXP = "{'type':'object',"
246                 +"'properties':{'dec':{'type':'number'},"
247                 +"'bigInt':{'type':'integer'}}}";
248         assertEquals(EXP, json);
249     }
250 }
251