| <#-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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. |
| --> |
| <#-- Prevent freemarker from escaping stuff --> |
| <#outputformat "undefined"> |
| <#-- Declare the name and type of variables passed in to the template --> |
| <#-- @ftlvariable name="languageName" type="java.lang.String" --> |
| <#-- @ftlvariable name="protocolName" type="java.lang.String" --> |
| <#-- @ftlvariable name="outputFlavor" type="java.lang.String" --> |
| <#-- @ftlvariable name="helper" type="org.apache.plc4x.language.java.JavaLanguageTemplateHelper" --> |
| <#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" --> |
| <#-- Declare the name and type of variables declared locally inside the template --> |
| <#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" --> |
| <#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" --> |
| <#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" --> |
| <#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" --> |
| <#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" --> |
| <#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" --> |
| <#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" --> |
| <#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" --> |
| <#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" --> |
| <#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" --> |
| <#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" --> |
| <#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" --> |
| <#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" --> |
| <#-- @ftlvariable name="unknownField" type="org.apache.plc4x.plugins.codegenerator.types.fields.UnknownField" --> |
| <#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" --> |
| <#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" --> |
| <#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" --> |
| ${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")}/${type.name}.java |
| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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 ${helper.packageName(protocolName, languageName, outputFlavor)}; |
| |
| import static org.apache.plc4x.java.spi.generation.StaticHelper.*; |
| |
| import ${helper.packageName(protocolName, languageName, outputFlavor)}.io.*; |
| import ${helper.packageName(protocolName, languageName, outputFlavor)}.types.*; |
| |
| import org.apache.commons.lang3.builder.ToStringBuilder; |
| import org.apache.commons.lang3.builder.ToStringStyle; |
| import org.apache.plc4x.java.api.value.*; |
| import org.apache.plc4x.java.spi.generation.Message; |
| import org.apache.plc4x.java.spi.generation.MessageIO; |
| |
| import java.time.*; |
| import java.util.*; |
| import java.math.BigInteger; |
| |
| // Code generated by code-generation. DO NOT EDIT. |
| |
| public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${type.name}<#if type.parentType??> extends ${type.parentType.name}</#if> implements Message { |
| |
| <#-- |
| If this is a discriminated child type, we need to generate methods for accessing it's discriminator |
| values, as if they were normal java properties. |
| --> |
| <#if helper.isDiscriminatedChildTypeDefinition()> |
| <#assign discriminatedChildType = type> |
| <#-- @ftlvariable name="discriminatedChildType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition" --> |
| // Accessors for discriminator values. |
| <#list helper.getDiscriminatorValues(discriminatedChildType) as discriminatorName, discriminatorValue> |
| <#-- If the discriminator name matches that of another field, suppress the methods generation --> |
| <#if !helper.isNonDiscriminatorField(discriminatorName)> |
| public ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} get${discriminatorName?cap_first}() { |
| <#if !helper.isComplexTypeReference(helper.getDiscriminatorTypes()[discriminatorName])> |
| return <#if helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName]) = "String"><#if discriminatorValue??>"${discriminatorValue}"<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if><#else><#if discriminatorValue??>${helper.adjustLiterals(helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName]),discriminatorValue)}<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if></#if>; |
| <#else> |
| return <#if helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName]) = "String"><#if discriminatorValue??>"${discriminatorValue}"<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if><#else><#if discriminatorValue??>${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}.${discriminatorValue}<#else>${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}.${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if></#if>; |
| </#if> |
| } |
| </#if> |
| </#list> |
| </#if> |
| <#-- |
| If this is a discriminated parent type, we need to generate the abstract methods for accessing it's |
| discriminator values instead. |
| --> |
| <#if helper.isDiscriminatedParentTypeDefinition()> |
| <#assign discriminatedParentType = type> |
| <#-- @ftlvariable name="discriminatedParentType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" --> |
| // Abstract accessors for discriminator values. |
| <#list helper.getDiscriminatorTypes() as discriminatorName, discriminatorType> |
| <#-- If the discriminator name matches that of another field, suppress the methods generation --> |
| <#if !helper.isNonDiscriminatorField(discriminatorName)> |
| public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}(); |
| </#if> |
| </#list> |
| </#if> |
| <#-- If the current type contains "const" fields, generate some java constants for holing their values --> |
| <#if type.constFields?has_content> |
| |
| // Constant values. |
| <#list type.constFields as field> |
| public static final ${helper.getLanguageTypeNameForField(field)} ${field.name?upper_case} = <#if helper.getLanguageTypeNameForField(field) = 'float'>${field.referenceValue}f<#else>${field.referenceValue}</#if>; |
| </#list> |
| </#if> |
| <#-- Prpoerty fields are fields that require a property in the pojo --> |
| <#if type.propertyFields?has_content> |
| |
| // Properties. |
| <#list type.propertyFields as field> |
| private final ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name}; |
| </#list> |
| </#if> |
| |
| <#-- getAllPropertyFields() returns not only the property fields of this type but also of it's parents --> |
| public ${type.name}(<#list type.getAllPropertyFields() as field>${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name}<#sep>, </#sep></#list>) { |
| <#if type.getParentPropertyFields()?has_content> |
| super(<#list type.getParentPropertyFields() as field>${field.name}<#sep>, </#sep></#list>); |
| </#if> |
| <#list type.propertyFields as field> |
| this.${field.name} = ${field.name}; |
| </#list> |
| } |
| |
| <#list type.getAbstractFields() as field> |
| public abstract ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> get${field.name?cap_first}(); |
| |
| </#list> |
| <#list type.propertyFields as field> |
| public ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> get${field.name?cap_first}() { |
| return ${field.name}; |
| } |
| |
| </#list> |
| <#list type.virtualFields as field> |
| <#if !helper.isDiscriminatorField(field.name)> |
| public ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> get${field.name?cap_first}() { |
| <#if helper.getLanguageTypeNameForField(field) = 'String'> |
| return ${helper.getLanguageTypeNameForField(field)}.valueOf(${helper.toParseExpression(field, field.valueExpression, type.parserArguments)}); |
| <#else> |
| return (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field, field.valueExpression, type.parserArguments)}); |
| </#if> |
| } |
| </#if> |
| |
| </#list> |
| @Override |
| public int getLengthInBytes() { |
| return getLengthInBits() / 8; |
| } |
| |
| @Override |
| public int getLengthInBits() { |
| return getLengthInBitsConditional(false); |
| } |
| |
| <#-- TODO: use serializer args instead of a fixed bool for one case --> |
| public int getLengthInBitsConditional(boolean lastItem) { |
| int lengthInBits = <#if type.parentType??>super.getLengthInBitsConditional(lastItem)<#else>0</#if>; |
| ${helper.getLanguageTypeNameForTypeReference(type.typeReference)} _value = this; |
| <#list type.fields as field> |
| <#switch field.typeName> |
| <#case "array"> |
| <#assign arrayField = field> |
| |
| // Array field |
| if(${arrayField.name} != null) { |
| <#if helper.isSimpleTypeReference(arrayField.type)> |
| <#assign simpleTypeReference = arrayField.type> |
| lengthInBits += ${simpleTypeReference.sizeInBits} * ${arrayField.name}.length; |
| <#elseif helper.isCountArrayField(arrayField)> |
| int i=0; |
| <#assign simpleTypeReference = arrayField.type> |
| for(${arrayField.type.name} element : ${arrayField.name}) { |
| boolean last = ++i >= ${arrayField.name}.length; |
| lengthInBits += element.getLengthInBitsConditional(last); |
| } |
| <#else> |
| for(Message element : ${arrayField.name}) { |
| lengthInBits += element.getLengthInBits(); |
| } |
| </#if> |
| } |
| <#break> |
| <#case "checksum"> |
| <#assign checksumField = field> |
| <#assign simpleTypeReference = checksumField.type> |
| |
| // Checksum Field (checksum) |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| <#break> |
| <#case "const"> |
| <#assign constField = field> |
| <#assign simpleTypeReference = constField.type> |
| |
| // Const Field (${constField.name}) |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| <#break> |
| <#case "discriminator"> |
| <#assign discriminatorField = field> |
| |
| // Discriminator Field (${discriminatorField.name}) |
| <#if helper.isSimpleTypeReference(discriminatorField.type)> |
| <#assign simpleTypeReference = discriminatorField.type> |
| <#if helper.getLanguageTypeNameForTypeReference(discriminatorField.type) = "String"> |
| lengthInBits += ${helper.toSerializationExpression(discriminatorField, simpleTypeReference.getLengthExpression(), type.parserArguments)}; |
| <#else> |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| </#if> |
| <#elseif helper.isEnumField(field)> |
| lengthInBits += ${helper.getEnumBaseTypeReference(discriminatorField.type).sizeInBits}; |
| <#else> |
| lengthInBits += ${discriminatorField.name}.getLengthInBits(); |
| </#if> |
| <#break> |
| <#case "enum"> |
| <#assign enumField = field> |
| |
| // Enum Field (${enumField.name}) |
| lengthInBits += ${helper.getEnumBaseTypeReference(enumField.type).sizeInBits}; |
| <#break> |
| <#case "implicit"> |
| <#assign implicitField = field> |
| <#assign simpleTypeReference = implicitField.type> |
| |
| // Implicit Field (${implicitField.name}) |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| //${helper.getLanguageTypeNameForField(field)} ${implicitField.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(implicitField, implicitField.serializeExpression, type.parserArguments)}); |
| <#break> |
| <#case "manualArray"> |
| <#assign manualArrayField = field> |
| |
| // Manual Array Field (${manualArrayField.name}) |
| lengthInBits += ${helper.toParseExpression(manualArrayField, manualArrayField.lengthExpression, type.parserArguments)} * 8; |
| <#break> |
| <#case "manual"> |
| <#assign manualField = field> |
| |
| // Manual Field (${manualField.name}) |
| lengthInBits += ${helper.toParseExpression(manualField, manualField.lengthExpression, type.parserArguments)} * 8; |
| <#break> |
| <#case "optional"> |
| <#assign optionalField = field> |
| |
| // Optional Field (${optionalField.name}) |
| if(${optionalField.name} != null) { |
| <#if helper.isSimpleTypeReference(optionalField.type)> |
| <#assign simpleTypeReference = optionalField.type> |
| <#if helper.getLanguageTypeNameForTypeReference(optionalField.type) = "String"> |
| lengthInBits += ${helper.toSerializationExpression(discriminatorField, simpleTypeReference.getLengthExpression(), type.parserArguments)}; |
| <#else> |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| </#if> |
| <#elseif helper.isEnumField(field)> |
| lengthInBits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits}; |
| <#else> |
| lengthInBits += ${optionalField.name}.getLengthInBits(); |
| </#if> |
| } |
| <#break> |
| <#case "padding"> |
| <#assign paddingField = field> |
| <#assign simpleTypeReference = paddingField.type> |
| |
| // Padding Field (padding) |
| <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last --> |
| int _timesPadding = (int) (${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)}); |
| while (_timesPadding-- > 0) { |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| } |
| <#break> |
| <#case "reserved"> |
| <#assign reservedField = field> |
| <#assign simpleTypeReference = reservedField.type> |
| |
| // Reserved Field (reserved) |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| <#break> |
| <#case "simple"> |
| <#assign simpleField = field> |
| |
| // Simple field (${simpleField.name}) |
| <#if helper.isSimpleTypeReference(simpleField.type)> |
| <#if helper.getLanguageTypeNameForTypeReference(simpleField.type) = "String"> |
| <#assign simpleTypeReference = simpleField.type> |
| lengthInBits += ${helper.toSerializationExpression(simpleField, simpleTypeReference.getLengthExpression(), type.parserArguments)}; |
| <#else> |
| <#assign simpleTypeReference = simpleField.type> |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| </#if> |
| <#elseif helper.isEnumField(field)> |
| lengthInBits += ${helper.getEnumBaseTypeReference(simpleField.type).sizeInBits}; |
| <#else> |
| lengthInBits += ${simpleField.name}.getLengthInBits(); |
| </#if> |
| <#break> |
| <#case "switch"> |
| <#assign switchField = field> |
| |
| // Length of sub-type elements will be added by sub-type... |
| <#break> |
| <#case "unknown"> |
| <#assign unknownField = field> |
| <#assign simpleTypeReference = unknownField.type> |
| |
| // Unknown field |
| lengthInBits += ${simpleTypeReference.sizeInBits}; |
| <#case "virtual"> |
| <#assign virtualField = field> |
| |
| // A virtual field doesn't have any in- or output. |
| <#break> |
| </#switch> |
| </#list> |
| |
| return lengthInBits; |
| } |
| |
| @Override |
| public MessageIO<<#if type.parentType??>${type.parentType.name}<#else>${type.name}</#if>, <#if type.parentType??>${type.parentType.name}<#else>${type.name}</#if>> getMessageIO() { |
| return new <#if type.parentType??>${type.parentType.name}<#else>${type.name}</#if>IO(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (!(o instanceof ${type.name})) { |
| return false; |
| } |
| ${type.name} that = (${type.name}) o; |
| return |
| <#if type.propertyFields?has_content> |
| <#list type.propertyFields as field> |
| (get${field.name?cap_first}() == that.get${field.name?cap_first}()) && |
| </#list> |
| </#if> |
| <#if type.parentType??> |
| super.equals(that) && |
| </#if> |
| true; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash( |
| <#if type.parentType??> |
| super.hashCode()<#if type.propertyFields?has_content>,</#if> |
| </#if> |
| <#if type.propertyFields?has_content> |
| <#list type.propertyFields as field> |
| get${field.name?cap_first}()<#sep>,</#sep> |
| </#list> |
| </#if> |
| ); |
| } |
| |
| @Override |
| public String toString() { |
| return toString(ToStringStyle.SHORT_PREFIX_STYLE); |
| } |
| |
| public String toString(ToStringStyle style) { |
| return new ToStringBuilder(this, style) |
| <#if type.parentType??> |
| .appendSuper(super.toString(style)) |
| </#if> |
| <#if type.propertyFields?has_content> |
| <#list type.propertyFields as field> |
| .append("${field.name}", get${field.name?cap_first}()) |
| </#list> |
| </#if> |
| <#list type.virtualFields as field> |
| .append("${field.name}", get${field.name?cap_first}()) |
| </#list> |
| .toString(); |
| } |
| |
| } |
| </#outputformat> |