X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=code-generator%2Fbinding-data-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fbinding%2Fdata%2Fcodec%2Fgen%2Fimpl%2FDataNodeContainerSerializerSource.java;h=d9094acc31cbab5624f5332e937f63570d67f546;hb=4485155ab1f9e7f77b05eddc847a67f532a3bc68;hp=9b8faba4cb67a2a3bf36215dbc9796937ed9b48d;hpb=c1dfdbde61e58a5a30337e55ef01129468b16249;p=yangtools.git diff --git a/code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/gen/impl/DataNodeContainerSerializerSource.java b/code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/gen/impl/DataNodeContainerSerializerSource.java index 9b8faba4cb..d9094acc31 100644 --- a/code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/gen/impl/DataNodeContainerSerializerSource.java +++ b/code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/gen/impl/DataNodeContainerSerializerSource.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html - */package org.opendaylight.yangtools.binding.data.codec.gen.impl; + */ + +package org.opendaylight.yangtools.binding.data.codec.gen.impl; import com.google.common.base.Preconditions; import java.util.HashMap; @@ -15,12 +17,13 @@ import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature; import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.binding.BindingMapping; +import org.opendaylight.yangtools.yang.binding.BindingSerializer; import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation; import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; @@ -30,9 +33,13 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSource { + private static final Logger LOG = LoggerFactory.getLogger(DataNodeContainerSerializerSource.class); + protected static final String INPUT = "_input"; private static final String CHOICE_PREFIX = "CHOICE_"; @@ -54,12 +61,20 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou @Override protected CharSequence getSerializerBody() { - StringBuilder b = new StringBuilder(); + final StringBuilder b = new StringBuilder(); b.append("{\n"); b.append(statement(assign(DataObjectSerializerRegistry.class.getName(), REGISTRY, "$1"))); b.append(statement(assign(dtoType.getFullyQualifiedName(), INPUT, cast(dtoType.getFullyQualifiedName(), "$2")))); b.append(statement(assign(BindingStreamEventWriter.class.getName(), STREAM, cast(BindingStreamEventWriter.class.getName(), "$3")))); + b.append(statement(assign(BindingSerializer.class.getName(), SERIALIZER, null))); + b.append("if ("); + b.append(STREAM); + b.append(" instanceof "); + b.append(BindingSerializer.class.getName()); + b.append(") {"); + b.append(statement(assign(SERIALIZER, cast(BindingSerializer.class.getName(), STREAM)))); + b.append('}'); b.append(statement(emitStartEvent())); emitBody(b); @@ -79,10 +94,10 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou } private static Map collectAllProperties(final GeneratedType type, final Map hashMap) { - for (MethodSignature definition : type.getMethodDefinitions()) { + for (final MethodSignature definition : type.getMethodDefinitions()) { hashMap.put(definition.getName(), definition.getReturnType()); } - for (Type parent : type.getImplements()) { + for (final Type parent : type.getImplements()) { if (parent instanceof GeneratedType) { collectAllProperties((GeneratedType) parent, hashMap); } @@ -90,7 +105,7 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou return hashMap; } - private static final String getGetterName(final DataSchemaNode node) { + private static String getGetterName(final DataSchemaNode node) { final TypeDefinition type ; if (node instanceof LeafSchemaNode) { type = ((LeafSchemaNode) node).getType(); @@ -114,11 +129,24 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou } private void emitBody(final StringBuilder b) { - Map getterToType = collectAllProperties(dtoType, new HashMap()); - for (DataSchemaNode schemaChild : schemaNode.getChildNodes()) { + final Map getterToType = collectAllProperties(dtoType, new HashMap()); + for (final DataSchemaNode schemaChild : schemaNode.getChildNodes()) { if (!schemaChild.isAugmenting()) { - String getter = getGetterName(schemaChild); - Type childType = getterToType.get(getter); + final String getter = getGetterName(schemaChild); + final Type childType = getterToType.get(getter); + if (childType == null) { + // FIXME AnyXml nodes are ignored, since their type cannot be found in generated bindnig + // Bug-706 https://bugs.opendaylight.org/show_bug.cgi?id=706 + if (schemaChild instanceof AnyXmlSchemaNode) { + LOG.warn("Node {} will be ignored. AnyXml is not yet supported from binding aware code." + + "Binding Independent code can be used to serialize anyXml nodes.", schemaChild.getPath()); + continue; + } else { + throw new IllegalStateException( + String.format("Unable to find type for child node %s. Expected child nodes: %s", + schemaChild.getPath(), getterToType)); + } + } emitChild(b, getter, childType, schemaChild); } } @@ -141,22 +169,34 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou b.append(statement(anyxmlNode(child.getQName().getLocalName(), getterName))); } else if (child instanceof LeafListSchemaNode) { b.append(statement(startLeafSet(child.getQName().getLocalName(),invoke(getterName, "size")))); - Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0]; + final Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0]; b.append(forEach(getterName, valueType, statement(leafSetEntryNode(CURRENT)))); b.append(statement(endNode())); } else if (child instanceof ListSchemaNode) { - Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0]; - ListSchemaNode casted = (ListSchemaNode) child; + final Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0]; + final ListSchemaNode casted = (ListSchemaNode) child; emitList(b, getterName, valueType, casted); } else if (child instanceof ContainerSchemaNode) { - b.append(statement(staticInvokeEmitter(childType, getterName))); - } else if (child instanceof ChoiceNode) { - String propertyName = CHOICE_PREFIX + childType.getName(); + b.append(tryToUseCacheElse(getterName,statement(staticInvokeEmitter(childType, getterName)))); + } else if (child instanceof ChoiceSchemaNode) { + final String propertyName = CHOICE_PREFIX + childType.getName(); staticConstant(propertyName, DataObjectSerializerImplementation.class, ChoiceDispatchSerializer.from(loadClass(childType))); - b.append(statement(invoke(propertyName, StreamWriterGenerator.SERIALIZE_METHOD_NAME, REGISTRY, cast(DataObject.class.getName(),getterName), STREAM))); + b.append(tryToUseCacheElse(getterName,statement(invoke(propertyName, StreamWriterGenerator.SERIALIZE_METHOD_NAME, REGISTRY, cast(DataObject.class.getName(),getterName), STREAM)))); } } + private StringBuilder tryToUseCacheElse(final String getterName, final CharSequence statement) { + final StringBuilder b = new StringBuilder(); + + b.append("if ( "); + b.append(SERIALIZER).append("== null || "); + b.append(invoke(SERIALIZER, "serialize", getterName)).append("== null"); + b.append(") {"); + b.append(statement); + b.append("}"); + return b; + } + private void emitList(final StringBuilder b, final String getterName, final Type valueType, final ListSchemaNode child) { final CharSequence startEvent; @@ -170,7 +210,7 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou startEvent = startMapNode(classReference(valueType), "_count"); } b.append(statement(startEvent)); - b.append(forEach(getterName, valueType, statement(staticInvokeEmitter(valueType, CURRENT)))); + b.append(forEach(getterName, valueType, tryToUseCacheElse(CURRENT,statement(staticInvokeEmitter(valueType, CURRENT))))); b.append(statement(endNode())); } } \ No newline at end of file