View Javadoc

1   package com.atlassian.plugins.rest.doclet.generators.schema;
2   
3   import com.atlassian.annotations.tenancy.TenantAware;
4   import com.google.common.base.Function;
5   import com.google.common.base.Joiner;
6   import com.google.common.base.Objects;
7   import com.google.common.base.Splitter;
8   import com.google.common.collect.ImmutableList;
9   import com.google.common.collect.ImmutableMap;
10  import com.google.common.collect.Iterables;
11  import com.google.common.collect.Lists;
12  import com.google.common.collect.Maps;
13  import org.codehaus.jackson.annotate.JsonAutoDetect;
14  import org.codehaus.jackson.annotate.JsonProperty;
15  
16  import java.util.Arrays;
17  import java.util.List;
18  import java.util.Map;
19  
20  import static com.atlassian.annotations.tenancy.TenancyScope.SUPPRESS;
21  import static com.atlassian.annotations.tenancy.TenancyScope.TENANTLESS;
22  
23  @JsonAutoDetect
24  public class Schema
25  {
26      public enum Type
27      {
28          Any, Object, Array, Number, Integer, Boolean, String, Uri("string", "uri");
29  
30          private final String name;
31          private final String format;
32  
33          Type(final java.lang.String name, final java.lang.String format)
34          {
35              this.name = name;
36              this.format = format;
37          }
38  
39          Type()
40          {
41              this(null, null);
42          }
43  
44          @Override
45          public String toString()
46          {
47              return Objects.firstNonNull(name, this.name().toLowerCase());
48          }
49  
50          public java.lang.String format()
51          {
52              return format;
53          }
54      }
55  
56      private final String $ref;
57      private final String id;
58      private final String title;
59      private final String description;
60      private final String type;
61      private final String format;
62      @TenantAware(TENANTLESS)
63      private final Map<String, Schema> properties;
64      private final Schema items;
65      @JsonProperty ("enum")
66      private final List<String> _enum;
67  
68      @TenantAware(TENANTLESS)
69      private final Map<String, Schema> patternProperties;
70      private final List<Schema> anyOf;
71  
72      @TenantAware(TENANTLESS)
73      private final Map<String, Schema> definitions;
74      private Boolean additionalProperties;
75      private final List<String> required;
76  
77      private Schema(final String $ref, final String id, String title, String description, Type type, Map<String, Schema> properties, Schema items, Iterable<String> _enum, Iterable<String> required, Map<String, Schema> patternProperties, final Map<String, Schema> definitions, final List<Schema> anyOf)
78      {
79          this.$ref = $ref;
80          this.id = id;
81          this.title = title;
82          this.description = description;
83          this.type = type != null && type != Type.Any ? type.toString() : null;
84          this.format = this.type != null ? type.format() : null;
85          this.anyOf = anyOf != null && anyOf.size() > 0 ? ImmutableList.copyOf(anyOf) : null;
86          this.properties = properties != null && properties.size() > 0
87                  ? ImmutableMap.copyOf(properties)
88                  : null;
89          this.items = items;
90          this._enum = _enum != null && Iterables.size(_enum) > 0 ? ImmutableList.copyOf(_enum) : null;
91          this.required = required != null && Iterables.size(required) > 0 ? ImmutableList.copyOf(required) : null;
92          this.patternProperties = patternProperties != null && patternProperties.size() > 0
93                  ? ImmutableMap.copyOf(patternProperties)
94                  : null;
95          this.definitions = definitions != null && definitions.size() > 0
96                  ? ImmutableMap.copyOf(definitions)
97                  : null;
98          this.additionalProperties = type != null && type == Type.Object &&
99                  (this.properties != null || this.patternProperties != null) ? false : null;
100     }
101 
102     public static Schema ref(String title)
103     {
104         return new Schema("#/definitions/" + titleToId(title), null, null, null, null, null, null, null, null, null, null, null);
105     }
106 
107     public static String titleToId(final String title)
108     {
109         return title != null ? Joiner.on("-").join(Splitter.on(" ").split(title)).toLowerCase() : null;
110     }
111 
112     public String get$ref()
113     {
114         return $ref;
115     }
116 
117     public String getId()
118     {
119         return id;
120     }
121 
122     public String getTitle()
123     {
124         return title;
125     }
126 
127     public String getDescription()
128     {
129         return description;
130     }
131 
132     public String getType()
133     {
134         return type;
135     }
136 
137     public String getFormat()
138     {
139         return format;
140     }
141 
142     public Map<String, Schema> getProperties()
143     {
144         return properties;
145     }
146 
147     public Schema getItems()
148     {
149         return items;
150     }
151 
152     public List<String> get_enum()
153     {
154         return _enum;
155     }
156 
157     public Map<String, Schema> getPatternProperties()
158     {
159         return patternProperties;
160     }
161 
162     public List<Schema> getAnyOf()
163     {
164         return anyOf;
165     }
166 
167     public Map<String, Schema> getDefinitions()
168     {
169         return definitions;
170     }
171 
172     public Boolean getAdditionalProperties()
173     {
174         return additionalProperties;
175     }
176 
177     public List<String> getRequired()
178     {
179         return required;
180     }
181 
182     public static Builder builder()
183     {
184         return new Builder();
185     }
186 
187     @Override
188     public boolean equals(Object o)
189     {
190         if (this == o) { return true; }
191         if (o == null || getClass() != o.getClass()) { return false; }
192 
193         Schema that = (Schema) o;
194 
195         return Objects.equal(this.title, that.title) &&
196                 Objects.equal(this.description, that.description) &&
197                 Objects.equal(this.type, that.type) &&
198                 Objects.equal(this.properties, that.properties) &&
199                 Objects.equal(this.items, that.items) &&
200                 Objects.equal(this._enum, that._enum) &&
201                 Objects.equal(this.required, that.required);
202     }
203 
204     @Override
205     public int hashCode()
206     {
207         return Objects.hashCode(title, description, type, properties, items, _enum, required);
208     }
209 
210     @Override
211     public String toString()
212     {
213         return Objects.toStringHelper(this)
214                 .add("title", title)
215                 .add("description", description)
216                 .add("type", type)
217                 .add("properties", properties)
218                 .add("items", items)
219                 .add("enum", _enum)
220                 .add("required", required)
221                 .toString();
222     }
223 
224     public static final class Builder
225     {
226         private String id;
227         private String title;
228         private String description;
229         private Type type;
230 
231         @TenantAware(SUPPRESS)
232         private Map<String, Schema> properties = Maps.newLinkedHashMap();
233 
234         @TenantAware(SUPPRESS)
235         private Map<String, Schema> patternProperties = Maps.newLinkedHashMap();
236         private Schema items;
237         private List<String> _enum = Lists.newArrayList();
238         private List<String> required = Lists.newArrayList();
239 
240         @TenantAware(SUPPRESS)
241         private Map<String, Schema> definitions = Maps.newTreeMap();
242         private List<Schema> anyOf = Lists.newArrayList();
243 
244         private Builder() {}
245 
246         public Builder setId(String id)
247         {
248             this.id = id;
249             return this;
250         }
251 
252         public Builder setTitle(String title)
253         {
254             this.title = title;
255             return this;
256         }
257 
258         public Builder setDescription(String description)
259         {
260             this.description = description;
261             return this;
262         }
263 
264         public Builder setType(Type type)
265         {
266             this.type = type;
267             return this;
268         }
269 
270         public Builder setProperties(Map<String, Schema> properties)
271         {
272             this.properties = properties;
273             return this;
274         }
275 
276         public Builder addProperty(String propertyName, Schema propertySchema)
277         {
278             this.properties.put(propertyName, propertySchema);
279             return this;
280         }
281 
282         public Builder addPatternProperty(String pattern, Schema schema)
283         {
284             this.patternProperties.put(pattern, schema);
285             return this;
286         }
287 
288         public Builder setItems(Schema items)
289         {
290             this.items = items;
291             return this;
292         }
293 
294         public <T extends Enum<T>> Builder setEnum(Class<T> enumType)
295         {
296             this._enum = ImmutableList.copyOf(Iterables.transform(Arrays.asList(enumType.getEnumConstants()), new Function<T, String>()
297             {
298                 @Override
299                 public String apply(final T input)
300                 {
301                     return input.toString();
302                 }
303             }));
304             return this;
305         }
306 
307         public Builder setRequired(List<String> required)
308         {
309             this.required = required;
310             return this;
311         }
312 
313         public Builder addRequired(String required)
314         {
315             this.required.add(required);
316             return this;
317         }
318 
319         public Builder addDefinition(Schema schema)
320         {
321             this.definitions.put(titleToId(schema.getTitle()), schema);
322             return this;
323         }
324 
325         public Builder addAnyOf(Schema schema)
326         {
327             this.anyOf.add(schema);
328             return this;
329         }
330 
331         public Schema build()
332         {
333             return new Schema(null, id, title, description, type, properties, items, _enum, required, patternProperties, definitions, anyOf);
334         }
335     }
336 }