/** * Returns the fields as a list of parameters for inclusion in Java source. E.g.: * * <code> * field1, field2, field3, field4 * </code> * * @param fields provides the fields to construct a parameter list for. * @return the fields as a list of parameters for inclusion in Java source. */ public String fieldList(List<RecordTemplateSpec.Field> fields) { StringBuilder sb = new StringBuilder(); Iterator<RecordTemplateSpec.Field> iter = fields.iterator(); while(iter.hasNext()) { RecordTemplateSpec.Field field = iter.next(); sb.append(escapeKeyword(field.getSchemaField().getName())); if (iter.hasNext()) sb.append(", "); } return sb.toString(); }
if (key instanceof RecordDataSchema.Field) sb.append(((RecordDataSchema.Field) key).getName()).append(" (field)");
private static String toRecordLiteral(StringBuilder sb, DataMap dataMap, RecordDataSchema recordSchema) { Iterator<RecordDataSchema.Field> iter = recordSchema.getFields().iterator(); sb.append(escapeKeyword(recordSchema.getName())); sb.append("("); while (iter.hasNext()) { RecordDataSchema.Field field = iter.next(); sb.append(escapeKeyword(field.getName())); sb.append(": "); sb.append(toLiteral(field.getType(), dataMap.get(field.getName()))); if (iter.hasNext()) { sb.append(", "); } } sb.append(")"); return sb.toString(); }
append(" of field \"").append(field.getName()). append("\" declared in record \"").append(recordSchema.getFullName()). append("\" failed validation.\n");
final ClassTemplateSpec fieldClass = processSchema(field.getType(), recordClass, field.getName()); final RecordTemplateSpec.Field newField = new RecordTemplateSpec.Field(); newField.setSchemaField(field); newField.setType(fieldClass); newField.setDataClass(determineDataClass(field.getType(), recordClass, field.getName()));
/** * Set the value of field whose type has needs to be coerced by {@link DirectCoercer}. * * @see SetMode * * @param field provides the field to set. * @param valueClass provides the expected class of the input value. * @param dataClass provides the class stored in the underlying {@link DataMap}. * @param object provides the value to set. * @param mode determines how should happen if the value provided is null. * @param <T> is the type of the object. * @throws ClassCastException if provided object is not the same as the expected class or * it cannot be coerced to the expected class. * @throws NullPointerException if null is not allowed, see {@link SetMode#DISALLOW_NULL}. * @throws IllegalArgumentException if attempting to remove a mandatory field by setting it to null, * see {@link SetMode#REMOVE_OPTIONAL_IF_NULL}. */ protected <T> void putCustomType(RecordDataSchema.Field field, Class<T> valueClass, Class<?> dataClass, T object, SetMode mode) throws ClassCastException { if (checkPutNullValue(field, object, mode)) { final Object coerced = DataTemplateUtil.coerceInput(object, valueClass, dataClass); _map.put(field.getName(), coerced); getCache().put(coerced, object); } }
/** * Set the value of field. * * This is direct method. The value is not a {@link DataTemplate}. * * @see SetMode * * @param field provides the field to set. * @param valueClass provides the expected class of the input value. * @param dataClass provides the class stored in the underlying {@link DataMap}. * @param object provides the value to set. * @param mode determines how should happen if the value provided is null. * @param <T> is the type of the object. * @throws ClassCastException if provided object is not the same as the expected class or * it cannot be coerced to the expected class. * @throws NullPointerException if null is not allowed, see {@link SetMode#DISALLOW_NULL}. * @throws IllegalArgumentException if attempting to remove a mandatory field by setting it to null, * see {@link SetMode#REMOVE_OPTIONAL_IF_NULL}. */ protected <T> void putDirect(RecordDataSchema.Field field, Class<T> valueClass, Class<?> dataClass, T object, SetMode mode) throws ClassCastException { if (checkPutNullValue(field, object, mode)) { _map.put(field.getName(), DataTemplateUtil.coerceInput(object, valueClass, dataClass)); } }
/** * Returns Java source code that computes the hashCodes of each of the fields, as a list of * parameters. * * This is the same as {@link #fieldList} except when the fields are Java arrays, in which * case they are wrapped with a utilty method to hash them correctly. E.g. * * <code> * intField, stringField, mapField, Arrays.deepHashCode(javaArrayField), recordField * </code> * * @param fields provides the fields to include in the hashcode expression. * @return a java expression that calculates a hash code. */ public String hashCodeList(List<RecordTemplateSpec.Field> fields) { StringBuilder sb = new StringBuilder(); Iterator<RecordTemplateSpec.Field> iter = fields.iterator(); while(iter.hasNext()) { RecordTemplateSpec.Field field = iter.next(); Type schemaType = field.getSchemaField().getType().getType(); sb.append(escapeKeyword(field.getSchemaField().getName())); if (iter.hasNext()) sb.append(", "); } return sb.toString(); } }
private boolean isOptionalityCompatible(RecordDataSchema.Field field, Object leader, Object follower) { /* compatible: leader : follower : is optional null : null : true null : not null : true not null : not null : true not null : not null : false incompatible: leader : follower : is optional not null : null : true null : null : false (caught by validator) null : not null : false (caught by validator) not null : null : false (caught by validator) */ final boolean isLeaderNull = (leader == null); final boolean isFollowerNull = (follower == null); final boolean isCompatible = !(!isLeaderNull && isFollowerNull && field.getOptional()); if (isCompatible && isLeaderNull != isFollowerNull) { _infoMap.addRestSpecInfo(CompatibilityInfo.Type.OPTIONAL_VALUE, _infoPath, field.getName()); } return isCompatible; }
/** * @return true if the check passes, even with compatible changes. * false if the check fails, i.e. incompatible changes are detected */ private boolean checkEqualSingleValue(RecordDataSchema.Field field, Object prevData, Object currData) { assert (field != null); if (!isOptionalityCompatible(field, prevData, currData)) { _infoMap.addRestSpecInfo(CompatibilityInfo.Type.VALUE_WRONG_OPTIONALITY, _infoPath, field.getName()); return false; } // if both prev and curr are null, they are considered equal // if prev is null and curr is not null, it has to be a optional field, which is compatible // if both prev and curr are not null, they are compatible iff they are equal if (prevData != null && !prevData.equals(currData)) { _infoMap.addRestSpecInfo(field.getName(), CompatibilityInfo.Type.VALUE_NOT_EQUAL, _infoPath, prevData, currData); return false; } return true; }
/** * @return whether the optionality check passes. it does not cover the result of RecordTemplate check */ private <T extends RecordTemplate> boolean checkComplexField(RecordDataSchema.Field field, T prevRec, T currRec) { assert (field != null); if (!isOptionalityCompatible(field, prevRec, currRec)) { _infoMap.addRestSpecInfo(CompatibilityInfo.Type.VALUE_WRONG_OPTIONALITY, _infoPath, field.getName()); return false; } if (prevRec != null) { _infoPath.push(field.getName()); checkRecordTemplate(prevRec, currRec); _infoPath.pop(); } return true; }
/** * Returns the fields as a list of parameter declarations for inclusion in Java source. E.g.: * * <code> * org.example.Record field1, List<Integer> field2, Map<String, Integer> field3, Integer field4 * </code> * * @param fields provides the fields to construct a parameter declaration list for. * @return the fields as a list of parameter declarations. */ public String fieldAndTypeList(List<RecordTemplateSpec.Field> fields) { StringBuilder sb = new StringBuilder(); Iterator<RecordTemplateSpec.Field> iter = fields.iterator(); while(iter.hasNext()) { RecordTemplateSpec.Field field = iter.next(); sb.append(toOptionalType(field.getType(), field.getSchemaField().getOptional())); sb.append(" "); sb.append(escapeKeyword(field.getSchemaField().getName())); if (iter.hasNext()) sb.append(", "); } return sb.toString(); }
/** * @return whether the check passes */ private <T extends WrappingArrayTemplate<? extends RecordTemplate>> boolean checkEqualComplexArrayField(RecordDataSchema.Field field, String keyName, T prevArray, T currArray) { final HashMap<String, Integer> currRemainder = new HashMap<String, Integer>(); // if prev has more than curr, array missing element // this should catch it if (!checkComplexArrayField(field, keyName, prevArray, currArray, currRemainder, false)) { return false; } // if prev has less than curr, the remainder will contain the extra current elements if (!currRemainder.isEmpty()) { _infoMap.addRestSpecInfo(field.getName(), CompatibilityInfo.Type.ARRAY_NOT_EQUAL, _infoPath, prevArray); return false; } return true; }
private boolean checkDoc(RecordDataSchema.Field field, Object prevData, Object currData) { assert (field != null); if ((prevData == null) != (currData == null)) { _infoMap.addRestSpecInfo(field.getName(), CompatibilityInfo.Type.DOC_NOT_EQUAL, _infoPath); return false; } if (prevData != null && !prevData.equals(currData)) { _infoMap.addRestSpecInfo(field.getName(), CompatibilityInfo.Type.DOC_NOT_EQUAL, _infoPath); return false; } return true; }
private void checkAnnotationsMap(RecordDataSchema.Field field, CustomAnnotationContentSchemaMap prevMap, CustomAnnotationContentSchemaMap currMap) { Set<String> allKeys = new HashSet<String>(); if (prevMap != null) allKeys.addAll(prevMap.keySet()); if (currMap != null) allKeys.addAll(currMap.keySet()); for(String key : allKeys) { CustomAnnotationContentSchema prevMapAnnotation = prevMap == null ? null : prevMap.get(key); CustomAnnotationContentSchema currMapAnnotation = currMap == null ? null : currMap.get(key); _infoPath.push(field.getName()); checkAnnotationsSchema(key, prevMapAnnotation, currMapAnnotation); _infoPath.pop(); } }
/** The typescript property for getting this field. */ public String accessorName() { return escapeKeyword(_schemaField().getName(), EscapeStrategy.QUOTE); }
private boolean isFieldOptional(RecordDataSchema.Field field, DataElement element) { if (field.getOptional()) { return true; } return _options.getTreatOptional().evaluate(new SimpleDataElement(null, field.getName(), field.getType(), element)); }
protected void addIsRequiredMessage(DataElement element, RecordDataSchema.Field field, String msg) { _messages.add(new Message(element.path(field.getName()), msg)); _valid = false; }
/** * Returns whether the specified field is present. * * @param field to check. * @return whether the specified field is present. */ protected boolean contains(RecordDataSchema.Field field) { return _map.containsKey(field.getName()); }
/** * Remove a field from the record. * * @param field to remove. * @return true if the field was removed. */ protected boolean remove(RecordDataSchema.Field field) { return _map.remove(field.getName()) != null; }