/* * Copyright 2012 Amazon Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://aws.amazon.com/apache2.0 * * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES * OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and * limitations under the License. */ package com.amazonaws.eclipse.cloudformation.templates.schema; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Set; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class TemplateSchemaRules { // JSON Keys private static final String ALLOWED_VALUES = "allowed-values"; private static final String CHILD_SCHEMAS = "child-schemas"; private static final String DEFAULT_CHILD_SCHEMA = "default-child-schema"; private static final String DESCRIPTION = "description"; private static final String INTRINSIC_FUNCTIONS = "intrinsic-functions"; private static final String PARAMETER = "parameter"; private static final String PROPERTIES = "properties"; private static final String PSEUDO_PARAMETERS = "pseudo-parameters"; private static final String REQUIRED = "required"; private static final String RESOURCES = "Resources"; private static final String ROOT_SCHEMA_OBJECT = "root-schema-object"; private static final String SCHEMA_LOOKUP_PROPERTY = "schema-lookup-property"; private static final String TYPE = "type"; // Template URL private static final String TEMPLATE_SCHEMA_LOCATION = "http://vstoolkit.amazonwebservices.com/CloudFormationSchema/CloudFormationV1.schema"; private JsonNode rootNode; private static TemplateSchemaRules instance; private void parse() throws Exception { ObjectMapper mapper = new ObjectMapper(); rootNode = mapper.readValue(new URL(TEMPLATE_SCHEMA_LOCATION), JsonNode.class); } public Set<String> getResourceTypeNames() { return getTopLevelSchema().getProperty(RESOURCES).getChildSchemas().keySet(); } public Schema getTopLevelSchema() { Schema schema = parseSchema(this.rootNode.get(ROOT_SCHEMA_OBJECT)); return schema; } public List<PseudoParameter> getPseudoParameters() { // TODO: Caching ArrayList<PseudoParameter> pseudoParameters = new ArrayList<PseudoParameter>(); Iterator<Entry<String, JsonNode>> iterator = rootNode.get(PSEUDO_PARAMETERS).fields(); while (iterator.hasNext()) { Entry<String, JsonNode> entry = iterator.next(); pseudoParameters.add(new PseudoParameter(entry.getKey(), entry.getValue().get(TYPE).asText(), entry.getValue().get(DESCRIPTION).asText())); } return pseudoParameters; } public List<IntrinsicFunction> getIntrinsicFuntions() { // TODO: Caching ArrayList<IntrinsicFunction> intrinsicFunctions = new ArrayList<IntrinsicFunction>(); Iterator<Entry<String, JsonNode>> iterator = rootNode.get(INTRINSIC_FUNCTIONS).fields(); while (iterator.hasNext()) { Entry<String, JsonNode> entry = iterator.next(); intrinsicFunctions.add(new IntrinsicFunction(entry.getKey(), entry.getValue().get(PARAMETER).asText(), entry.getValue().get(DESCRIPTION).asText())); } return intrinsicFunctions; } public Schema parseSchema(JsonNode schemaNode) { Schema schema = new Schema(); if (schemaNode.has(DESCRIPTION)) { schema.setDescription(schemaNode.get(DESCRIPTION).textValue()); } if (schemaNode.has(PROPERTIES)) { Iterator<Entry<String, JsonNode>> fields = schemaNode.get(PROPERTIES).fields(); while (fields.hasNext()) { Entry<String, JsonNode> entry = fields.next(); SchemaProperty schemaProperty = new SchemaProperty(entry.getValue().get(TYPE).asText()); if (entry.getValue().has(DESCRIPTION)) { schemaProperty.setDescription(entry.getValue().get(DESCRIPTION).asText()); } if (entry.getValue().has(REQUIRED)) { schemaProperty.setRequired(entry.getValue().get(REQUIRED).asBoolean()); } if (entry.getValue().has(ALLOWED_VALUES)) { List<String> allowedValues = new ArrayList<String>(); Iterator<JsonNode> iterator = entry.getValue().get(ALLOWED_VALUES).elements(); while (iterator.hasNext()) allowedValues.add(iterator.next().asText()); schemaProperty.setAllowedValues(allowedValues); } schema.addProperty(entry.getKey(), schemaProperty); JsonNode node = entry.getValue(); if (node.has(DEFAULT_CHILD_SCHEMA)) { Schema defaultSchema = parseSchema(node.get(DEFAULT_CHILD_SCHEMA)); schemaProperty.setDefaultChildSchema(defaultSchema); } else if (node.has(PROPERTIES)) { Schema defaultSchema = parseSchema(node); schemaProperty.setSchema(defaultSchema); } if (node.has(SCHEMA_LOOKUP_PROPERTY)) { schemaProperty.setSchemaLookupProperty(node.get(SCHEMA_LOOKUP_PROPERTY).asText()); } if (node.has(CHILD_SCHEMAS)) { Iterator<Entry<String, JsonNode>> fields2 = node.get(CHILD_SCHEMAS).fields(); while (fields2.hasNext()) { Entry<String, JsonNode> entry2 = fields2.next(); String schemaName = entry2.getKey(); Schema schema2 = parseSchema(entry2.getValue()); schemaProperty.addChildSchema(schemaName, schema2); } } } } else { // JSON freeform text? } return schema; } public static TemplateSchemaRules getInstance() { if (instance == null) { instance = new TemplateSchemaRules(); try { instance.parse(); } catch (Exception e) { throw new RuntimeException("", e); } } return instance; } }