2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.core.utilities.json;
23 import org.json.JSONException;
24 import org.json.JSONObject;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import java.util.HashMap;
32 * The type Json schema data generator.
34 public class JsonSchemaDataGenerator {
36 private static final String ROOT = "root";
37 private static final Logger logger = LoggerFactory.getLogger(JsonSchemaDataGenerator.class);
39 * The Include defaults.
41 boolean includeDefaults = true;
42 private JSONObject root;
43 private Map<String, Object> referencesData;
46 * Instantiates a new Json schema data generator.
48 * @param jsonSchema the json schema
50 public JsonSchemaDataGenerator(String jsonSchema) {
51 if (jsonSchema == null) {
52 throw new IllegalArgumentException("Input string jsonSchema can not be null");
54 root = new JSONObject(jsonSchema);
58 * Sets include defaults.
60 * @param includeDefaults the include defaults
62 public void setIncludeDefaults(boolean includeDefaults) {
63 this.includeDefaults = includeDefaults;
67 * Generates json data that conform to the schema according to turned on flags.
69 * @return json that conform to the schema.
71 public String generateData() {
72 referencesData = new HashMap<>();
73 JSONObject data = new JSONObject();
75 generateData(ROOT, root,
76 data); // "root" is dummy name to represent the top level object (which, as apposed to
77 // inner objects, doesn't have a name in the schema)
78 return data.has(ROOT) ? data.get(ROOT).toString() : data.toString();
81 private void generateData(String propertyName, JSONObject property, JSONObject propertyData) {
82 if (property.has(JsonSchemaKeyword.TYPE)) {
83 String propertyType = property.getString(JsonSchemaKeyword.TYPE);
84 if (JsonSchemaKeyword.OBJECT.equals(propertyType)) {
85 generateObjectData(propertyName, property, propertyData);
87 generatePrimitiveData(propertyType, propertyName, property, propertyData);
89 } else if (property.has(JsonSchemaKeyword.REF)) {
90 generateReferenceData(propertyName, property.getString(JsonSchemaKeyword.REF), propertyData);
94 private void generateObjectData(String propertyName, JSONObject property,
95 JSONObject propertyData) {
96 JSONObject subProperties = property.getJSONObject(JsonSchemaKeyword.PROPERTIES);
98 JSONObject subPropertiesData = new JSONObject();
99 for (String subPropertyName : subProperties.keySet()) {
100 generateData(subPropertyName, subProperties.getJSONObject(subPropertyName),
104 if (subPropertiesData.length() > 0) {
105 propertyData.put(propertyName, subPropertiesData);
109 private void generateReferenceData(String propertyName, String referencePath,
110 JSONObject propertyData) {
111 if (referencesData.containsKey(referencePath)) {
112 Object referenceData = referencesData.get(referencePath);
113 if (referenceData != null) {
114 propertyData.put(propertyName, referenceData);
117 generateData(propertyName, resolveReference(referencePath), propertyData);
118 referencesData.put(referencePath, propertyData.opt(propertyName));
122 private JSONObject resolveReference(String referencePath) {
123 String[] keys = referencePath.replaceFirst("#/", "").split("/");
125 JSONObject reference = root;
126 for (String key : keys) {
127 reference = reference.getJSONObject(key);
132 private void generatePrimitiveData(String propertyType, String propertyName, JSONObject property,
133 JSONObject propertyData) {
134 if (includeDefaults) {
135 populateWithDefaultValue(propertyType, propertyName, property, propertyData);
139 private void populateWithDefaultValue(String propertyType, String propertyName,
140 JSONObject property, JSONObject propertyData) {
141 if (!property.has(JsonSchemaKeyword.DEFAULT)) {
145 switch (propertyType) {
146 case JsonSchemaKeyword.ARRAY:
147 propertyData.put(propertyName, property.getJSONArray(JsonSchemaKeyword.DEFAULT));
149 case JsonSchemaKeyword.BOOLEAN:
150 propertyData.put(propertyName, property.getBoolean(JsonSchemaKeyword.DEFAULT));
152 case JsonSchemaKeyword.INTEGER:
153 propertyData.put(propertyName, property.getInt(JsonSchemaKeyword.DEFAULT));
155 case JsonSchemaKeyword.NUMBER:
156 propertyData.put(propertyName, property.getDouble(JsonSchemaKeyword.DEFAULT));
158 case JsonSchemaKeyword.STRING:
159 propertyData.put(propertyName, property.getString(JsonSchemaKeyword.DEFAULT));
164 } catch (JSONException e0) {
165 Object defaultValue = property.get(JsonSchemaKeyword.DEFAULT);
166 logger.error(String.format(
167 "Invalid schema: '%s' property type is '%s' but it has a default value which is not: %s.",
168 propertyName, propertyType, defaultValue), e0);
173 private static class JsonSchemaKeyword {
174 private static final String DEFAULT = "default";
175 private static final String TYPE = "type";
176 private static final String PROPERTIES = "properties";
177 private static final String ARRAY = "array";
178 private static final String BOOLEAN = "boolean";
179 private static final String INTEGER = "integer";
180 private static final String NUMBER = "number";
181 private static final String STRING = "string";
182 private static final String OBJECT = "object";
183 private static final String REF = "$ref";