private JsonObject getJsonObjectMapping(String root,
      Map<String, JsonObject> jsonObjectMapping, String propertyKey) {

    // if there is already a mapping for the key, return the mapping
    if (jsonObjectMapping.containsKey(propertyKey)) {
      return jsonObjectMapping.get(propertyKey);
    }

    if (root.equals(propertyKey)) {
      JsonObject jsonRoot = jsonObjectMapping.get(root);
      if (null == jsonRoot) {
        jsonRoot = new JsonObject();
        jsonObjectMapping.put(root, jsonRoot);
      }

      return jsonRoot;
    }

    String propertyCategory = PropertyHelper.getPropertyCategory(propertyKey);
    JsonObject categoryJson = jsonObjectMapping.get(propertyCategory);

    if (null == categoryJson) {
      JsonObject parent = getJsonObjectMapping(root, jsonObjectMapping,
          propertyCategory);

      categoryJson = new JsonObject();
      jsonObjectMapping.put(propertyCategory, categoryJson);

      String categoryName = PropertyHelper.getPropertyName(propertyCategory);
      parent.add(categoryName, categoryJson);
    }

    return categoryJson;
  }
Gets a {@link JsonObject} that the specified flattened property should be
set on, creating all parent {@link JsonObject} instances as needed. This
will turn {code AlertDefinition/source/reporting/critical/text} into

<pre>
AlertDefinition/source: {
  reporting: {
    critical: {
      text
    }
  }
}
</pre>

Where the the following {@link JsonObject} instances are created:

<pre>
AlertDefinition/source
  Reporting
    Critical
      property 'text',
      property 'value',
      etc
</pre>

@param root
         the flattened property which will be considered the root.
@param jsonObjectMapping
         a mapping of flattened property to {@link JsonObject}.
@param propertyKey
         the key to get the {@link JsonObject} for.
@return the {@link JsonObject} that cooresponds to the specified key.
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java