/* * Copyright 2014-2016 CyberVision, 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://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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 org.kaaproject.kaa.server.admin.services.schema; import org.apache.avro.Schema; import org.apache.avro.Schema.Field; import org.apache.avro.Schema.Type; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericData.Record; import org.apache.avro.generic.GenericRecord; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.node.ArrayNode; import org.codehaus.jackson.node.BooleanNode; import org.codehaus.jackson.node.JsonNodeFactory; import org.codehaus.jackson.node.TextNode; import org.kaaproject.avro.ui.converter.CtlSource; import org.kaaproject.avro.ui.converter.SchemaFormAvroConverter; import org.kaaproject.avro.ui.shared.ArrayField.OverrideStrategy; import org.kaaproject.avro.ui.shared.FormField.FieldAccess; import org.kaaproject.avro.ui.shared.RecordField; import java.io.IOException; import java.util.Arrays; import java.util.List; /** * The Class ConfigurationSchemaFormAvroConverter. */ public class ConfigurationSchemaFormAvroConverter extends SchemaFormAvroConverter { /** * The Constant OVERRIDE_STRATEGY_TYPE_NAME. */ private static final String OVERRIDE_STRATEGY_TYPE_NAME = "OverrideStrategy"; /** * Instantiates a new configuration schema form avro converter. * * @throws IOException Signals that an I/O exception has occurred. */ public ConfigurationSchemaFormAvroConverter() throws IOException { super(); } public ConfigurationSchemaFormAvroConverter(CtlSource ctlSource) throws IOException { super(ctlSource); } /** * Creates the addressable field. * * @return the field */ private Field createAddressableField() { Field addressableField = new Field(ADDRESSABLE, Schema.createUnion(Arrays.asList( Schema.create(Type.BOOLEAN), Schema.create(Type.NULL))), null, null); addressableField.addProp(DISPLAY_NAME, "Is addressable"); addressableField.addProp(BY_DEFAULT, BooleanNode.valueOf(true)); addressableField.addProp(DISPLAY_PROMPT, "Click to enable/disable partial updates support"); return addressableField; } /** * Creates the override strategy field. * * @return the field */ private Field createOverrideStrategyField() { List<String> overrideStrategySymbols = Arrays.asList(OverrideStrategy.APPEND.name(), OverrideStrategy.REPLACE.name()); Schema overrideStrategyEnum = Schema.createEnum(OVERRIDE_STRATEGY_TYPE_NAME, null, BASE_SCHEMA_FORM_NAMESPACE, overrideStrategySymbols); Field overrideStrategyField = new Field(OVERRIDE_STRATEGY, Schema.createUnion(Arrays.asList( overrideStrategyEnum, Schema.create(Type.NULL))), null, null); overrideStrategyField.addProp(DISPLAY_NAME, "Override strategy"); JsonNodeFactory jsonFactory = JsonNodeFactory.instance; ArrayNode displayNamesNode = jsonFactory.arrayNode(); displayNamesNode.add(TextNode.valueOf("Append")); displayNamesNode.add(TextNode.valueOf("Replace")); overrideStrategyField.addProp(DISPLAY_NAMES, displayNamesNode); overrideStrategyField.addProp(DISPLAY_PROMPT, "Select array override strategy"); return overrideStrategyField; } /* (non-Javadoc) */ @Override protected void customizeRecordFields(Schema recordSchema, List<Field> fields) { if (recordSchema.getName().equals(RECORD_FIELD_TYPE)) { int index = getFieldIndex(fields, FIELDS); if (index > -1) { fields.add(index, createAddressableField()); } } else if (recordSchema.getName().equals(ARRAY_FIELD_TYPE)) { int index = getFieldIndex(fields, ARRAY_ITEM); if (index > -1) { fields.add(index, createOverrideStrategyField()); } } } /* (non-Javadoc) */ @Override protected void customizeType(Record record, Schema fieldTypeSchema) { if (record != null && record.getSchema().getName().equals(RECORD_FIELD_TYPE)) { JsonNode addressableNode = fieldTypeSchema.getJsonProp(ADDRESSABLE); if (addressableNode != null && addressableNode.isBoolean()) { record.put(ADDRESSABLE, addressableNode.asBoolean()); } else { record.put(ADDRESSABLE, true); } } } /* (non-Javadoc) */ @Override protected void customizeFormField(Record fieldType, Field field) { if (fieldType.getSchema().getName().equals(ARRAY_FIELD_TYPE)) { JsonNode overrideStrategyNode = field.getJsonProp(OVERRIDE_STRATEGY); Schema overrideStrategySchema = fieldType.getSchema().getField(OVERRIDE_STRATEGY).schema(); if (overrideStrategyNode != null && overrideStrategyNode.isTextual()) { fieldType.put(OVERRIDE_STRATEGY, new GenericData.EnumSymbol( overrideStrategySchema, overrideStrategyNode.asText().toUpperCase())); } else { fieldType.put(OVERRIDE_STRATEGY, new GenericData.EnumSymbol( overrideStrategySchema, OverrideStrategy.REPLACE.name())); } } } /* (non-Javadoc) */ @Override protected void customizeFieldSchema(Schema fieldSchema, GenericRecord fieldType) { if (fieldType != null && fieldType.getSchema().getName().equals(RECORD_FIELD_TYPE)) { Boolean addressable = (Boolean) fieldType.get(ADDRESSABLE); if (addressable != null && !addressable) { fieldSchema.addProp(ADDRESSABLE, BooleanNode.getFalse()); } } } /* (non-Javadoc) */ @Override protected void customizeSchemaField(Field avroField, Record fieldType) { if (fieldType.getSchema().getName().equals(ARRAY_FIELD_TYPE)) { GenericData.EnumSymbol overrideStrategy = (GenericData.EnumSymbol) fieldType.get(OVERRIDE_STRATEGY); if (overrideStrategy != null && !overrideStrategy.toString().equalsIgnoreCase(OverrideStrategy.REPLACE.name())) { avroField.addProp(OVERRIDE_STRATEGY, overrideStrategy.toString().toLowerCase()); } } } /* (non-Javadoc) */ @Override protected RecordField customizeUiForm(RecordField field) { field.setDisplayName("Configuration schema"); field.getFieldByName(ADDRESSABLE).setFieldAccess(FieldAccess.HIDDEN); return field; } }