<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-model-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
</dependencies>
<build>
--- /dev/null
+/*
+ * Copyright (c) 2013 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.sal.binding.generator.api;
+
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+
+public interface ClassLoadingStrategy {
+
+ public Class<?> loadClass(Type type) throws ClassNotFoundException;
+
+ Class<?> loadClass(String fullyQualifiedName) throws ClassNotFoundException;
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.sal.binding.generator.api;
+
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+
+public interface ModuleInfoRegistry {
+
+ ObjectRegistration<YangModuleInfo> registerModuleInfo(YangModuleInfo yangModuleInfo);
+}
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+/*
+ * Copyright (c) 2013 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.sal.binding.generator.impl;
-\r
-import static com.google.common.base.Preconditions.*;\r
-import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;\r
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;\r
-import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;\r
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;\r
+
+import static com.google.common.base.Preconditions.*;
+import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;\r
-import java.util.Iterator\r
+import java.util.Set;
+import java.util.Iterator
import java.util.Collection
import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder
import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl
-import org.opendaylight.yangtools.yang.common.QName\rimport org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.binding.BindingMapping
import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase
import com.google.common.collect.Sets
private final Map<Module, ModuleContext> genCtx = new HashMap()
- /**\r
- * Outer key represents the package name. Outer value represents map of\r
- * all builders in the same package. Inner key represents the schema node\r
- * name (in JAVA class/interface name format). Inner value represents\r
- * instance of builder for schema node specified in key part.\r
+ /**
+ * Outer key represents the package name. Outer value represents map of
+ * all builders in the same package. Inner key represents the schema node
+ * name (in JAVA class/interface name format). Inner value represents
+ * instance of builder for schema node specified in key part.
*/
private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
- /**\r
- * Provide methods for converting YANG types to JAVA types.\r
+ /**
+ * Provide methods for converting YANG types to JAVA types.
*/
private var TypeProvider typeProvider;
- /**\r
- * Holds reference to schema context to resolve data of augmented element\r
- * when creating augmentation builder\r
+ /**
+ * Holds reference to schema context to resolve data of augmented element
+ * when creating augmentation builder
*/
private var SchemaContext schemaContext;
- /**\r
- * Constant with the concrete name of namespace.\r
+ /**
+ * Constant with the concrete name of namespace.
*/
private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";
- /**\r
- * Constant with the concrete name of identifier.\r
+ /**
+ * Constant with the concrete name of identifier.
*/
private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";
- /**\r
- * Resolves generated types from <code>context</code> schema nodes of all\r
- * modules.\r
- *\r
- * Generated types are created for modules, groupings, types, containers,\r
- * lists, choices, augments, rpcs, notification, identities.\r
- *\r
- * @param context\r
- * schema context which contains data about all schema nodes\r
- * saved in modules\r
- * @return list of types (usually <code>GeneratedType</code>\r
- * <code>GeneratedTransferObject</code>which are generated from\r
- * <code>context</code> data.\r
- * @throws IllegalArgumentException\r
- * if param <code>context</code> is null\r
- * @throws IllegalStateException\r
- * if <code>context</code> contain no modules\r
+ /**
+ * Resolves generated types from <code>context</code> schema nodes of all
+ * modules.
+ *
+ * Generated types are created for modules, groupings, types, containers,
+ * lists, choices, augments, rpcs, notification, identities.
+ *
+ * @param context
+ * schema context which contains data about all schema nodes
+ * saved in modules
+ * @return list of types (usually <code>GeneratedType</code>
+ * <code>GeneratedTransferObject</code>which are generated from
+ * <code>context</code> data.
+ * @throws IllegalArgumentException
+ * if param <code>context</code> is null
+ * @throws IllegalStateException
+ * if <code>context</code> contain no modules
*/
override generateTypes(SchemaContext context) {
checkArgument(context !== null, "Schema Context reference cannot be NULL.");
return generateTypes(context, modules);
}
- /**\r
- * Resolves generated types from <code>context</code> schema nodes only for\r
- * modules specified in <code>modules</code>\r
- *\r
- * Generated types are created for modules, groupings, types, containers,\r
- * lists, choices, augments, rpcs, notification, identities.\r
- *\r
- * @param context\r
- * schema context which contains data about all schema nodes\r
- * saved in modules\r
- * @param modules\r
- * set of modules for which schema nodes should be generated\r
- * types\r
- * @return list of types (usually <code>GeneratedType</code> or\r
- * <code>GeneratedTransferObject</code>) which:\r
- * <ul>\r
- * <li>are generated from <code>context</code> schema nodes and</li>\r
- * <li>are also part of some of the module in <code>modules</code>\r
- * set</li>.\r
- * </ul>\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if param <code>context</code> is null or</li>\r
- * <li>if param <code>modules</code> is null</li>\r
- * </ul>\r
- * @throws IllegalStateException\r
- * if <code>context</code> contain no modules\r
+ /**
+ * Resolves generated types from <code>context</code> schema nodes only for
+ * modules specified in <code>modules</code>
+ *
+ * Generated types are created for modules, groupings, types, containers,
+ * lists, choices, augments, rpcs, notification, identities.
+ *
+ * @param context
+ * schema context which contains data about all schema nodes
+ * saved in modules
+ * @param modules
+ * set of modules for which schema nodes should be generated
+ * types
+ * @return list of types (usually <code>GeneratedType</code> or
+ * <code>GeneratedTransferObject</code>) which:
+ * <ul>
+ * <li>are generated from <code>context</code> schema nodes and</li>
+ * <li>are also part of some of the module in <code>modules</code>
+ * set</li>.
+ * </ul>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if param <code>context</code> is null or</li>
+ * <li>if param <code>modules</code> is null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if <code>context</code> contain no modules
*/
override generateTypes(SchemaContext context, Set<Module> modules) {
checkArgument(context !== null, "Schema Context reference cannot be NULL.");
val List<Type> filteredGenTypes = new ArrayList();
for (Module m : modules) {
- filteredGenTypes.addAll(genCtx.get(m).generatedTypes);\r
- val Set<Type> additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m)\r
- if (additionalTypes != null) {\r
- filteredGenTypes.addAll(additionalTypes)\r
+ val ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m)
+ filteredGenTypes.addAll(ctx.generatedTypes);
+ val Set<Type> additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m)
+ if (additionalTypes != null) {
+ filteredGenTypes.addAll(additionalTypes)
}
- }\r
+ }
return filteredGenTypes;
}
}
}
- /**\r
- * Converts all extended type definitions of module to the list of\r
- * <code>Type</code> objects.\r
- *\r
- * @param module\r
- * module from which is obtained set of type definitions\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if module equals null</li>\r
- * <li>if name of module equals null</li>\r
- * <li>if type definitions of module equal null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Converts all extended type definitions of module to the list of
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained set of type definitions
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if module equals null</li>
+ * <li>if name of module equals null</li>
+ * <li>if type definitions of module equal null</li>
+ * </ul>
+ *
*/
private def void allTypeDefinitionsToGenTypes(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
}
}
}
- }\r
-\r
+ }
+
private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) {
if (node.augmenting || node.addedByUses) {
}
}
- // serialVersionUID\r
+ // serialVersionUID
if (genTOBuilder !== null) {
val GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder as GeneratedTOBuilderImpl)));
val basePackageName = moduleNamespaceToPackageName(module);
for (usesNode : node.uses) {
for (augment : usesNode.augmentations) {
- augmentationToGenTypes(basePackageName, augment, module, usesNode);
+ usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node);
processUsesAugments(augment, module);
}
}
}
- /**\r
- * Converts all <b>augmentation</b> of the module to the list\r
- * <code>Type</code> objects.\r
- *\r
- * @param module\r
- * module from which is obtained list of all augmentation objects\r
- * to iterate over them\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if the module equals null</li>\r
- * <li>if the name of module equals null</li>\r
- * <li>if the set of child nodes equals null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Converts all <b>augmentation</b> of the module to the list
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained list of all augmentation objects
+ * to iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module equals null</li>
+ * <li>if the name of module equals null</li>
+ * <li>if the set of child nodes equals null</li>
+ * </ul>
+ *
*/
private def void allAugmentsToGenTypes(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
val basePackageName = moduleNamespaceToPackageName(module);
val List<AugmentationSchema> augmentations = resolveAugmentations(module);
for (augment : augmentations) {
- augmentationToGenTypes(basePackageName, augment, module, null);
- }
- }
-
- /**\r
- * Returns list of <code>AugmentationSchema</code> objects. The objects are\r
- * sorted according to the length of their target path from the shortest to\r
- * the longest.\r
- *\r
- * @param module\r
- * module from which is obtained list of all augmentation objects\r
- * @return list of sorted <code>AugmentationSchema</code> objects obtained\r
- * from <code>module</code>\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if the module equals null</li>\r
- * <li>if the set of augmentation equals null</li>\r
- * </ul>\r
- *\r
+ augmentationToGenTypes(basePackageName, augment, module);
+ }
+ }
+
+ /**
+ * Returns list of <code>AugmentationSchema</code> objects. The objects are
+ * sorted according to the length of their target path from the shortest to
+ * the longest.
+ *
+ * @param module
+ * module from which is obtained list of all augmentation objects
+ * @return list of sorted <code>AugmentationSchema</code> objects obtained
+ * from <code>module</code>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module equals null</li>
+ * <li>if the set of augmentation equals null</li>
+ * </ul>
+ *
*/
private def List<AugmentationSchema> resolveAugmentations(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
return sortedAugmentations;
}
- /**\r
- * Converts whole <b>module</b> to <code>GeneratedType</code> object.\r
- * Firstly is created the module builder object from which is vally\r
- * obtained reference to <code>GeneratedType</code> object.\r
- *\r
- * @param module\r
- * module from which are obtained the module name, child nodes,\r
- * uses and is derived package name\r
- * @return <code>GeneratedType</code> which is internal representation of\r
- * the module\r
- * @throws IllegalArgumentException\r
- * if the module equals null\r
- *\r
+ /**
+ * Converts whole <b>module</b> to <code>GeneratedType</code> object.
+ * Firstly is created the module builder object from which is vally
+ * obtained reference to <code>GeneratedType</code> object.
+ *
+ * @param module
+ * module from which are obtained the module name, child nodes,
+ * uses and is derived package name
+ * @return <code>GeneratedType</code> which is internal representation of
+ * the module
+ * @throws IllegalArgumentException
+ * if the module equals null
+ *
*/
private def GeneratedTypeBuilder moduleToDataType(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
return moduleDataTypeBuilder;
}
- /**\r
- * Converts all <b>rpcs</b> inputs and outputs substatements of the module\r
- * to the list of <code>Type</code> objects. In addition are to containers\r
- * and lists which belong to input or output also part of returning list.\r
- *\r
- * @param module\r
- * module from which is obtained set of all rpc objects to\r
- * iterate over them\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if the module equals null</li>\r
- * <li>if the name of module equals null</li>\r
- * <li>if the set of child nodes equals null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Converts all <b>rpcs</b> inputs and outputs substatements of the module
+ * to the list of <code>Type</code> objects. In addition are to containers
+ * and lists which belong to input or output also part of returning list.
+ *
+ * @param module
+ * module from which is obtained set of all rpc objects to
+ * iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module equals null</li>
+ * <li>if the name of module equals null</li>
+ * <li>if the set of child nodes equals null</li>
+ * </ul>
+ *
*/
private def void rpcMethodsToGenType(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
genCtx.get(module).addTopLevelNodeType(interfaceBuilder)
}
- /**\r
- * Converts all <b>notifications</b> of the module to the list of\r
- * <code>Type</code> objects. In addition are to this list added containers\r
- * and lists which are part of this notification.\r
- *\r
- * @param module\r
- * module from which is obtained set of all notification objects\r
- * to iterate over them\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if the module equals null</li>\r
- * <li>if the name of module equals null</li>\r
- * <li>if the set of child nodes equals null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Converts all <b>notifications</b> of the module to the list of
+ * <code>Type</code> objects. In addition are to this list added containers
+ * and lists which are part of this notification.
+ *
+ * @param module
+ * module from which is obtained set of all notification objects
+ * to iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module equals null</li>
+ * <li>if the name of module equals null</li>
+ * <li>if the set of child nodes equals null</li>
+ * </ul>
+ *
*/
private def void notificationsToGenType(Module module) {
checkArgument(module !== null, "Module reference cannot be NULL.");
notificationInterface.addImplementsType(NOTIFICATION);
genCtx.get(module).addChildNodeType(notification.path, notificationInterface)
- // Notification object\r
+ // Notification object
resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface,
notification.childNodes);
- listenerInterface.addMethod("on" + notificationInterface.name) //\r
+ listenerInterface.addMethod("on" + notificationInterface.name) //
.setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification").
setReturnType(Types.VOID);
}
genCtx.get(module).addTopLevelNodeType(listenerInterface)
}
- /**\r
- * Converts all <b>identities</b> of the module to the list of\r
- * <code>Type</code> objects.\r
- *\r
- * @param module\r
- * module from which is obtained set of all identity objects to\r
- * iterate over them\r
- * @param context\r
- * schema context only used as input parameter for method\r
- * {@link identityToGenType}\r
- *\r
+ /**
+ * Converts all <b>identities</b> of the module to the list of
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained set of all identity objects to
+ * iterate over them
+ * @param context
+ * schema context only used as input parameter for method
+ * {@link identityToGenType}
+ *
*/
private def void allIdentitiesToGenTypes(Module module, SchemaContext context) {
val Set<IdentitySchemaNode> schemaIdentities = module.identities;
}
}
- /**\r
- * Converts the <b>identity</b> object to GeneratedType. Firstly it is\r
- * created transport object builder. If identity contains base identity then\r
- * reference to base identity is added to superior identity as its extend.\r
- * If identity doesn't contain base identity then only reference to abstract\r
- * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity\r
- * BaseIdentity} is added\r
- *\r
- * @param module current module\r
- * @param basePackageName\r
- * string contains the module package name\r
- * @param identity\r
- * IdentitySchemaNode which contains data about identity\r
- * @param context\r
- * SchemaContext which is used to get package and name\r
- * information about base of identity\r
- *\r
+ /**
+ * Converts the <b>identity</b> object to GeneratedType. Firstly it is
+ * created transport object builder. If identity contains base identity then
+ * reference to base identity is added to superior identity as its extend.
+ * If identity doesn't contain base identity then only reference to abstract
+ * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity
+ * BaseIdentity} is added
+ *
+ * @param module current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param identity
+ * IdentitySchemaNode which contains data about identity
+ * @param context
+ * SchemaContext which is used to get package and name
+ * information about base of identity
+ *
*/
private def void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity,
SchemaContext context) {
val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
newType.setExtendsType(gto);
}
- newType.setAbstract(true);\r
- val qname = identity.QName;\r
- \r
- newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname);\r
+ newType.setAbstract(true);
+ val qname = identity.QName;
+
+ newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname);
genCtx.get(module).addIdentityType(identity.QName,newType)
- }\r
- \r
+ }
+
private static def qnameConstant(GeneratedTypeBuilderBase<?> toBuilder, String constantName, QName name) {
- toBuilder.addConstant(QName.typeForClass,constantName,'''\r
- org.opendaylight.yangtools.yang.common.QName.create("«name.namespace»","«name.formattedRevision»","«name.localName»")\r
+ toBuilder.addConstant(QName.typeForClass,constantName,'''
+ org.opendaylight.yangtools.yang.common.QName.create("«name.namespace»","«name.formattedRevision»","«name.localName»")
''');
}
- /**\r
- * Converts all <b>groupings</b> of the module to the list of\r
- * <code>Type</code> objects. Firstly are groupings sorted according mutual\r
- * dependencies. At least dependent (independent) groupings are in the list\r
- * saved at first positions. For every grouping the record is added to map\r
- * {@link BindingGeneratorImpl#allGroupings allGroupings}\r
- *\r
- * @param module\r
- * current module\r
- * @param collection of groupings from which types will be generated\r
- *\r
+ /**
+ * Converts all <b>groupings</b> of the module to the list of
+ * <code>Type</code> objects. Firstly are groupings sorted according mutual
+ * dependencies. At least dependent (independent) groupings are in the list
+ * saved at first positions. For every grouping the record is added to map
+ * {@link BindingGeneratorImpl#allGroupings allGroupings}
+ *
+ * @param module
+ * current module
+ * @param collection of groupings from which types will be generated
+ *
*/
private def void groupingsToGenTypes(Module module, Collection<GroupingDefinition> groupings) {
val basePackageName = moduleNamespaceToPackageName(module);
}
}
- /**\r
- * Converts individual grouping to GeneratedType. Firstly generated type\r
- * builder is created and every child node of grouping is resolved to the\r
- * method.\r
- *\r
- * @param basePackageName\r
- * string contains the module package name\r
- * @param grouping\r
- * GroupingDefinition which contains data about grouping\r
- * @param module current module\r
- * @return GeneratedType which is generated from grouping (object of type\r
- * <code>GroupingDefinition</code>)\r
+ /**
+ * Converts individual grouping to GeneratedType. Firstly generated type
+ * builder is created and every child node of grouping is resolved to the
+ * method.
+ *
+ * @param basePackageName
+ * string contains the module package name
+ * @param grouping
+ * GroupingDefinition which contains data about grouping
+ * @param module current module
+ * @return GeneratedType which is generated from grouping (object of type
+ * <code>GroupingDefinition</code>)
*/
private def void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) {
val packageName = packageNameForGeneratedType(basePackageName, grouping.path);
processUsesAugments(grouping, module);
}
- /**\r
- * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base\r
- * type of <code>typeDefinition</code> is of the type ExtendedType then this\r
- * method is recursively called with this base type.\r
- *\r
- * @param typeDefinition\r
- * TypeDefinition in which should be EnumTypeDefinition found as\r
- * base type\r
- * @return EnumTypeDefinition if it is found inside\r
- * <code>typeDefinition</code> or <code>null</code> in other case\r
+ /**
+ * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base
+ * type of <code>typeDefinition</code> is of the type ExtendedType then this
+ * method is recursively called with this base type.
+ *
+ * @param typeDefinition
+ * TypeDefinition in which should be EnumTypeDefinition found as
+ * base type
+ * @return EnumTypeDefinition if it is found inside
+ * <code>typeDefinition</code> or <code>null</code> in other case
*/
private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition<?> typeDefinition) {
if (typeDefinition !== null) {
return null;
}
- /**\r
- * Adds enumeration builder created from <code>enumTypeDef</code> to\r
- * <code>typeBuilder</code>.\r
- *\r
- * Each <code>enumTypeDef</code> item is added to builder with its name and\r
- * value.\r
- *\r
- * @param enumTypeDef\r
- * EnumTypeDefinition contains enum data\r
- * @param enumName\r
- * string contains name which will be assigned to enumeration\r
- * builder\r
- * @param typeBuilder\r
- * GeneratedTypeBuilder to which will be enum builder assigned\r
- * @return enumeration builder which contains data from\r
- * <code>enumTypeDef</code>\r
+ /**
+ * Adds enumeration builder created from <code>enumTypeDef</code> to
+ * <code>typeBuilder</code>.
+ *
+ * Each <code>enumTypeDef</code> item is added to builder with its name and
+ * value.
+ *
+ * @param enumTypeDef
+ * EnumTypeDefinition contains enum data
+ * @param enumName
+ * string contains name which will be assigned to enumeration
+ * builder
+ * @param typeBuilder
+ * GeneratedTypeBuilder to which will be enum builder assigned
+ * @return enumeration builder which contains data from
+ * <code>enumTypeDef</code>
*/
private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName,
GeneratedTypeBuilder typeBuilder) {
return null;
}
- /**\r
- * Generates type builder for <code>module</code>.\r
- *\r
- * @param module\r
- * Module which is source of package name for generated type\r
- * builder\r
- * @param postfix\r
- * string which is added to the module class name representation\r
- * as suffix\r
- * @return instance of GeneratedTypeBuilder which represents\r
- * <code>module</code>.\r
- * @throws IllegalArgumentException\r
- * if <code>module</code> equals null\r
+ /**
+ * Generates type builder for <code>module</code>.
+ *
+ * @param module
+ * Module which is source of package name for generated type
+ * builder
+ * @param postfix
+ * string which is added to the module class name representation
+ * as suffix
+ * @return instance of GeneratedTypeBuilder which represents
+ * <code>module</code>.
+ * @throws IllegalArgumentException
+ * if <code>module</code> equals null
*/
private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) {
checkArgument(module !== null, "Module reference cannot be NULL.");
return new GeneratedTypeBuilderImpl(packageName, moduleName);
}
- /**\r
- * Converts <code>augSchema</code> to list of <code>Type</code> which\r
- * contains generated type for augmentation. In addition there are also\r
- * generated types for all containers, list and choices which are child of\r
- * <code>augSchema</code> node or a generated types for cases are added if\r
- * augmented node is choice.\r
- *\r
- * @param augmentPackageName\r
- * string with the name of the package to which the augmentation\r
- * belongs\r
- * @param augSchema\r
- * AugmentationSchema which is contains data about augmentation\r
- * (target path, childs...)\r
- * @param module current module\r
- * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement)\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>augmentPackageName</code> equals null</li>\r
- * <li>if <code>augSchema</code> equals null</li>\r
- * <li>if target path of <code>augSchema</code> equals null</li>\r
- * </ul>\r
+ /**
+ * Converts <code>augSchema</code> to list of <code>Type</code> which
+ * contains generated type for augmentation. In addition there are also
+ * generated types for all containers, list and choices which are child of
+ * <code>augSchema</code> node or a generated types for cases are added if
+ * augmented node is choice.
+ *
+ * @param augmentPackageName
+ * string with the name of the package to which the augmentation
+ * belongs
+ * @param augSchema
+ * AugmentationSchema which is contains data about augmentation
+ * (target path, childs...)
+ * @param module current module
+ * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement)
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>augmentPackageName</code> equals null</li>
+ * <li>if <code>augSchema</code> equals null</li>
+ * <li>if target path of <code>augSchema</code> equals null</li>
+ * </ul>
*/
- private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
- UsesNode parentUsesNode) {
+ private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) {
checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
checkState(augSchema.targetPath !== null,
"Augmentation Schema does not contain Target Path (Target Path is NULL).");
- processUsesAugments(augSchema, module);\r
+ processUsesAugments(augSchema, module);
val targetPath = augSchema.targetPath;
- var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);\r
+ var SchemaNode targetSchemaNode = null
+
+ targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) {
- if (parentUsesNode == null) {
- targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode);
- } else {
- targetSchemaNode = findOriginalTargetFromGrouping(targetSchemaNode.QName.localName, parentUsesNode);
- }
+ targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode);
if (targetSchemaNode == null) {
throw new NullPointerException(
- "Failed to find target node from grouping for augmentation " + augSchema + " in module " +
+ "Failed to find target node from grouping in augmentation " + augSchema + " in module " +
module.name);
}
- }\r
-\r
- if (targetSchemaNode == null) {\r
- throw new IllegalArgumentException("augment target not found: " + targetPath)\r
- }\r
-
- if (targetSchemaNode !== null) {
- var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
- if (targetTypeBuilder === null) {
- targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
- }
- if (targetTypeBuilder === null) {
- throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
- }
- if (!(targetSchemaNode instanceof ChoiceNode)) {
- var packageName = augmentPackageName;
- if (parentUsesNode != null) {
- packageName = packageNameForGeneratedType(augmentPackageName, augSchema.targetPath);
- }
- val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
- targetTypeBuilder.toInstance, augSchema);
- genCtx.get(module).addAugmentType(augTypeBuilder)\r
- genCtx.get(module).addTypeToAugmentation(augTypeBuilder,augSchema);
- } else {
- generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
- targetSchemaNode as ChoiceNode, augSchema.childNodes);
+ }
+ if (targetSchemaNode == null) {
+ throw new IllegalArgumentException("augment target not found: " + targetPath)
+ }
+
+ var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
+ if (targetTypeBuilder === null) {
+ targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
+ }
+ if (targetTypeBuilder === null) {
+ throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+ }
+
+ if (!(targetSchemaNode instanceof ChoiceNode)) {
+ var packageName = augmentPackageName;
+ val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+ targetTypeBuilder.toInstance, augSchema);
+ genCtx.get(module).addAugmentType(augTypeBuilder)
+ genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+ } else {
+ generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
+ targetSchemaNode as ChoiceNode, augSchema.childNodes);
+ }
+ }
+
+ private def void usesAugmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
+ UsesNode usesNode, DataNodeContainer usesNodeParent) {
+ checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
+ checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
+ checkState(augSchema.targetPath !== null,
+ "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+
+ processUsesAugments(augSchema, module);
+ val targetPath = augSchema.targetPath;
+ var SchemaNode targetSchemaNode = null
+ targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode);
+ if (targetSchemaNode == null) {
+ throw new IllegalArgumentException("augment target not found: " + targetPath)
+ }
+
+ var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
+ if (targetTypeBuilder === null) {
+ targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
+ }
+ if (targetTypeBuilder === null) {
+ throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+ }
+
+ if (!(targetSchemaNode instanceof ChoiceNode)) {
+ var packageName = augmentPackageName;
+ if (usesNodeParent instanceof SchemaNode) {
+ packageName = packageNameForGeneratedType(augmentPackageName, (usesNodeParent as SchemaNode).path, true)
}
+ val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+ targetTypeBuilder.toInstance, augSchema);
+ genCtx.get(module).addAugmentType(augTypeBuilder)
+ genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+ } else {
+ generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
+ targetSchemaNode as ChoiceNode, augSchema.childNodes);
}
}
- /**\r
- * Utility method which search for original node defined in grouping.\r
+ /**
+ * Utility method which search for original node defined in grouping.
*/
private def DataSchemaNode findOriginal(DataSchemaNode node) {
var DataSchemaNode result = findCorrectTargetFromGrouping(node);
return null
}
- var QName currentName = node.QName\r
+ var QName currentName = node.QName
var Object currentNode = node
- var Object parent = node;\r
- val tmpPath = new ArrayList<QName>()\r
- val tmpTree = new ArrayList<SchemaNode>()\r
+ var Object parent = node;
+ val tmpPath = new ArrayList<QName>()
+ val tmpTree = new ArrayList<SchemaNode>()
var AugmentationSchema augment = null;
- do {\r
- val SchemaPath sp = (parent as SchemaNode).path\r
- val List<QName> names = sp.path\r
- val List<QName> newNames = new ArrayList(names)\r
- newNames.remove(newNames.size - 1)\r
- val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)\r
- parent = findDataSchemaNode(schemaContext, newSp)\r
+ do {
+ val SchemaPath sp = (parent as SchemaNode).path
+ val List<QName> names = sp.path
+ val List<QName> newNames = new ArrayList(names)
+ newNames.remove(newNames.size - 1)
+ val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+ parent = findDataSchemaNode(schemaContext, newSp)
if (parent instanceof AugmentationTarget) {
- tmpPath.add(currentName);\r
- tmpTree.add(currentNode as SchemaNode)\r
+ tmpPath.add(currentName);
+ tmpTree.add(currentNode as SchemaNode)
augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName);
if (augment == null) {
- currentName = (parent as DataSchemaNode).QName\r
+ currentName = (parent as DataSchemaNode).QName
currentNode = parent
}
}
if (augment == null) {
return null;
} else {
- Collections.reverse(tmpPath);\r
+ Collections.reverse(tmpPath);
Collections.reverse(tmpTree);
var Object actualParent = augment;
var DataSchemaNode result = null;
}
}
- if (result.addedByUses) {\r
+ if (result.addedByUses) {
result = findCorrectTargetFromAugmentGrouping(result, augment, tmpTree);
}
}
private def AugmentationSchema findNodeInAugment(Collection<AugmentationSchema> augments, QName name) {
- for (augment : augments) {\r
- val DataSchemaNode node = augment.getDataChildByName(name);\r
+ for (augment : augments) {
+ val DataSchemaNode node = augment.getDataChildByName(name);
if (node != null) {
return augment;
}
}
return null;
}
-\r
- private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) {\r
- if (node.path.path.size == 1) {\r
- // uses is under module statement\r
- val Module m = findParentModule(schemaContext, node);\r
- var DataSchemaNode result = null;\r
- for (u : m.uses) {\r
- var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path);\r
- if (!(targetGrouping instanceof GroupingDefinition)) {\r
- throw new IllegalArgumentException("Failed to generate code for augment in " + u);\r
- }\r
- var gr = targetGrouping as GroupingDefinition;\r
- result = gr.getDataChildByName(node.QName.localName);\r
- }\r
- if (result == null) {\r
- throw new IllegalArgumentException("Failed to generate code for augment")\r
- }\r
- return result\r
- } else {\r
- var DataSchemaNode result = null;\r
- var QName currentName = node.QName\r
- var tmpPath = new ArrayList<QName>()\r
- var Object parent = null\r
+
+ private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) {
+ if (node.path.path.size == 1) {
+ // uses is under module statement
+ val Module m = findParentModule(schemaContext, node);
+ var DataSchemaNode result = null;
+ for (u : m.uses) {
+ var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path);
+ if (!(targetGrouping instanceof GroupingDefinition)) {
+ throw new IllegalArgumentException("Failed to generate code for augment in " + u);
+ }
+ var gr = targetGrouping as GroupingDefinition;
+ result = gr.getDataChildByName(node.QName.localName);
+ }
+ if (result == null) {
+ throw new IllegalArgumentException("Failed to generate code for augment")
+ }
+ return result
+ } else {
+ var DataSchemaNode result = null;
+ var QName currentName = node.QName
+ var tmpPath = new ArrayList<QName>()
+ var Object parent = null
val SchemaPath sp = node.path
val List<QName> names = sp.path
newNames.remove(newNames.size - 1)
val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
parent = findDataSchemaNode(schemaContext, newSp)
-\r
- do {\r
- tmpPath.add(currentName);\r
- if (parent instanceof DataNodeContainer) {\r
- val dataNodeParent = parent as DataNodeContainer;\r
- for (u : dataNodeParent.uses) {\r
- if (result == null) {\r
- result = getResultFromUses(u, currentName.localName)\r
- }\r
- }\r
- }\r
+
+ do {
+ tmpPath.add(currentName);
+ if (parent instanceof DataNodeContainer) {
+ val dataNodeParent = parent as DataNodeContainer;
+ for (u : dataNodeParent.uses) {
+ if (result == null) {
+ result = getResultFromUses(u, currentName.localName)
+ }
+ }
+ }
if (result == null) {
currentName = (parent as SchemaNode).QName
if (parent instanceof SchemaNode) {
} else {
throw new IllegalArgumentException("Failed to generate code for augment")
}
- }\r
- } while (result == null && !(parent instanceof Module));\r
-\r
- if (result != null) {\r
- result = getTargetNode(tmpPath, result)\r
- }\r
- return result;\r
- }\r
- }\r
-\r
+ }
+ } while (result == null && !(parent instanceof Module));
+
+ if (result != null) {
+ result = getTargetNode(tmpPath, result)
+ }
+ return result;
+ }
+ }
+
private def DataSchemaNode findCorrectTargetFromAugmentGrouping(DataSchemaNode node, AugmentationSchema parentNode,
- List<SchemaNode> dataTree) {\r
-\r
+ List<SchemaNode> dataTree) {
+
var DataSchemaNode result = null;
var QName currentName = node.QName
- var tmpPath = new ArrayList<QName>()\r
- tmpPath.add(currentName)\r
- var int i = 1;\r
+ var tmpPath = new ArrayList<QName>()
+ tmpPath.add(currentName)
+ var int i = 1;
var Object parent = null
-\r
- do {\r
+
+ do {
if (dataTree.size < 2 || dataTree.size == i) {
parent = parentNode
} else {
parent = dataTree.get(dataTree.size - (i+1))
tmpPath.add((parent as SchemaNode).QName)
- }\r
+ }
val dataNodeParent = parent as DataNodeContainer;
for (u : dataNodeParent.uses) {
- if (result == null) {\r
+ if (result == null) {
result = getResultFromUses(u, currentName.localName)
}
}
if (result == null) {
- i = i + 1\r
+ i = i + 1
currentName = (parent as SchemaNode).QName
}
} while (result == null);
-\r
+
if (result != null) {
- result = getTargetNode(tmpPath, result)\r
+ result = getTargetNode(tmpPath, result)
}
return result;
- }\r
-\r
+ }
+
private def getResultFromUses(UsesNode u, String currentName) {
var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path)
if (!(targetGrouping instanceof GroupingDefinition)) {
}
var gr = targetGrouping as GroupingDefinition
return gr.getDataChildByName(currentName)
- }\r
-\r
+ }
+
private def getTargetNode(List<QName> tmpPath, DataSchemaNode node) {
var DataSchemaNode result = node
if (tmpPath.size == 1) {
Collections.reverse(tmpPath);
tmpPath.remove(0);
- for (name : tmpPath) {\r
- // searching by local name is must, because node has different namespace in its original location\r
- if (newParent instanceof DataNodeContainer) {\r
- newParent = (newParent as DataNodeContainer).getDataChildByName(name.localName);\r
- } else {\r
- newParent = (newParent as ChoiceNode).getCaseNodeByName(name.localName);\r
+ for (name : tmpPath) {
+ // searching by local name is must, because node has different namespace in its original location
+ if (newParent instanceof DataNodeContainer) {
+ newParent = (newParent as DataNodeContainer).getDataChildByName(name.localName);
+ } else {
+ newParent = (newParent as ChoiceNode).getCaseNodeByName(name.localName);
}
}
if (newParent != null && newParent.addedByUses) {
}
return newParent;
}
- }\r
+ }
- /**\r
- * Convenient method to find node added by uses statement.\r
+ /**
+ * Convenient method to find node added by uses statement.
*/
- private def DataSchemaNode findOriginalTargetFromGrouping(String targetSchemaNodeName, UsesNode parentUsesNode) {
+ private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, UsesNode parentUsesNode) {
var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path);
if (!(targetGrouping instanceof GroupingDefinition)) {
throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode);
}
var grouping = targetGrouping as GroupingDefinition;
- var result = grouping.getDataChildByName(targetSchemaNodeName);
+ var SchemaNode result = grouping;
+ val List<QName> path = targetPath.path
+ for (node : path) {
+ // finding by local name is valid, grouping cannot contain nodes with same name and different namespace
+ if (result instanceof DataNodeContainer) {
+ result = (result as DataNodeContainer).getDataChildByName(node.localName)
+ } else if (result instanceof ChoiceNode) {
+ result = (result as ChoiceNode).getCaseNodeByName(node.localName)
+ }
+ }
if (result == null) {
return null;
}
- var boolean fromUses = result.addedByUses;
+ val String targetSchemaNodeName = result.QName.localName;
+ var boolean fromUses = (result as DataSchemaNode).addedByUses
var Iterator<UsesNode> groupingUses = grouping.uses.iterator;
while (fromUses) {
if (groupingUses.hasNext()) {
grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition;
result = grouping.getDataChildByName(targetSchemaNodeName);
- fromUses = result.addedByUses;
+ fromUses = (result as DataSchemaNode).addedByUses;
} else {
throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode);
}
}
- return result;
+ return result as DataSchemaNode
}
- /**\r
- * Returns a generated type builder for an augmentation.\r
- *\r
- * The name of the type builder is equal to the name of augmented node with\r
- * serial number as suffix.\r
- *\r
- * @param module current module\r
- * @param augmentPackageName\r
- * string with contains the package name to which the augment\r
- * belongs\r
- * @param basePackageName\r
- * string with the package name to which the augmented node\r
- * belongs\r
- * @param targetTypeRef\r
- * target type\r
- * @param augSchema\r
- * augmentation schema which contains data about the child nodes\r
- * and uses of augment\r
- * @return generated type builder for augment\r
+ /**
+ * Returns a generated type builder for an augmentation.
+ *
+ * The name of the type builder is equal to the name of augmented node with
+ * serial number as suffix.
+ *
+ * @param module current module
+ * @param augmentPackageName
+ * string with contains the package name to which the augment
+ * belongs
+ * @param basePackageName
+ * string with the package name to which the augmented node
+ * belongs
+ * @param targetTypeRef
+ * target type
+ * @param augSchema
+ * augmentation schema which contains data about the child nodes
+ * and uses of augment
+ * @return generated type builder for augment
*/
private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName,
String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) {
return augTypeBuilder;
}
- /**\r
- *\r
- * @param unknownSchemaNodes\r
- * @return nodeParameter of UnknownSchemaNode\r
+ /**
+ *
+ * @param unknownSchemaNodes
+ * @return nodeParameter of UnknownSchemaNode
*/
private def String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {
for (unknownSchemaNode : unknownSchemaNodes) {
return null;
}
- /**\r
- * Returns first unique name for the augment generated type builder. The\r
- * generated type builder name for augment consists from name of augmented\r
- * node and serial number of its augmentation.\r
- *\r
- * @param builders\r
- * map of builders which were created in the package to which the\r
- * augmentation belongs\r
- * @param genTypeName\r
- * string with name of augmented node\r
- * @return string with unique name for augmentation builder\r
+ /**
+ * Returns first unique name for the augment generated type builder. The
+ * generated type builder name for augment consists from name of augmented
+ * node and serial number of its augmentation.
+ *
+ * @param builders
+ * map of builders which were created in the package to which the
+ * augmentation belongs
+ * @param genTypeName
+ * string with name of augmented node
+ * @return string with unique name for augmentation builder
*/
private def String augGenTypeName(Map<String, GeneratedTypeBuilder> builders, String genTypeName) {
var index = 1;
return genTypeName + index;
}
- /**\r
- * Adds the methods to <code>typeBuilder</code> which represent subnodes of\r
- * node for which <code>typeBuilder</code> was created.\r
- *\r
- * The subnodes aren't mapped to the methods if they are part of grouping or\r
- * augment (in this case are already part of them).\r
- *\r
- * @param module current module\r
- * @param basePackageName\r
- * string contains the module package name\r
- * @param parent\r
- * generated type builder which represents any node. The subnodes\r
- * of this node are added to the <code>typeBuilder</code> as\r
- * methods. The subnode can be of type leaf, leaf-list, list,\r
- * container, choice.\r
- * @param childOf parent type\r
- * @param schemaNodes\r
- * set of data schema nodes which are the children of the node\r
- * for which <code>typeBuilder</code> was created\r
- * @return generated type builder which is the same builder as input\r
- * parameter. The getter methods (representing child nodes) could be\r
- * added to it.\r
+ /**
+ * Adds the methods to <code>typeBuilder</code> which represent subnodes of
+ * node for which <code>typeBuilder</code> was created.
+ *
+ * The subnodes aren't mapped to the methods if they are part of grouping or
+ * augment (in this case are already part of them).
+ *
+ * @param module current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param parent
+ * generated type builder which represents any node. The subnodes
+ * of this node are added to the <code>typeBuilder</code> as
+ * methods. The subnode can be of type leaf, leaf-list, list,
+ * container, choice.
+ * @param childOf parent type
+ * @param schemaNodes
+ * set of data schema nodes which are the children of the node
+ * for which <code>typeBuilder</code> was created
+ * @return generated type builder which is the same builder as input
+ * parameter. The getter methods (representing child nodes) could be
+ * added to it.
*/
private def GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName,
GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
return parent;
}
- /**\r
- * Adds the methods to <code>typeBuilder</code> what represents subnodes of\r
- * node for which <code>typeBuilder</code> was created.\r
- *\r
- * @param module current module\r
- * @param basePackageName\r
- * string contains the module package name\r
- * @param typeBuilder\r
- * generated type builder which represents any node. The subnodes\r
- * of this node are added to the <code>typeBuilder</code> as\r
- * methods. The subnode can be of type leaf, leaf-list, list,\r
- * container, choice.\r
- * @param childOf parent type\r
- * @param schemaNodes\r
- * set of data schema nodes which are the children of the node\r
- * for which <code>typeBuilder</code> was created\r
- * @return generated type builder which is the same object as the input\r
- * parameter <code>typeBuilder</code>. The getter method could be\r
- * added to it.\r
+ /**
+ * Adds the methods to <code>typeBuilder</code> what represents subnodes of
+ * node for which <code>typeBuilder</code> was created.
+ *
+ * @param module current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param typeBuilder
+ * generated type builder which represents any node. The subnodes
+ * of this node are added to the <code>typeBuilder</code> as
+ * methods. The subnode can be of type leaf, leaf-list, list,
+ * container, choice.
+ * @param childOf parent type
+ * @param schemaNodes
+ * set of data schema nodes which are the children of the node
+ * for which <code>typeBuilder</code> was created
+ * @return generated type builder which is the same object as the input
+ * parameter <code>typeBuilder</code>. The getter method could be
+ * added to it.
*/
private def GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName,
GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
return typeBuilder;
}
- /**\r
- * Adds to <code>typeBuilder</code> a method which is derived from\r
- * <code>schemaNode</code>.\r
- *\r
- * @param basePackageName\r
- * string with the module package name\r
- * @param node\r
- * data schema node which is added to <code>typeBuilder</code> as\r
- * a method\r
- * @param typeBuilder\r
- * generated type builder to which is <code>schemaNode</code>\r
- * added as a method.\r
- * @param childOf parent type\r
- * @param module current module\r
+ /**
+ * Adds to <code>typeBuilder</code> a method which is derived from
+ * <code>schemaNode</code>.
+ *
+ * @param basePackageName
+ * string with the module package name
+ * @param node
+ * data schema node which is added to <code>typeBuilder</code> as
+ * a method
+ * @param typeBuilder
+ * generated type builder to which is <code>schemaNode</code>
+ * added as a method.
+ * @param childOf parent type
+ * @param module current module
*/
private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node,
GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) {
}
}
- /**\r
- * Converts <code>choiceNode</code> to the list of generated types for\r
- * choice and its cases.\r
- *\r
- * The package names for choice and for its cases are created as\r
- * concatenation of the module package (<code>basePackageName</code>) and\r
- * names of all parents node.\r
- *\r
- * @param module current module\r
- * @param basePackageName\r
- * string with the module package name\r
- * @param parent parent type\r
- * @param childOf concrete parent for case child nodes\r
- * @param choiceNode\r
- * choice node which is mapped to generated type. Also child\r
- * nodes - cases are mapped to generated types.\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>basePackageName</code> equals null</li>\r
- * <li>if <code>choiceNode</code> equals null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Converts <code>choiceNode</code> to the list of generated types for
+ * choice and its cases.
+ *
+ * The package names for choice and for its cases are created as
+ * concatenation of the module package (<code>basePackageName</code>) and
+ * names of all parents node.
+ *
+ * @param module current module
+ * @param basePackageName
+ * string with the module package name
+ * @param parent parent type
+ * @param childOf concrete parent for case child nodes
+ * @param choiceNode
+ * choice node which is mapped to generated type. Also child
+ * nodes - cases are mapped to generated types.
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> equals null</li>
+ * <li>if <code>choiceNode</code> equals null</li>
+ * </ul>
+ *
*/
private def void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent,
ChoiceNode choiceNode) {
}
}
- /**\r
- * Converts <code>caseNodes</code> set to list of corresponding generated\r
- * types.\r
- *\r
- * For every <i>case</i> which isn't added through augment or <i>uses</i> is\r
- * created generated type builder. The package names for the builder is\r
- * created as concatenation of the module package (\r
- * <code>basePackageName</code>) and names of all parents nodes of the\r
- * concrete <i>case</i>. There is also relation "<i>implements type</i>"\r
- * between every case builder and <i>choice</i> type\r
- *\r
- * @param basePackageName\r
- * string with the module package name\r
- * @param refChoiceType\r
- * type which represents superior <i>case</i>\r
- * @param caseNodes\r
- * set of choice case nodes which are mapped to generated types\r
- * @return list of generated types for <code>caseNodes</code>.\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>basePackageName</code> equals null</li>\r
- * <li>if <code>refChoiceType</code> equals null</li>\r
- * <li>if <code>caseNodes</code> equals null</li>\r
- * </ul>\r
- * *\r
+ /**
+ * Converts <code>caseNodes</code> set to list of corresponding generated
+ * types.
+ *
+ * For every <i>case</i> which isn't added through augment or <i>uses</i> is
+ * created generated type builder. The package names for the builder is
+ * created as concatenation of the module package (
+ * <code>basePackageName</code>) and names of all parents nodes of the
+ * concrete <i>case</i>. There is also relation "<i>implements type</i>"
+ * between every case builder and <i>choice</i> type
+ *
+ * @param basePackageName
+ * string with the module package name
+ * @param refChoiceType
+ * type which represents superior <i>case</i>
+ * @param caseNodes
+ * set of choice case nodes which are mapped to generated types
+ * @return list of generated types for <code>caseNodes</code>.
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> equals null</li>
+ * <li>if <code>refChoiceType</code> equals null</li>
+ * <li>if <code>caseNodes</code> equals null</li>
+ * </ul>
+ * *
*/
private def void generateTypesFromChoiceCases(Module module, String basePackageName,
GeneratedTypeBuilder choiceParent, Type refChoiceType, ChoiceNode choiceNode) {
genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder)
val Set<DataSchemaNode> caseChildNodes = caseNode.childNodes
if (caseChildNodes !== null) {
- var Object parentNode = null\r
- val SchemaPath nodeSp = choiceNode.path\r
- val List<QName> nodeNames = nodeSp.path\r
- val List<QName> nodeNewNames = new ArrayList(nodeNames)\r
- nodeNewNames.remove(nodeNewNames.size - 1)\r
- val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)\r
- parentNode = findDataSchemaNode(schemaContext, nodeNewSp)\r
+ var Object parentNode = null
+ val SchemaPath nodeSp = choiceNode.path
+ val List<QName> nodeNames = nodeSp.path
+ val List<QName> nodeNewNames = new ArrayList(nodeNames)
+ nodeNewNames.remove(nodeNewNames.size - 1)
+ val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+ parentNode = findDataSchemaNode(schemaContext, nodeNewSp)
var SchemaNode parent
if (parentNode instanceof AugmentationSchema) {
}
parent = targetSchemaNode
} else {
- val SchemaPath sp = choiceNode.path\r
- val List<QName> names = sp.path\r
- val List<QName> newNames = new ArrayList(names)\r
- newNames.remove(newNames.size - 1)\r
- val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)\r
- parent = findDataSchemaNode(schemaContext, newSp)\r
+ val SchemaPath sp = choiceNode.path
+ val List<QName> names = sp.path
+ val List<QName> newNames = new ArrayList(names)
+ newNames.remove(newNames.size - 1)
+ val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+ parent = findDataSchemaNode(schemaContext, newSp)
}
var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path)
resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes)
}
}
- /**\r
- * Generates list of generated types for all the cases of a choice which are\r
- * added to the choice through the augment.\r
- *\r
- *\r
- * @param basePackageName\r
- * string contains name of package to which augment belongs. If\r
- * an augmented choice is from an other package (pcg1) than an\r
- * augmenting choice (pcg2) then case's of the augmenting choice\r
- * will belong to pcg2.\r
- * @param refChoiceType\r
- * Type which represents the choice to which case belongs. Every\r
- * case has to contain its choice in extend part.\r
- * @param caseNodes\r
- * set of choice case nodes for which is checked if are/aren't\r
- * added to choice through augmentation\r
- * @return list of generated types which represents augmented cases of\r
- * choice <code>refChoiceType</code>\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>basePackageName</code> equals null</li>\r
- * <li>if <code>refChoiceType</code> equals null</li>\r
- * <li>if <code>caseNodes</code> equals null</li>\r
- * </ul>\r
+ /**
+ * Generates list of generated types for all the cases of a choice which are
+ * added to the choice through the augment.
+ *
+ *
+ * @param basePackageName
+ * string contains name of package to which augment belongs. If
+ * an augmented choice is from an other package (pcg1) than an
+ * augmenting choice (pcg2) then case's of the augmenting choice
+ * will belong to pcg2.
+ * @param refChoiceType
+ * Type which represents the choice to which case belongs. Every
+ * case has to contain its choice in extend part.
+ * @param caseNodes
+ * set of choice case nodes for which is checked if are/aren't
+ * added to choice through augmentation
+ * @return list of generated types which represents augmented cases of
+ * choice <code>refChoiceType</code>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> equals null</li>
+ * <li>if <code>refChoiceType</code> equals null</li>
+ * <li>if <code>caseNodes</code> equals null</li>
+ * </ul>
*/
private def void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType,
ChoiceNode targetNode, Set<DataSchemaNode> augmentedNodes) {
val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
caseTypeBuilder.addImplementsType(targetType);
- var SchemaNode parent = null\r
- val SchemaPath nodeSp = targetNode.path\r
- val List<QName> nodeNames = nodeSp.path\r
- val List<QName> nodeNewNames = new ArrayList(nodeNames)\r
- nodeNewNames.remove(nodeNewNames.size - 1)\r
- val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)\r
- parent = findDataSchemaNode(schemaContext, nodeNewSp)\r
+ var SchemaNode parent = null
+ val SchemaPath nodeSp = targetNode.path
+ val List<QName> nodeNames = nodeSp.path
+ val List<QName> nodeNewNames = new ArrayList(nodeNames)
+ nodeNewNames.remove(nodeNewNames.size - 1)
+ val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+ parent = findDataSchemaNode(schemaContext, nodeNewSp)
var GeneratedTypeBuilder childOfType = null;
if (parent instanceof Module) {
}
- /**\r
- * Converts <code>leaf</code> to the getter method which is added to\r
- * <code>typeBuilder</code>.\r
- *\r
- * @param typeBuilder\r
- * generated type builder to which is added getter method as\r
- * <code>leaf</code> mapping\r
- * @param leaf\r
- * leaf schema node which is mapped as getter method which is\r
- * added to <code>typeBuilder</code>\r
- * @return boolean value\r
- * <ul>\r
- * <li>false - if <code>leaf</code> or <code>typeBuilder</code> are\r
- * null</li>\r
- * <li>true - in other cases</li>\r
- * </ul>\r
+ /**
+ * Converts <code>leaf</code> to the getter method which is added to
+ * <code>typeBuilder</code>.
+ *
+ * @param typeBuilder
+ * generated type builder to which is added getter method as
+ * <code>leaf</code> mapping
+ * @param leaf
+ * leaf schema node which is mapped as getter method which is
+ * added to <code>typeBuilder</code>
+ * @return boolean value
+ * <ul>
+ * <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
+ * null</li>
+ * <li>true - in other cases</li>
+ * </ul>
*/
private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
if ((leaf !== null) && (typeBuilder !== null)) {
}
(typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);
} else if (typeDef instanceof UnionType) {
- genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);\r
- if (genTOBuilder !== null) {\r
- returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)\r
+ genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
+ if (genTOBuilder !== null) {
+ returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
}
} else if (typeDef instanceof BitsTypeDefinition) {
- genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);\r
- if (genTOBuilder !== null) {\r
- returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
+ genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
+ if (genTOBuilder !== null) {
+ returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
}
} else {
val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
return null;
}
- /**\r
- * Converts <code>leaf</code> schema node to property of generated TO\r
- * builder.\r
- *\r
- * @param toBuilder\r
- * generated TO builder to which is <code>leaf</code> added as\r
- * property\r
- * @param leaf\r
- * leaf schema node which is added to <code>toBuilder</code> as\r
- * property\r
- * @param isReadOnly\r
- * boolean value which says if leaf property is|isn't read only\r
- * @return boolean value\r
- * <ul>\r
- * <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf\r
- * name equals null or if leaf is added by <i>uses</i>.</li>\r
- * <li>true - other cases</li>\r
- * </ul>\r
+ /**
+ * Converts <code>leaf</code> schema node to property of generated TO
+ * builder.
+ *
+ * @param toBuilder
+ * generated TO builder to which is <code>leaf</code> added as
+ * property
+ * @param leaf
+ * leaf schema node which is added to <code>toBuilder</code> as
+ * property
+ * @param isReadOnly
+ * boolean value which says if leaf property is|isn't read only
+ * @return boolean value
+ * <ul>
+ * <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
+ * name equals null or if leaf is added by <i>uses</i>.</li>
+ * <li>true - other cases</li>
+ * </ul>
*/
private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,
boolean isReadOnly, Module module) {
leafDesc = "";
}
- if (leafName !== null) {\r
+ if (leafName !== null) {
var Type returnType = null;
- val TypeDefinition<?> typeDef = leaf.type;\r
- if (typeDef instanceof UnionTypeDefinition) {\r
- // GeneratedType for this type definition should be already created\r
- var qname = typeDef.QName\r
- var Module unionModule = null\r
- if (qname.prefix == null || qname.prefix.empty) {\r
- unionModule = module\r
- } else {\r
- unionModule = findModuleFromImports(module.imports, qname.prefix)\r
- }\r
- val ModuleContext mc = genCtx.get(unionModule)\r
- returnType = mc.typedefs.get(typeDef.path)\r
- } else {\r
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);\r
+ val TypeDefinition<?> typeDef = leaf.type;
+ if (typeDef instanceof UnionTypeDefinition) {
+ // GeneratedType for this type definition should be already created
+ var qname = typeDef.QName
+ var Module unionModule = null
+ if (qname.prefix == null || qname.prefix.empty) {
+ unionModule = module
+ } else {
+ unionModule = findModuleFromImports(module.imports, qname.prefix)
+ }
+ val ModuleContext mc = genCtx.get(unionModule)
+ returnType = mc.typedefs.get(typeDef.path)
+ } else {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
}
if (returnType !== null) {
return false;
}
- /**\r
- * Converts <code>node</code> leaf list schema node to getter method of\r
- * <code>typeBuilder</code>.\r
- *\r
- * @param typeBuilder\r
- * generated type builder to which is <code>node</code> added as\r
- * getter method\r
- * @param node\r
- * leaf list schema node which is added to\r
- * <code>typeBuilder</code> as getter method\r
- * @return boolean value\r
- * <ul>\r
- * <li>true - if <code>node</code>, <code>typeBuilder</code>,\r
- * nodeName equal null or <code>node</code> is added by <i>uses</i></li>\r
- * <li>false - other cases</li>\r
- * </ul>\r
+ /**
+ * Converts <code>node</code> leaf list schema node to getter method of
+ * <code>typeBuilder</code>.
+ *
+ * @param typeBuilder
+ * generated type builder to which is <code>node</code> added as
+ * getter method
+ * @param node
+ * leaf list schema node which is added to
+ * <code>typeBuilder</code> as getter method
+ * @return boolean value
+ * <ul>
+ * <li>true - if <code>node</code>, <code>typeBuilder</code>,
+ * nodeName equal null or <code>node</code> is added by <i>uses</i></li>
+ * <li>false - other cases</li>
+ * </ul>
*/
private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) {
if ((node !== null) && (typeBuilder !== null)) {
nodeDesc = "";
}
if (nodeName !== null && !node.isAddedByUses()) {
- val TypeDefinition<?> typeDef = node.type;\r
- val parentModule = findParentModule(schemaContext, node);\r
-\r
- var Type returnType = null;\r
- if (typeDef instanceof EnumTypeDefinition) {\r
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);\r
- val enumTypeDef = typeDef as EnumTypeDefinition;\r
- val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder);\r
- returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);\r
- (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);\r
- } else if (typeDef instanceof UnionType) {\r
- val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);\r
- if (genTOBuilder !== null) {\r
- returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)\r
+ val TypeDefinition<?> typeDef = node.type;
+ val parentModule = findParentModule(schemaContext, node);
+
+ var Type returnType = null;
+ if (typeDef instanceof EnumTypeDefinition) {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);
+ val enumTypeDef = typeDef as EnumTypeDefinition;
+ val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder);
+ returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);
+ (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);
+ } else if (typeDef instanceof UnionType) {
+ val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
+ if (genTOBuilder !== null) {
+ returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
}
- } else if (typeDef instanceof BitsTypeDefinition) {\r
- val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);\r
- returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
- } else {\r
- val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);\r
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);\r
- }\r
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
+ returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+ } else {
+ val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);
+ }
val listType = Types.listTypeFor(returnType);
constructGetter(typeBuilder, nodeName.localName, nodeDesc, listType);
}
return false;
}
-\r
+
private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
GeneratedTypeBuilder typeBuilder, Module parentModule) {
val Type returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
genTOBuilder.setIsUnion(true);
(typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
- // union builder\r
+ // union builder
val GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),
genTOBuilder.getName() + "Builder");
unionBuilder.setIsUnionBuilder(true);
types.add(unionBuilder.toInstance)
}
return returnType
- }\r
+ }
private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
return addDefaultInterfaceDefinition(packageName, schemaNode, null);
}
- /**\r
- * Instantiates generated type builder with <code>packageName</code> and\r
- * <code>schemaNode</code>.\r
- *\r
- * The new builder always implements\r
- * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />\r
- * If <code>schemaNode</code> is instance of GroupingDefinition it also\r
- * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable\r
- * Augmentable}.<br />\r
- * If <code>schemaNode</code> is instance of\r
- * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer\r
- * DataNodeContainer} it can also implement nodes which are specified in\r
- * <i>uses</i>.\r
- *\r
- * @param packageName\r
- * string with the name of the package to which\r
- * <code>schemaNode</code> belongs.\r
- * @param schemaNode\r
- * schema node for which is created generated type builder\r
- * @param parent parent type (can be null)\r
- * @return generated type builder <code>schemaNode</code>\r
+ /**
+ * Instantiates generated type builder with <code>packageName</code> and
+ * <code>schemaNode</code>.
+ *
+ * The new builder always implements
+ * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />
+ * If <code>schemaNode</code> is instance of GroupingDefinition it also
+ * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable
+ * Augmentable}.<br />
+ * If <code>schemaNode</code> is instance of
+ * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+ * DataNodeContainer} it can also implement nodes which are specified in
+ * <i>uses</i>.
+ *
+ * @param packageName
+ * string with the name of the package to which
+ * <code>schemaNode</code> belongs.
+ * @param schemaNode
+ * schema node for which is created generated type builder
+ * @param parent parent type (can be null)
+ * @return generated type builder <code>schemaNode</code>
*/
private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode,
Type parent) {
- val it = addRawInterfaceDefinition(packageName, schemaNode, "");\r
- qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);\r
+ val it = addRawInterfaceDefinition(packageName, schemaNode, "");
+ qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);
if (parent === null) {
addImplementsType(DATA_OBJECT);
} else {
return it;
}
- /**\r
- * Wraps the calling of the same overloaded method.\r
- *\r
- * @param packageName\r
- * string with the package name to which returning generated type\r
- * builder belongs\r
- * @param schemaNode\r
- * schema node which provide data about the schema node name\r
- * @return generated type builder for <code>schemaNode</code>\r
+ /**
+ * Wraps the calling of the same overloaded method.
+ *
+ * @param packageName
+ * string with the package name to which returning generated type
+ * builder belongs
+ * @param schemaNode
+ * schema node which provide data about the schema node name
+ * @return generated type builder for <code>schemaNode</code>
*/
private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) {
return addRawInterfaceDefinition(packageName, schemaNode, "");
}
- /**\r
- * Returns reference to generated type builder for specified\r
- * <code>schemaNode</code> with <code>packageName</code>.\r
- *\r
- * Firstly the generated type builder is searched in\r
- * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't\r
- * found it is created and added to <code>genTypeBuilders</code>.\r
- *\r
- * @param packageName\r
- * string with the package name to which returning generated type\r
- * builder belongs\r
- * @param schemaNode\r
- * schema node which provide data about the schema node name\r
- * @param prefix return type name prefix\r
- * @return generated type builder for <code>schemaNode</code>\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>schemaNode</code> equals null</li>\r
- * <li>if <code>packageName</code> equals null</li>\r
- * <li>if Q name of schema node is null</li>\r
- * <li>if schema node name is null</li>\r
- * </ul>\r
- *\r
+ /**
+ * Returns reference to generated type builder for specified
+ * <code>schemaNode</code> with <code>packageName</code>.
+ *
+ * Firstly the generated type builder is searched in
+ * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't
+ * found it is created and added to <code>genTypeBuilders</code>.
+ *
+ * @param packageName
+ * string with the package name to which returning generated type
+ * builder belongs
+ * @param schemaNode
+ * schema node which provide data about the schema node name
+ * @param prefix return type name prefix
+ * @return generated type builder for <code>schemaNode</code>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>schemaNode</code> equals null</li>
+ * <li>if <code>packageName</code> equals null</li>
+ * <li>if Q name of schema node is null</li>
+ * <li>if schema node name is null</li>
+ * </ul>
+ *
*/
private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode,
String prefix) {
genTypeName = prefix + BindingMapping.getClassName(schemaNodeName);
}
- //FIXME: Validation of name conflict\r
+ //FIXME: Validation of name conflict
val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
if (!genTypeBuilders.containsKey(packageName)) {
val Map<String, GeneratedTypeBuilder> builders = new HashMap();
return newType;
}
- /**\r
- * Creates the name of the getter method from <code>methodName</code>.\r
- *\r
- * @param methodName\r
- * string with the name of the getter method\r
- * @param returnType return type\r
- * @return string with the name of the getter method for\r
- * <code>methodName</code> in JAVA method format\r
+ /**
+ * Creates the name of the getter method from <code>methodName</code>.
+ *
+ * @param methodName
+ * string with the name of the getter method
+ * @param returnType return type
+ * @return string with the name of the getter method for
+ * <code>methodName</code> in JAVA method format
*/
public static def String getterMethodName(String localName, Type returnType) {
val method = new StringBuilder();
return method.toString();
}
- /**\r
- * Created a method signature builder as part of\r
- * <code>interfaceBuilder</code>.\r
- *\r
- * The method signature builder is created for the getter method of\r
- * <code>schemaNodeName</code>. Also <code>comment</code> and\r
- * <code>returnType</code> information are added to the builder.\r
- *\r
- * @param interfaceBuilder\r
- * generated type builder for which the getter method should be\r
- * created\r
- * @param schemaNodeName\r
- * string with schema node name. The name will be the part of the\r
- * getter method name.\r
- * @param comment\r
- * string with comment for the getter method\r
- * @param returnType\r
- * type which represents the return type of the getter method\r
- * @return method signature builder which represents the getter method of\r
- * <code>interfaceBuilder</code>\r
+ /**
+ * Created a method signature builder as part of
+ * <code>interfaceBuilder</code>.
+ *
+ * The method signature builder is created for the getter method of
+ * <code>schemaNodeName</code>. Also <code>comment</code> and
+ * <code>returnType</code> information are added to the builder.
+ *
+ * @param interfaceBuilder
+ * generated type builder for which the getter method should be
+ * created
+ * @param schemaNodeName
+ * string with schema node name. The name will be the part of the
+ * getter method name.
+ * @param comment
+ * string with comment for the getter method
+ * @param returnType
+ * type which represents the return type of the getter method
+ * @return method signature builder which represents the getter method of
+ * <code>interfaceBuilder</code>
*/
private def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName,
String comment, Type returnType) {
return getMethod;
}
- /**\r
- * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method\r
- * or to <code>genTOBuilder</code> as property.\r
- *\r
- * @param basePackageName\r
- * string contains the module package name\r
- * @param schemaNode\r
- * data schema node which should be added as getter method to\r
- * <code>typeBuilder</code> or as a property to\r
- * <code>genTOBuilder</code> if is part of the list key\r
- * @param typeBuilder\r
- * generated type builder for the list schema node\r
- * @param genTOBuilder\r
- * generated TO builder for the list keys\r
- * @param listKeys\r
- * list of string which contains names of the list keys\r
- * @param module current module\r
- * @throws IllegalArgumentException\r
- * <ul>\r
- * <li>if <code>schemaNode</code> equals null</li>\r
- * <li>if <code>typeBuilder</code> equals null</li>\r
- * </ul>\r
+ /**
+ * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method
+ * or to <code>genTOBuilder</code> as property.
+ *
+ * @param basePackageName
+ * string contains the module package name
+ * @param schemaNode
+ * data schema node which should be added as getter method to
+ * <code>typeBuilder</code> or as a property to
+ * <code>genTOBuilder</code> if is part of the list key
+ * @param typeBuilder
+ * generated type builder for the list schema node
+ * @param genTOBuilder
+ * generated TO builder for the list keys
+ * @param listKeys
+ * list of string which contains names of the list keys
+ * @param module current module
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>schemaNode</code> equals null</li>
+ * <li>if <code>typeBuilder</code> equals null</li>
+ * </ul>
*/
private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode,
GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List<String> listKeys, Module module) {
if (schemaNode instanceof LeafSchemaNode) {
val leaf = schemaNode as LeafSchemaNode;
- val leafName = leaf.QName.localName;\r
+ val leafName = leaf.QName.localName;
resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
if (listKeys.contains(leafName)) {
resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module)
}
}
- /**\r
- * Selects the names of the list keys from <code>list</code> and returns\r
- * them as the list of the strings\r
- *\r
- * @param list\r
- * of string with names of the list keys\r
- * @return list of string which represents names of the list keys. If the\r
- * <code>list</code> contains no keys then the empty list is\r
- * returned.\r
+ /**
+ * Selects the names of the list keys from <code>list</code> and returns
+ * them as the list of the strings
+ *
+ * @param list
+ * of string with names of the list keys
+ * @return list of string which represents names of the list keys. If the
+ * <code>list</code> contains no keys then the empty list is
+ * returned.
*/
private def listKeys(ListSchemaNode list) {
val List<String> listKeys = new ArrayList();
return listKeys;
}
- /**\r
- * Generates for the <code>list</code> which contains any list keys special\r
- * generated TO builder.\r
- *\r
- * @param packageName\r
- * string with package name to which the list belongs\r
- * @param list\r
- * list schema node which is source of data about the list name\r
- * @return generated TO builder which represents the keys of the\r
- * <code>list</code> or null if <code>list</code> is null or list of\r
- * key definitions is null or empty.\r
+ /**
+ * Generates for the <code>list</code> which contains any list keys special
+ * generated TO builder.
+ *
+ * @param packageName
+ * string with package name to which the list belongs
+ * @param list
+ * list schema node which is source of data about the list name
+ * @return generated TO builder which represents the keys of the
+ * <code>list</code> or null if <code>list</code> is null or list of
+ * key definitions is null or empty.
*/
private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) {
var GeneratedTOBuilder genTOBuilder = null;
return genTOBuilder;
}
- /**\r
- * Builds generated TO builders for <code>typeDef</code> of type\r
- * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or\r
- * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition\r
- * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as\r
- * enclosing transfer object.\r
- *\r
- * If more then one generated TO builder is created for enclosing then all\r
- * of the generated TO builders are added to <code>typeBuilder</code> as\r
- * enclosing transfer objects.\r
- *\r
- * @param typeDef\r
- * type definition which can be of type <code>UnionType</code> or\r
- * <code>BitsTypeDefinition</code>\r
- * @param typeBuilder\r
- * generated type builder to which is added generated TO created\r
- * from <code>typeDef</code>\r
- * @param leafName\r
- * string with name for generated TO builder\r
- * @param leaf\r
- * @param parentModule\r
- * @return generated TO builder for <code>typeDef</code>\r
+ /**
+ * Builds generated TO builders for <code>typeDef</code> of type
+ * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or
+ * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
+ * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as
+ * enclosing transfer object.
+ *
+ * If more then one generated TO builder is created for enclosing then all
+ * of the generated TO builders are added to <code>typeBuilder</code> as
+ * enclosing transfer objects.
+ *
+ * @param typeDef
+ * type definition which can be of type <code>UnionType</code> or
+ * <code>BitsTypeDefinition</code>
+ * @param typeBuilder
+ * generated type builder to which is added generated TO created
+ * from <code>typeDef</code>
+ * @param leafName
+ * string with name for generated TO builder
+ * @param leaf
+ * @param parentModule
+ * @return generated TO builder for <code>typeDef</code>
*/
private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
DataSchemaNode leaf, Module parentModule) {
val classNameFromLeaf = BindingMapping.getClassName(leaf.QName);
val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();
val packageName = typeBuilder.fullyQualifiedName;
- if (typeDef instanceof UnionTypeDefinition) {\r
- val List<GeneratedTOBuilder> types = (typeProvider as TypeProviderImpl).\r
- provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),\r
+ if (typeDef instanceof UnionTypeDefinition) {
+ val List<GeneratedTOBuilder> types = (typeProvider as TypeProviderImpl).
+ provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),
classNameFromLeaf, leaf);
- genTOBuilders.addAll(types);\r
- \r
- \r
- var GeneratedTOBuilder resultTOBuilder = null;\r
- if (!types.isEmpty()) {\r
- resultTOBuilder = types.remove(0);\r
- for (GeneratedTOBuilder genTOBuilder : types) {\r
- resultTOBuilder.addEnclosingTransferObject(genTOBuilder);\r
- }\r
- }\r
-\r
- val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");\r
- genPropBuilder.setReturnType(Types.primitiveType("char[]", null));\r
- resultTOBuilder.addEqualsIdentity(genPropBuilder);\r
- resultTOBuilder.addHashIdentity(genPropBuilder);\r
- resultTOBuilder.addToStringProperty(genPropBuilder);\r
+ genTOBuilders.addAll(types);
+
+
+ var GeneratedTOBuilder resultTOBuilder = null;
+ if (!types.isEmpty()) {
+ resultTOBuilder = types.remove(0);
+ for (GeneratedTOBuilder genTOBuilder : types) {
+ resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
+ }
+ }
+
+ val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
+ genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+ resultTOBuilder.addEqualsIdentity(genPropBuilder);
+ resultTOBuilder.addHashIdentity(genPropBuilder);
+ resultTOBuilder.addToStringProperty(genPropBuilder);
} else if (typeDef instanceof BitsTypeDefinition) {
genTOBuilders.add(
}
- /**\r
- * Adds the implemented types to type builder.\r
- *\r
- * The method passes through the list of <i>uses</i> in\r
- * {@code dataNodeContainer}. For every <i>use</i> is obtained corresponding\r
- * generated type from {@link BindingGeneratorImpl#allGroupings\r
- * allGroupings} which is added as <i>implements type</i> to\r
- * <code>builder</code>\r
- *\r
- * @param dataNodeContainer\r
- * element which contains the list of used YANG groupings\r
- * @param builder\r
- * builder to which are added implemented types according to\r
- * <code>dataNodeContainer</code>\r
- * @return generated type builder with all implemented types\r
+ /**
+ * Adds the implemented types to type builder.
+ *
+ * The method passes through the list of <i>uses</i> in
+ * {@code dataNodeContainer}. For every <i>use</i> is obtained corresponding
+ * generated type from {@link BindingGeneratorImpl#allGroupings
+ * allGroupings} which is added as <i>implements type</i> to
+ * <code>builder</code>
+ *
+ * @param dataNodeContainer
+ * element which contains the list of used YANG groupings
+ * @param builder
+ * builder to which are added implemented types according to
+ * <code>dataNodeContainer</code>
+ * @return generated type builder with all implemented types
*/
private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) {
for (usesNode : dataNodeContainer.uses) {
}
return null
}
-\r
- private def Module getParentModule(SchemaNode node) {\r
- val QName qname = node.getPath().getPath().get(0);\r
- val URI namespace = qname.getNamespace();\r
- val Date revision = qname.getRevision();\r
- return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);\r
- }\r
-\r
- public def getModuleContexts() {\r
- genCtx;\r
- }\r
-\r
+
+ private def Module getParentModule(SchemaNode node) {
+ val QName qname = node.getPath().getPath().get(0);
+ val URI namespace = qname.getNamespace();
+ val Date revision = qname.getRevision();
+ return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
+ }
+
+ public def getModuleContexts() {
+ genCtx;
+ }
+
}
*/
package org.opendaylight.yangtools.sal.binding.generator.impl;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils;
import org.opendaylight.yangtools.sal.binding.model.api.Type;
-public abstract class GeneratedClassLoadingStrategy {
+public abstract class GeneratedClassLoadingStrategy implements ClassLoadingStrategy {
private static final GeneratedClassLoadingStrategy TCCL_STRATEGY = new TCCLClassLoadingStrategy();
*/
package org.opendaylight.yangtools.sal.binding.generator.impl;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
+import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
import org.opendaylight.yangtools.binding.generator.util.Types;
import org.opendaylight.yangtools.concepts.Delegator;
import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils;
import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException;
import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class LazyGeneratedCodecRegistry implements //
CodecRegistry, //
private SchemaContext currentSchema;
- private final GeneratedClassLoadingStrategy classLoadingStrategy;
+ private final ClassLoadingStrategy classLoadingStrategy;
- LazyGeneratedCodecRegistry(SchemaLock lock, GeneratedClassLoadingStrategy identityClassLoadingStrategy) {
+ LazyGeneratedCodecRegistry(SchemaLock lock, ClassLoadingStrategy identityClassLoadingStrategy) {
this.lock = Preconditions.checkNotNull(lock);
this.classLoadingStrategy = identityClassLoadingStrategy;
}
*/
package org.opendaylight.yangtools.sal.binding.generator.impl;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
import org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy //
implements //
- AdvancedSchemaSourceProvider<InputStream> {
+ AdvancedSchemaSourceProvider<InputStream>, ModuleInfoRegistry, SchemaContextProvider {
- private ModuleInfoBackedContext(GeneratedClassLoadingStrategy loadingStrategy) {
+ private ModuleInfoBackedContext(ClassLoadingStrategy loadingStrategy) {
this.backingLoadingStrategy = loadingStrategy;
}
return new ModuleInfoBackedContext(getTCCLClassLoadingStrategy());
}
- public static ModuleInfoBackedContext create(GeneratedClassLoadingStrategy loadingStrategy) {
+ public static ModuleInfoBackedContext create(ClassLoadingStrategy loadingStrategy) {
return new ModuleInfoBackedContext(loadingStrategy);
}
private final ConcurrentMap<String, WeakReference<ClassLoader>> packageNameToClassLoader = new ConcurrentHashMap<>();
private final ConcurrentMap<SourceIdentifier, YangModuleInfo> sourceIdentifierToModuleInfo = new ConcurrentHashMap<>();
- private final GeneratedClassLoadingStrategy backingLoadingStrategy;
+ private final ClassLoadingStrategy backingLoadingStrategy;
@Override
public Class<?> loadClass(String fullyQualifiedName) throws ClassNotFoundException {
}
}
+ @Override
public ObjectRegistration<YangModuleInfo> registerModuleInfo(YangModuleInfo yangModuleInfo) {
YangModuleInfoRegistration registration = new YangModuleInfoRegistration(yangModuleInfo, this);
private void remove(YangModuleInfoRegistration registration) {
// FIXME implement
}
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return tryToCreateSchemaContext().get();
+ }
}
*/
package org.opendaylight.yangtools.sal.binding.generator.impl
-import javassist.ClassPool
-import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener
-import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
-import java.util.Map
+import com.google.common.base.Optional
+import com.google.common.collect.FluentIterable
+import com.google.common.collect.HashMultimap
+import com.google.common.util.concurrent.SettableFuture
+import java.util.AbstractMap.SimpleEntry
+import java.util.ArrayList
import java.util.Collections
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import java.util.concurrent.ConcurrentHashMap
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.Map
import java.util.Map.Entry
-import java.util.AbstractMap.SimpleEntry
-import org.opendaylight.yangtools.yang.model.api.SchemaPath
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-import org.opendaylight.yangtools.yang.binding.DataContainer
+import java.util.Set
+import java.util.concurrent.Callable
+import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import com.google.common.collect.HashMultimap
-import com.google.common.util.concurrent.SettableFuture
import java.util.concurrent.Future
+import javassist.ClassPool
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService
-import org.slf4j.LoggerFactory
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName
-import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec
import org.opendaylight.yangtools.binding.generator.util.Types
-
-//import org.osgi.framework.BundleContext
-
-//import org.osgi.framework.ServiceRegistration
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException
-import java.util.concurrent.Callable
-import org.opendaylight.yangtools.yang.binding.Augmentation
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy
import org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils
-import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.yang.binding.Augmentation
+import org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.RpcService
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
-import java.util.ArrayList
import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.binding.RpcService
-import java.util.Set
-import org.opendaylight.yangtools.yang.common.QName
-import com.google.common.collect.FluentIterable
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService
+import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException
+import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName
import org.opendaylight.yangtools.yang.model.api.Module
-import com.google.common.base.Optional
-import org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import org.slf4j.LoggerFactory
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener,
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
SchemaLock, AutoCloseable, SchemaContextHolder {
@Property
@Property
val ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap();
- val promisedTypeDefinitions = HashMultimap.<Type, SettableFuture<GeneratedTypeBuilder>>create;
-
val promisedTypes = HashMultimap.<Type, SettableFuture<Type>>create;
- val GeneratedClassLoadingStrategy classLoadingStrategy;
+ val ClassLoadingStrategy classLoadingStrategy;
@Property
var SchemaContext schemaContext;
this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy())
}
- new(GeneratedClassLoadingStrategy strat){
+ new(ClassLoadingStrategy strat){
classLoadingStrategy = strat
}
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.yangtools.sal.binding.generator.impl;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+import java.io.File;\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.junit.Test;\r
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;\r
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature;\r
+import org.opendaylight.yangtools.sal.binding.model.api.Type;\r
+import org.opendaylight.yangtools.yang.model.api.Module;\r
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;\r
+import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;\r
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;\r
+\r
+public class GeneratedTypesLeafrefTest {\r
+\r
+ private SchemaContext resolveSchemaContextFromFiles(final URI... yangFiles) {\r
+ final YangModelParser parser = new YangParserImpl();\r
+\r
+ final List<File> inputFiles = new ArrayList<File>();\r
+ for (int i = 0; i < yangFiles.length; ++i) {\r
+ inputFiles.add(new File(yangFiles[i]));\r
+ }\r
+\r
+ final Set<Module> modules = parser.parseYangModels(inputFiles);\r
+ return parser.resolveSchemaContext(modules);\r
+ }\r
+\r
+ @Test\r
+ public void testLeafrefResolving() throws URISyntaxException {\r
+ final URI topologyPath = getClass().getResource("/leafref-test-models/abstract-topology@2013-02-08.yang")\r
+ .toURI();\r
+ final URI interfacesPath = getClass().getResource("/leafref-test-models/ietf-interfaces@2012-11-15.yang")\r
+ .toURI();\r
+ final URI inetTypesPath = getClass().getResource("/leafref-test-models/ietf-inet-types@2010-09-24.yang")\r
+ .toURI();\r
+ final URI yangTypesPath = getClass().getResource("/leafref-test-models/ietf-yang-types@2010-09-24.yang")\r
+ .toURI();\r
+\r
+ assertNotNull(topologyPath);\r
+ assertNotNull(interfacesPath);\r
+ assertNotNull(inetTypesPath);\r
+ assertNotNull(yangTypesPath);\r
+\r
+ final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, inetTypesPath,\r
+ yangTypesPath);\r
+ assertNotNull(context);\r
+ assertEquals(4, context.getModules().size());\r
+\r
+ final BindingGenerator bindingGen = new BindingGeneratorImpl();\r
+ final List<Type> genTypes = bindingGen.generateTypes(context);\r
+\r
+ assertEquals(54, genTypes.size());\r
+ assertNotNull(genTypes);\r
+\r
+ GeneratedTransferObject gtIfcKey = null;\r
+ GeneratedType gtIfc = null;\r
+ GeneratedType gtNetworkLink = null;\r
+ GeneratedType gtSource = null;\r
+ GeneratedType gtDest = null;\r
+ GeneratedType gtTunnel = null;\r
+ GeneratedTransferObject gtTunnelKey = null;\r
+ GeneratedType gtTopology = null;\r
+ for (final Type type : genTypes) {\r
+ String name = type.getName();\r
+ if ("InterfaceKey".equals(name)) {\r
+ gtIfcKey = (GeneratedTransferObject) type;\r
+ } else if ("Interface".equals(name)) {\r
+ gtIfc = (GeneratedType) type;\r
+ } else if ("NetworkLink".equals(name)) {\r
+ gtNetworkLink = (GeneratedType) type;\r
+ } else if ("SourceNode".equals(name)) {\r
+ gtSource = (GeneratedType) type;\r
+ } else if ("DestinationNode".equals(name)) {\r
+ gtDest = (GeneratedType) type;\r
+ } else if ("Tunnel".equals(name)) {\r
+ gtTunnel = (GeneratedType) type;\r
+ } else if ("TunnelKey".equals(name)) {\r
+ gtTunnelKey = (GeneratedTransferObject) type;\r
+ } else if ("Topology".equals(name)) {\r
+ gtTopology = (GeneratedType) type;\r
+ }\r
+ }\r
+\r
+ assertNotNull(gtIfcKey);\r
+ assertNotNull(gtIfc);\r
+ assertNotNull(gtNetworkLink);\r
+ assertNotNull(gtSource);\r
+ assertNotNull(gtDest);\r
+ assertNotNull(gtTunnel);\r
+ assertNotNull(gtTunnelKey);\r
+ assertNotNull(gtTopology);\r
+\r
+ // Topology\r
+ final List<MethodSignature> gtTopoMethods = gtTopology.getMethodDefinitions();\r
+ assertNotNull(gtTopoMethods);\r
+ MethodSignature condLeafref = null;\r
+ for (final MethodSignature method : gtTopoMethods) {\r
+ if (method.getName().equals("getCondLeafref")) {\r
+ condLeafref = method;\r
+ }\r
+ }\r
+ assertNotNull(condLeafref);\r
+ Type condLeafRT = condLeafref.getReturnType();\r
+ assertNotNull(condLeafRT);\r
+ assertEquals("java.lang.Object", condLeafRT.getFullyQualifiedName());\r
+\r
+ // InterfaceId\r
+ final List<GeneratedProperty> gtIfcKeyProps = gtIfcKey.getProperties();\r
+ assertNotNull(gtIfcKeyProps);\r
+ GeneratedProperty ifcIdProp = null;\r
+ for (final GeneratedProperty property : gtIfcKeyProps) {\r
+ if (property.getName().equals("interfaceId")) {\r
+ ifcIdProp = property;\r
+ }\r
+ }\r
+ assertNotNull(ifcIdProp);\r
+ Type ifcIdPropType = ifcIdProp.getReturnType();\r
+ assertNotNull(ifcIdPropType);\r
+ assertEquals("java.lang.String", ifcIdPropType.getFullyQualifiedName());\r
+\r
+ // Interface\r
+ final List<MethodSignature> gtIfcMethods = gtIfc.getMethodDefinitions();\r
+ assertNotNull(gtIfcMethods);\r
+ MethodSignature getIfcKey = null;\r
+ MethodSignature getHigherLayerIf = null;\r
+ for (final MethodSignature method : gtIfcMethods) {\r
+ if (method.getName().equals("getKey")) {\r
+ getIfcKey = method;\r
+ } else if (method.getName().equals("getHigherLayerIf")) {\r
+ getHigherLayerIf = method;\r
+ }\r
+ }\r
+ assertNotNull(getIfcKey);\r
+ Type getIfcKeyType = getIfcKey.getReturnType();\r
+ assertNotNull(getIfcKeyType);\r
+ assertNotSame("java.lang.Void", getIfcKeyType);\r
+ assertEquals("InterfaceKey", getIfcKeyType.getName());\r
+\r
+ assertNotNull(getHigherLayerIf);\r
+ Type getHigherLayerIfType = getHigherLayerIf.getReturnType();\r
+ assertNotNull(getHigherLayerIfType);\r
+ assertNotSame("java.lang.Void", getHigherLayerIfType);\r
+ assertEquals("List", getHigherLayerIfType.getName());\r
+\r
+ // NetworkLink\r
+ final List<MethodSignature> gtNetworkLinkMethods = gtNetworkLink.getMethodDefinitions();\r
+ assertNotNull(gtNetworkLinkMethods);\r
+ MethodSignature getIfc = null;\r
+ for (MethodSignature method : gtNetworkLinkMethods) {\r
+ if (method.getName().equals("getInterface")) {\r
+ getIfc = method;\r
+ }\r
+ }\r
+ assertNotNull(getIfc);\r
+ Type getIfcType = getIfc.getReturnType();\r
+ assertNotNull(getIfcType);\r
+ assertNotSame("java.lang.Void", getIfcType);\r
+ assertEquals("String", getIfcType.getName());\r
+\r
+ // SourceNode\r
+ final List<MethodSignature> gtSourceMethods = gtSource.getMethodDefinitions();\r
+ assertNotNull(gtSourceMethods);\r
+ MethodSignature getIdSource = null;\r
+ for (MethodSignature method : gtSourceMethods) {\r
+ if (method.getName().equals("getId")) {\r
+ getIdSource = method;\r
+ }\r
+ }\r
+ assertNotNull(getIdSource);\r
+ Type getIdType = getIdSource.getReturnType();\r
+ assertNotNull(getIdType);\r
+ assertNotSame("java.lang.Void", getIdType);\r
+ assertEquals("Uri", getIdType.getName());\r
+\r
+ // DestinationNode\r
+ final List<MethodSignature> gtDestMethods = gtDest.getMethodDefinitions();\r
+ assertNotNull(gtDestMethods);\r
+ MethodSignature getIdDest = null;\r
+ for (MethodSignature method : gtDestMethods) {\r
+ if (method.getName().equals("getId")) {\r
+ getIdDest = method;\r
+ }\r
+ }\r
+ assertNotNull(getIdDest);\r
+ Type getIdDestType = getIdDest.getReturnType();\r
+ assertNotNull(getIdDestType);\r
+ assertNotSame("java.lang.Void", getIdDestType);\r
+ assertEquals("Uri", getIdDestType.getName());\r
+\r
+ // Tunnel\r
+ final List<MethodSignature> gtTunnelMethods = gtTunnel.getMethodDefinitions();\r
+ assertNotNull(gtTunnelMethods);\r
+ MethodSignature getTunnelKey = null;\r
+ for (MethodSignature method : gtTunnelMethods) {\r
+ if (method.getName().equals("getKey")) {\r
+ getTunnelKey = method;\r
+ }\r
+ }\r
+ assertNotNull(getTunnelKey);\r
+ Type getTunnelKeyType = getTunnelKey.getReturnType();\r
+ assertNotNull(getTunnelKeyType);\r
+ assertNotSame("java.lang.Void", getTunnelKeyType);\r
+ assertEquals("TunnelKey", getTunnelKeyType.getName());\r
+\r
+ // TunnelKey\r
+ final List<GeneratedProperty> gtTunnelKeyProps = gtTunnelKey.getProperties();\r
+ assertNotNull(gtTunnelKeyProps);\r
+ GeneratedProperty tunnelId = null;\r
+ for (final GeneratedProperty property : gtTunnelKeyProps) {\r
+ if (property.getName().equals("tunnelId")) {\r
+ tunnelId = property;\r
+ }\r
+ }\r
+ assertNotNull(tunnelId);\r
+ Type tunnelIdType = tunnelId.getReturnType();\r
+ assertNotNull(tunnelIdType);\r
+ assertNotSame("java.lang.Void", tunnelIdType);\r
+ assertEquals("Uri", tunnelIdType.getName());\r
+ }\r
+\r
+ @Test\r
+ public void testLeafrefInvalidPathResolving() throws URISyntaxException {\r
+ final URI resource = getClass().getResource("/leafref-test-invalid-model/foo.yang").toURI();\r
+ assertNotNull(resource);\r
+\r
+ final SchemaContext context = resolveSchemaContextFromFiles(resource);\r
+ assertNotNull(context);\r
+ assertEquals(1, context.getModules().size());\r
+\r
+ final BindingGenerator bindingGen = new BindingGeneratorImpl();\r
+ try {\r
+ bindingGen.generateTypes(context);\r
+ fail("Expected IllegalArgumentException caused by invalid leafref path");\r
+ } catch (IllegalArgumentException e) {\r
+ String expected = "Failed to find leafref target: ../id";\r
+ assertEquals(expected, e.getMessage());\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
assertEquals(29, genTypes.size());\r
}\r
\r
- @Test\r
- public void testLeafrefResolving() throws URISyntaxException {\r
- final URI topologyPath = getClass().getResource("/leafref-test-models/abstract-topology@2013-02-08.yang")\r
- .toURI();\r
- final URI interfacesPath = getClass().getResource("/leafref-test-models/ietf-interfaces@2012-11-15.yang")\r
- .toURI();\r
- final URI inetTypesPath = getClass().getResource("/leafref-test-models/ietf-inet-types@2010-09-24.yang")\r
- .toURI();\r
- final URI yangTypesPath = getClass().getResource("/leafref-test-models/ietf-yang-types@2010-09-24.yang")\r
- .toURI();\r
-\r
- assertNotNull(topologyPath);\r
- assertNotNull(interfacesPath);\r
- // assertTrue(ifTypePath != null);\r
- assertNotNull(inetTypesPath);\r
- assertNotNull(yangTypesPath);\r
-\r
- // final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, ifTypePath,\r
- // inetTypesPath, yangTypesPath);\r
- final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, inetTypesPath,\r
- yangTypesPath);\r
- assertNotNull(context);\r
- assertEquals(4, context.getModules().size());\r
-\r
- final BindingGenerator bindingGen = new BindingGeneratorImpl();\r
- final List<Type> genTypes = bindingGen.generateTypes(context);\r
-\r
- assertEquals(54, genTypes.size());\r
- assertNotNull(genTypes);\r
-\r
- GeneratedTransferObject gtIfcKey = null;\r
- GeneratedType gtIfc = null;\r
- GeneratedType gtNetworkLink = null;\r
- GeneratedType gtSource = null;\r
- GeneratedType gtDest = null;\r
- GeneratedType gtTunnel = null;\r
- GeneratedTransferObject gtTunnelKey = null;\r
- GeneratedType gtTopology = null;\r
- for (final Type type : genTypes) {\r
- String name = type.getName();\r
- if ("InterfaceKey".equals(name)) {\r
- gtIfcKey = (GeneratedTransferObject) type;\r
- } else if ("Interface".equals(name)) {\r
- gtIfc = (GeneratedType) type;\r
- } else if ("NetworkLink".equals(name)) {\r
- gtNetworkLink = (GeneratedType) type;\r
- } else if ("SourceNode".equals(name)) {\r
- gtSource = (GeneratedType) type;\r
- } else if ("DestinationNode".equals(name)) {\r
- gtDest = (GeneratedType) type;\r
- } else if ("Tunnel".equals(name)) {\r
- gtTunnel = (GeneratedType) type;\r
- } else if ("TunnelKey".equals(name)) {\r
- gtTunnelKey = (GeneratedTransferObject) type;\r
- } else if ("Topology".equals(name)) {\r
- gtTopology = (GeneratedType) type;\r
- }\r
- }\r
-\r
- assertNotNull(gtIfcKey);\r
- assertNotNull(gtIfc);\r
- assertNotNull(gtNetworkLink);\r
- assertNotNull(gtSource);\r
- assertNotNull(gtDest);\r
- assertNotNull(gtTunnel);\r
- assertNotNull(gtTunnelKey);\r
- assertNotNull(gtTopology);\r
-\r
- // Topology\r
- final List<MethodSignature> gtTopoMethods = gtTopology.getMethodDefinitions();\r
- assertNotNull(gtTopoMethods);\r
- MethodSignature condLeafref = null;\r
- for (final MethodSignature method : gtTopoMethods) {\r
- if (method.getName().equals("getCondLeafref")) {\r
- condLeafref = method;\r
- }\r
- }\r
- assertNotNull(condLeafref);\r
- Type condLeafRT = condLeafref.getReturnType();\r
- assertNotNull(condLeafRT);\r
- assertEquals("java.lang.Object", condLeafRT.getFullyQualifiedName());\r
-\r
- // InterfaceId\r
- final List<GeneratedProperty> gtIfcKeyProps = gtIfcKey.getProperties();\r
- assertNotNull(gtIfcKeyProps);\r
- GeneratedProperty ifcIdProp = null;\r
- for (final GeneratedProperty property : gtIfcKeyProps) {\r
- if (property.getName().equals("interfaceId")) {\r
- ifcIdProp = property;\r
- }\r
- }\r
- assertNotNull(ifcIdProp);\r
- Type ifcIdPropType = ifcIdProp.getReturnType();\r
- assertNotNull(ifcIdPropType);\r
- assertEquals("java.lang.String", ifcIdPropType.getFullyQualifiedName());\r
-\r
- // Interface\r
- final List<MethodSignature> gtIfcMethods = gtIfc.getMethodDefinitions();\r
- assertNotNull(gtIfcMethods);\r
- MethodSignature getIfcKey = null;\r
- MethodSignature getHigherLayerIf = null;\r
- for (final MethodSignature method : gtIfcMethods) {\r
- if (method.getName().equals("getKey")) {\r
- getIfcKey = method;\r
- } else if (method.getName().equals("getHigherLayerIf")) {\r
- getHigherLayerIf = method;\r
- }\r
- }\r
- assertNotNull(getIfcKey);\r
- Type getIfcKeyType = getIfcKey.getReturnType();\r
- assertNotNull(getIfcKeyType);\r
- assertNotSame("java.lang.Void", getIfcKeyType);\r
- assertEquals("InterfaceKey", getIfcKeyType.getName());\r
-\r
- assertNotNull(getHigherLayerIf);\r
- Type getHigherLayerIfType = getHigherLayerIf.getReturnType();\r
- assertNotNull(getHigherLayerIfType);\r
- assertNotSame("java.lang.Void", getHigherLayerIfType);\r
- assertEquals("List", getHigherLayerIfType.getName());\r
-\r
- // NetworkLink\r
- final List<MethodSignature> gtNetworkLinkMethods = gtNetworkLink.getMethodDefinitions();\r
- assertNotNull(gtNetworkLinkMethods);\r
- MethodSignature getIfc = null;\r
- for (MethodSignature method : gtNetworkLinkMethods) {\r
- if (method.getName().equals("getInterface")) {\r
- getIfc = method;\r
- }\r
- }\r
- assertNotNull(getIfc);\r
- Type getIfcType = getIfc.getReturnType();\r
- assertNotNull(getIfcType);\r
- assertNotSame("java.lang.Void", getIfcType);\r
- assertEquals("String", getIfcType.getName());\r
-\r
- // SourceNode\r
- final List<MethodSignature> gtSourceMethods = gtSource.getMethodDefinitions();\r
- assertNotNull(gtSourceMethods);\r
- MethodSignature getIdSource = null;\r
- for (MethodSignature method : gtSourceMethods) {\r
- if (method.getName().equals("getId")) {\r
- getIdSource = method;\r
- }\r
- }\r
- assertNotNull(getIdSource);\r
- Type getIdType = getIdSource.getReturnType();\r
- assertNotNull(getIdType);\r
- assertNotSame("java.lang.Void", getIdType);\r
- assertEquals("Uri", getIdType.getName());\r
-\r
- // DestinationNode\r
- final List<MethodSignature> gtDestMethods = gtDest.getMethodDefinitions();\r
- assertNotNull(gtDestMethods);\r
- MethodSignature getIdDest = null;\r
- for (MethodSignature method : gtDestMethods) {\r
- if (method.getName().equals("getId")) {\r
- getIdDest = method;\r
- }\r
- }\r
- assertNotNull(getIdDest);\r
- Type getIdDestType = getIdDest.getReturnType();\r
- assertNotNull(getIdDestType);\r
- assertNotSame("java.lang.Void", getIdDestType);\r
- assertEquals("Uri", getIdDestType.getName());\r
-\r
- // Tunnel\r
- final List<MethodSignature> gtTunnelMethods = gtTunnel.getMethodDefinitions();\r
- assertNotNull(gtTunnelMethods);\r
- MethodSignature getTunnelKey = null;\r
- for (MethodSignature method : gtTunnelMethods) {\r
- if (method.getName().equals("getKey")) {\r
- getTunnelKey = method;\r
- }\r
- }\r
- assertNotNull(getTunnelKey);\r
- Type getTunnelKeyType = getTunnelKey.getReturnType();\r
- assertNotNull(getTunnelKeyType);\r
- assertNotSame("java.lang.Void", getTunnelKeyType);\r
- assertEquals("TunnelKey", getTunnelKeyType.getName());\r
-\r
- // TunnelKey\r
- final List<GeneratedProperty> gtTunnelKeyProps = gtTunnelKey.getProperties();\r
- assertNotNull(gtTunnelKeyProps);\r
- GeneratedProperty tunnelId = null;\r
- for (final GeneratedProperty property : gtTunnelKeyProps) {\r
- if (property.getName().equals("tunnelId")) {\r
- tunnelId = property;\r
- }\r
- }\r
- assertNotNull(tunnelId);\r
- Type tunnelIdType = tunnelId.getReturnType();\r
- assertNotNull(tunnelIdType);\r
- assertNotSame("java.lang.Void", tunnelIdType);\r
- assertEquals("Uri", tunnelIdType.getName());\r
- }\r
-\r
@Test\r
public void testContainerResolving() throws URISyntaxException {\r
final URI filePath = getClass().getResource("/simple-container-demo.yang").toURI();\r
augment "/at:topology/at:network-links/at:network-link" {
leaf interface {
type leafref {
- path "../atp:interfaces/atp:interface/atp:interface-id";
+ path "../../../atp:interfaces/atp:interface/atp:interface-id";
}
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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
+ */
+module foo {
+ yang-version 1;
+ namespace "urn:yang.foo";
+ prefix "f";
+
+ revision "2014-03-10" {
+ }
+
+ container links {
+ container link {
+ leaf source {
+ type leafref {
+ path "../id";
+ }
+ }
+ }
+ }
+
+}
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.yangtools.sal.binding.generator.spi;\r
-\r
-public interface TypeProviderFactory {\r
-\r
- TypeProvider providerFor(YANGModuleIdentifier module);\r
-}\r
+/*
+ * Copyright (c) 2013 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.sal.binding.generator.spi;
+
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+
+//FIXME not implemented anywhere
+public interface TypeProviderFactory {
+
+ TypeProvider providerFor(ModuleIdentifier module);
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 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.sal.binding.generator.spi;
-
-import java.net.URI;
-import java.util.Date;
-
-
-public class YANGModuleIdentifier {
- private String name;
- private URI namespace;
- private Date revision;
-
- /**
- * Returns name.
- *
- * @return string with name
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Returns URI namespace.
- *
- * @return URI with namespace
- */
- public URI getNamespace() {
- return this.namespace;
- }
-
- /**
- * Returns the revision date.
- *
- * @return date of revision
- */
- public Date getRevision() {
- return this.revision;
- }
-}
return validateJavaPackage(packageNameBuilder.toString());
}
+ public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) {
+ return packageNameForGeneratedType(basePackageName, schemaPath, false);
+ }
+
/**
* Creates package name from specified <code>basePackageName</code> (package
* name for module) and <code>schemaPath</code>.
* name of this node
* @return string with valid JAVA package name
*/
- public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) {
+ public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath,
+ boolean isUsesAugment) {
if (basePackageName == null) {
throw new IllegalArgumentException("Base Package Name cannot be NULL!");
}
final StringBuilder builder = new StringBuilder();
builder.append(basePackageName);
final List<QName> pathToNode = schemaPath.getPath();
- final int traversalSteps = (pathToNode.size() - 1);
+ final int traversalSteps;
+ if (isUsesAugment) {
+ traversalSteps = (pathToNode.size());
+ } else {
+ traversalSteps = (pathToNode.size() - 1);
+ }
for (int i = 0; i < traversalSteps; ++i) {
builder.append(".");
String nodeLocalName = pathToNode.get(i).getLocalName();
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
-import java.util.Set;
import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator;
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
/**
* Set of <code>Type</code> instances for which the JAVA code is generated.
*/
- private final Set<? extends Type> types;
+ private final Collection<? extends Type> types;
/**
* BuildContext used for instantiating files
* @param types
* set of types for which JAVA code should be generated
*/
- public GeneratorJavaFile(final BuildContext buildContext, final Set<? extends Type> types) {
+ public GeneratorJavaFile(final BuildContext buildContext, final Collection<? extends Type> types) {
this.buildContext = Preconditions.checkNotNull(buildContext);
this.types = Preconditions.checkNotNull(types);
generators.add(new InterfaceGenerator());
* @param types
* set of types for which JAVA code should be generated
*/
- public GeneratorJavaFile(final Set<? extends Type> types) {
+ public GeneratorJavaFile(final Collection<? extends Type> types) {
this(new DefaultBuildContext(), types);
}
throw new IllegalStateException("Generated code should not be empty!");
}
final File file = new File(packageDir, generator.getUnitName(type) + ".java");
+
+ if (file.exists()) {
+ LOG.warn(
+ "Naming conflict for type '{}': file with same name already exists and will not be generated.",
+ type.getFullyQualifiedName());
+ return null;
+ }
+
try (final OutputStream stream = buildContext.newFileOutputStream(file)) {
try (final Writer fw = new OutputStreamWriter(stream)) {
try (final BufferedWriter bw = new BufferedWriter(fw)) {
}
}
return file;
- }
- return null;
- }
- private File generateStringToJavaFile(final File parentDir, final String generatedCode, String packageName,
- final CodeGenerator generator) throws IOException {
- if (parentDir == null) {
- LOG.warn("Parent Directory not specified, files will be generated "
- + "accordingly to generated Type package path.");
}
- if (generator == null) {
- LOG.error("Cannot generate Type into Java File because " + "Code Generator instance is NULL!");
- throw new IllegalArgumentException("Code Generator Cannot be NULL!");
- }
- final File packageDir = packageToDirectory(parentDir, packageName);
-
- if (!packageDir.exists()) {
- packageDir.mkdirs();
- }
-
- if (generatedCode.isEmpty()) {
- throw new IllegalStateException("Generated code should not be empty!");
- }
- final File file = new File(packageDir, "YangModuleInfoImpl.java");
- try (final OutputStream stream = buildContext.newFileOutputStream(file)) {
- try (final Writer fw = new OutputStreamWriter(stream)) {
- try (final BufferedWriter bw = new BufferedWriter(fw)) {
- bw.write(generatedCode);
- }
- } catch (IOException e) {
- LOG.error("Failed to write generate output into {}", file.getPath(), e);
- throw e;
- }
- }
- return file;
+ return null;
}
/**
package org.opendaylight.yangtools.sal.java.api.generator;
/**
- *
+ *
* Transformator of the data from the virtual form to JAVA source code. The result source code represents JAVA interface. For
* generating of the source code is used the template written in XTEND language.
- *
+ *
*/
import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator;
+import org.opendaylight.yangtools.sal.binding.model.api.Enumeration;
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
import org.opendaylight.yangtools.sal.binding.model.api.Type;
@Override
public boolean isAcceptable(Type type) {
- return type instanceof GeneratedType && !(type instanceof GeneratedTransferObject);
+ return type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)
+ && !(type instanceof Enumeration);
}
/**
val body = '''
public final class «MODULE_INFO_CLASS_NAME» implements «YangModuleInfo.importedName» {
- private static final «YangModuleInfo.importedName» INSTANCE = new «MODULE_INFO_CLASS_NAME»();
+ private static final «YangModuleInfo.importedName» INSTANCE = new «MODULE_INFO_CLASS_NAME»();
- private final Set<YangModuleInfo> importedModules;
+ private final «String.importedName» name = "«module.name»";
+ private final «String.importedName» namespace = "«module.namespace.toString»";
+ «val DateFormat df = new SimpleDateFormat("yyyy-MM-dd")»
+ private final «String.importedName» revision = "«df.format(module.revision)»";
+ private final «String.importedName» resourcePath = "«sourcePath»";
+
+ private final «Set.importedName»<YangModuleInfo> importedModules;
- public static «YangModuleInfo.importedName» getInstance() {
+ public static «YangModuleInfo.importedName» getInstance() {
return INSTANCE;
- }
-
- «module.classBody»
}
+
+ «module.classBody»
+ }
'''
return '''
-
- package «packageName» ;
- «imports»
- «body»
+ package «packageName» ;
+ «imports»
+ «body»
'''.toString
}
«ELSE»
importedModules = «Collections.importedName».emptySet();
«ENDIF»
- «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream("«sourcePath»");
+ «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream(resourcePath);
if (stream == null) {
- throw new IllegalStateException("Resource «sourcePath» is missing");
+ throw new IllegalStateException("Resource '" + resourcePath + "' is missing");
}
try {
stream.close();
@Override
public «String.importedName» getName() {
- return "«m.name»";
+ return name;
}
@Override
public «String.importedName» getRevision() {
- «val DateFormat df = new SimpleDateFormat("yyyy-MM-dd")»
- return "«df.format(m.revision)»";
+ return revision;
}
@Override
public «String.importedName» getNamespace() {
- return "«m.namespace.toString»";
+ return namespace;
}
@Override
public «InputStream.importedName» getModuleSourceStream() throws IOException {
- «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream("«sourcePath»");
+ «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream(resourcePath);
if (stream == null) {
- throw new «IOException.importedName»("Resource «sourcePath» is missing");
+ throw new «IOException.importedName»("Resource " + resourcePath + " is missing");
}
return stream;
}
public «Set.importedName»<«YangModuleInfo.importedName»> getImportedModules() {
return importedModules;
}
+
+ @Override
+ public «String.importedName» toString() {
+ «StringBuilder.importedName» sb = new «StringBuilder.importedName»(this.getClass().getCanonicalName());
+ sb.append("[");
+ sb.append("name = " + name);
+ sb.append(", namespace = " + namespace);
+ sb.append(", revision = " + revision);
+ sb.append(", resourcePath = " + resourcePath);
+ sb.append(", imports = " + importedModules);
+ sb.append("]");
+ return sb.toString();
+ }
'''
def getSourcePath() {
// Test if all sources were generated from 'module foo'
File parent = new File(sourcesOutputDir, NS_FOO);
assertTrue(new File(parent, "Object.java").exists());
+ assertTrue(new File(parent, "ClosedObject.java").exists());
assertTrue(new File(parent, "OpenObject.java").exists());
assertTrue(new File(parent, "ExplicitRouteObject.java").exists());
assertTrue(new File(parent, "PathKeySubobject.java").exists());
- assertFilesCount(parent, 7);
+ assertFilesCount(parent, 9);
parent = new File(parent, "object");
assertTrue(new File(parent, "Nodes.java").exists());
assertTrue(new File(parent, "NodesBuilder.java").exists());
assertFilesCount(parent, 2);
+ parent = new File(sourcesOutputDir, NS_FOO + FS + "closed");
+ assertFilesCount(parent, 1);
+
+ parent = new File(parent, "object");
+ assertTrue(new File(parent, "Link1.java").exists());
+ assertTrue(new File(parent, "Link1Builder.java").exists());
+ assertFilesCount(parent, 2);
+
parent = new File(sourcesOutputDir, NS_FOO + FS + "open");
assertFilesCount(parent, 1);
parent = new File(sourcesOutputDir, NS_BAR);
assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists());
assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists());
- assertFilesCount(parent, 3);
+ assertTrue(new File(parent, "RouteSubobjects.java").exists());
+ assertFilesCount(parent, 5);
- parent = new File(parent, "basic");
+ parent = new File(parent, "route");
+ assertFilesCount(parent, 1);
+ parent = new File(new File(sourcesOutputDir, NS_BAR), "basic");
assertFilesCount(parent, 1);
parent = new File(parent, "explicit");
assertFilesCount(parent, 1);
uses basic-explicit-route-subobjects;
}
+ grouping route-subobjects {
+ container links {
+ container link {
+ }
+ }
+ }
+
}
}
}
+ grouping closed-object {
+ uses b:route-subobjects {
+ augment "links/link" {
+ leaf id {
+ type string;
+ }
+ }
+ }
+ }
+
grouping explicit-route-object {
list subobjects {
leaf loose {
}
}
}
+ if (returnType == null) {
+ throw new IllegalArgumentException("Failed to find leafref target: " + strXPath);
+ }
return returnType;
}
*/
package org.opendaylight.yangtools.maven.sal.api.gen.plugin;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
import org.slf4j.LoggerFactory;
import org.sonatype.plexus.build.incremental.BuildContext;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware {
private static final String FS = File.separator;
final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
final List<Type> types = bindingGenerator.generateTypes(context, yangModules);
- final GeneratorJavaFile generator = new GeneratorJavaFile(buildContext, new HashSet<>(types));
+ final GeneratorJavaFile generator = new GeneratorJavaFile(buildContext, types);
File persistentSourcesDir = null;
if (additionalConfig != null) {
}
private Collection<? extends File> generateModuleInfos(File outputBaseDir, Set<Module> yangModules,
- SchemaContext context) {
+ SchemaContext context) {
Builder<File> result = ImmutableSet.builder();
Builder<String> bindingProviders = ImmutableSet.builder();
for (Module module : yangModules) {
- result.addAll(generateYangModuleInfo(outputBaseDir, module, context, bindingProviders));
+ Builder<String> currentProvidersBuilder = ImmutableSet.builder();
+ // TODO: do not mutate parameters, output of a method is defined by its return value
+ Set<File> moduleInfoProviders = generateYangModuleInfo(outputBaseDir, module, context, currentProvidersBuilder);
+ ImmutableSet<String> currentProviders = currentProvidersBuilder.build();
+ logger.info("Adding ModuleInfo providers {}", currentProviders);
+ bindingProviders.addAll(currentProviders);
+ result.addAll(moduleInfoProviders);
}
result.add(writeMetaInfServices(resourceBaseDir, YangModelBindingProvider.class, bindingProviders.build()));
<packaging>bundle</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>concepts</artifactId>
- <name>Concepts</name>
+ <name>${project.artifactId}</name>
<description>Java binding for YANG</description>
<build>
public final T getInstance() {
return instance;
}
+
+
+ @Override
+ public String toString() {
+ return "AbstractObjectRegistration{" +
+ "instance=" + instance +
+ '}';
+ }
}
terms of the Eclipse Public License v1.0 which accompanies this distribution,
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>yangtools</artifactId>
<artifactId>plexus-slf4j-logging</artifactId>
<version>1.1</version>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
- <!-- Our artifacts -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>concepts</artifactId>
- <version>${project.version}</version>
- </dependency>
+
+ <!-- Our artifacts -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>concepts</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
-<!--
- <Export-Package>*</Export-Package>
--->
+ <!--
+ <Export-Package>*</Export-Package>
+ -->
</instructions>
</configuration>
</plugin>
</goals>
</pluginExecutionFilter>
<action>
- <execute />
+ <execute/>
</action>
</pluginExecution>
</pluginExecutions>
<artifactId>concepts</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-io</artifactId>
- <version>1.3.2</version>
- </dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-proxy-client</artifactId>
<version>1.1.1</version>
</dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-model-util</artifactId>
import java.util.Set;
-import org.opendaylight.yangtools.restconf.client.api.auth.AuthenticationHolder;
import org.opendaylight.yangtools.restconf.client.api.data.ConfigurationDatastore;
import org.opendaylight.yangtools.restconf.client.api.data.OperationalDatastore;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
/**
* Returns a set of {@link RpcServiceContext} which provides invocation
* handling for RPCs supported by the backing server.
- *
+ *
* @return Future representing the asynchronous call to fetch the information.
*/
ListenableFuture<Set<Class<? extends RpcService>>> getRpcServices();
*/
package org.opendaylight.yangtools.restconf.client;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.sun.jersey.api.client.ClientResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
+
import javax.ws.rs.core.MediaType;
+
import org.opendaylight.yangtools.restconf.client.api.data.ConfigurationDatastore;
import org.opendaylight.yangtools.restconf.client.to.RestRpcError;
import org.opendaylight.yangtools.restconf.client.to.RestRpcResult;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-
public class ConfigurationDataStoreImpl extends AbstractDataStore implements ConfigurationDatastore {
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
-import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import org.opendaylight.yangtools.restconf.client.api.auth.AuthenticationHolder;
import org.opendaylight.yangtools.restconf.client.api.data.ConfigurationDatastore;
import org.opendaylight.yangtools.restconf.client.api.data.OperationalDatastore;
-import org.opendaylight.yangtools.restconf.client.api.dto.RestEventStreamInfo;
-import org.opendaylight.yangtools.restconf.client.api.dto.RestModule;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
import org.opendaylight.yangtools.restconf.client.api.event.ListenableEventStreamContext;
import org.opendaylight.yangtools.restconf.client.api.rpc.RpcServiceContext;
import org.opendaylight.yangtools.restconf.client.to.RestRpcServiceContext;
-import org.opendaylight.yangtools.restconf.common.ResourceMediaTypes;
import org.opendaylight.yangtools.restconf.common.ResourceUri;
import org.opendaylight.yangtools.restconf.utils.RestconfUtils;
import org.opendaylight.yangtools.restconf.utils.XmlTools;
@Override
public ListenableFuture<Set<Class<? extends RpcService>>> getRpcServices() {
- return get(ResourceUri.MODULES.getPath(), ResourceMediaTypes.XML.getMediaType(),new Function<ClientResponse, Set<Class<? extends RpcService>>>() {
+ return get(ResourceUri.MODULES.getPath(), MediaType.APPLICATION_XML,new Function<ClientResponse, Set<Class<? extends RpcService>>>() {
@Override
public Set<Class<? extends RpcService>> apply(ClientResponse clientResponse) {
if (clientResponse.getStatus() != 200) {
@Override
public ListenableFuture<Set<EventStreamInfo>> getAvailableEventStreams() {
- return get(ResourceUri.MODULES.getPath(), ResourceMediaTypes.XML.getMediaType(),new Function<ClientResponse, Set<EventStreamInfo>>() {
+ return get(ResourceUri.STREAM.getPath(), MediaType.APPLICATION_XML, new Function<ClientResponse, Set<EventStreamInfo>>() {
@Override
public Set<EventStreamInfo> apply(ClientResponse clientResponse) {
if (clientResponse.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ clientResponse.getStatus());
}
- List<RestModule> modules = null;
try {
- modules = XmlTools.getModulesFromInputStream(clientResponse.getEntityInputStream());
+ return XmlTools.evenStreamsFromInputStream(clientResponse.getEntityInputStream());
} catch (Exception e) {
- logger.trace("");
+ logger.trace("Stream discovery failed due to {}",e);
+ throw new IllegalStateException(e);
}
- // when restconf will support discovery by /restconf/streams use this instead of next iteration
- //return XmlTools.evenStreamsFromInputStream(response.getEntityInputStream());
- Set<EventStreamInfo> evtStreamInfos = new HashSet<EventStreamInfo>();
- for (RestModule module:modules){
- RestEventStreamInfo esi = new RestEventStreamInfo();
- esi.setIdentifier(module.getName()+":"+module.getName());
- esi.setDescription(module.getNamespace());
- evtStreamInfos.add(esi);
- }
- return evtStreamInfos;
}
});
}
public interface PathArgument {
Class<? extends DataObject> getType();
-
}
public static final class Item<T extends DataObject> implements PathArgument {
try {
Object potentialList = getGetterMethod().invoke(parent);
if (potentialList instanceof Iterable) {
+
final Iterable<Identifiable> dataList = (Iterable<Identifiable>) potentialList;
if (childArgument instanceof IdentifiableItem<?, ?>) {
return readUsingIdentifiableItem(dataList, (IdentifiableItem) childArgument, builder);
*/
package org.opendaylight.yangtools.yang.common;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.getRevisionFormat;
/**
* The QName from XML consists of local name of element and XML namespace, but
protected static final Logger LOGGER = LoggerFactory.getLogger(QName.class);
- private static final ThreadLocal<SimpleDateFormat> REVISION_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat("yyyy-MM-dd");
- };
-
- public void set(SimpleDateFormat value) {
- throw new UnsupportedOperationException();
- };
- };
static final String QNAME_REVISION_DELIMITER = "?revision=";
static final String QNAME_LEFT_PARENTHESIS = "(";
static final String QNAME_RIGHT_PARENTHESIS = ")";
this.revision = revision;
this.prefix = prefix;
if(revision != null) {
- this.formattedRevision = REVISION_FORMAT.get().format(revision);
+ this.formattedRevision = getRevisionFormat().format(revision);
} else {
this.formattedRevision = null;
}
if (nsAndRev.contains("?")) {
String[] splitted = nsAndRev.split("\\?");
this.namespace = URI.create(splitted[0]);
- revision = REVISION_FORMAT.get().parse(splitted[1]);
+ revision = getRevisionFormat().parse(splitted[1]);
} else {
this.namespace = URI.create(nsAndRev);
}
this.revision = revision;
this.prefix = null;
if (revision != null) {
- this.formattedRevision = REVISION_FORMAT.get().format(revision);
+ this.formattedRevision = getRevisionFormat().format(revision);
} else {
this.formattedRevision = null;
}
sb.append(QNAME_LEFT_PARENTHESIS + namespace);
if (revision != null) {
- sb.append(QNAME_REVISION_DELIMITER + REVISION_FORMAT.get().format(revision));
+ sb.append(QNAME_REVISION_DELIMITER + getRevisionFormat().format(revision));
}
sb.append(QNAME_RIGHT_PARENTHESIS);
}
public static Date parseRevision(String formatedDate) {
try {
- return REVISION_FORMAT.get().parse(formatedDate);
+ return getRevisionFormat().parse(formatedDate);
} catch (ParseException| RuntimeException e) {
throw new IllegalArgumentException("Revision is not in supported format:" + formatedDate,e);
}
if(revision == null) {
return null;
}
- return REVISION_FORMAT.get().format(revision);
+ return getRevisionFormat().format(revision);
}
public boolean isEqualWithoutRevision(QName other) {
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.common;
+
+import java.text.SimpleDateFormat;
+
+public class SimpleDateFormatUtil {
+
+ private static final ThreadLocal<SimpleDateFormat> REVISION_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat("yyyy-MM-dd");
+ };
+
+ public void set(SimpleDateFormat value) {
+ throw new UnsupportedOperationException();
+ };
+
+ };
+
+ public static SimpleDateFormat getRevisionFormat() {
+ return REVISION_FORMAT.get();
+ }
+}
public interface AttributesContainer {
-
- Map<QName,String> getAttributes();
-
+ Map<QName, String> getAttributes();
+
Object getAttributeValue(QName value);
-
+
}
*\r
*\r
*/\r
-public interface CompositeNode extends Node<List<Node<?>>>, NodeModification, Map<QName,List<Node<?>>> {\r
+public interface CompositeNode extends //\r
+ Node<List<Node<?>>>, //\r
+ NodeModification, //\r
+ Map<QName,List<Node<?>>> {\r
\r
+ /**\r
+ * Returns a list of children as seens in resulting XML serialization\r
+ * defined by YANG specification.\r
+ *\r
+ *\r
+ * @return\r
+ */\r
+ @Deprecated\r
List<Node<?>> getChildren();\r
\r
List<CompositeNode> getCompositesByName(QName children);\r
/**\r
* @return cast self to mutable, if possible\r
*/\r
+ @Deprecated\r
MutableCompositeNode asMutable();\r
- \r
+\r
}\r
* 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.yang.data.api;\r
-\r
+package org.opendaylight.yangtools.yang.data.api;
+
import java.io.Serializable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-\r
-public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable, Serializable {\r
-\r
- private static final long serialVersionUID = 8467409862384206193L;\r
- private final List<PathArgument> path;\r
-\r
+import com.google.common.collect.ImmutableSet;
+
+public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable, Serializable {
+
+ private static final long serialVersionUID = 8467409862384206193L;
+ private final List<PathArgument> path;
+
private transient String toStringCache = null;
- private transient Integer hashCodeCache = null;\r
-\r
- public List<PathArgument> getPath() {\r
- return path;\r
- }\r
-\r
- public InstanceIdentifier(final List<? extends PathArgument> path) {\r
- this.path =ImmutableList.copyOf(path);\r
- }\r
-\r
- private InstanceIdentifier(NodeIdentifier nodeIdentifier) {\r
- this.path = ImmutableList.<PathArgument>of(nodeIdentifier);\r
- }\r
-\r
- @Override\r
+ private transient Integer hashCodeCache = null;
+
+ public List<PathArgument> getPath() {
+ return path;
+ }
+
+ public InstanceIdentifier(final List<? extends PathArgument> path) {
+ this.path = ImmutableList.copyOf(path);
+ }
+
+ private InstanceIdentifier(NodeIdentifier nodeIdentifier) {
+ this.path = ImmutableList.<PathArgument> of(nodeIdentifier);
+ }
+
+ @Override
public int hashCode() {
/*
- * The hashCodeCache is safe, since the object contract requires immutability
- * of the object and all objects referenced from this object.
+ * The hashCodeCache is safe, since the object contract requires
+ * immutability of the object and all objects referenced from this
+ * object.
*
- * Used lists, maps are immutable. Path Arguments (elements) are also immutable,
- * since the PathArgument contract requires immutability.
+ * Used lists, maps are immutable. Path Arguments (elements) are also
+ * immutable, since the PathArgument contract requires immutability.
*
- * The cache is thread-safe - if multiple computations occurs at the same time,
- * cache will be overwritten with same result.
+ * The cache is thread-safe - if multiple computations occurs at the
+ * same time, cache will be overwritten with same result.
*/
- if(hashCodeCache == null) {
+ if (hashCodeCache == null) {
final int prime = 31;
int result = 1;
result = prime * result + ((path == null) ? 0 : path.hashCode());
hashCodeCache = result;
}
- return hashCodeCache;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj) {\r
- return true;\r
+ return hashCodeCache;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
}
- if (obj == null) {\r
+ if (obj == null) {
return false;
- }\r
- if (getClass() != obj.getClass()) {\r
+ }
+ if (getClass() != obj.getClass()) {
return false;
- }\r
+ }
InstanceIdentifier other = (InstanceIdentifier) obj;
- if(this.hashCode() != obj.hashCode()) {
+ if (this.hashCode() != obj.hashCode()) {
return false;
- }\r
- if (path == null) {\r
- if (other.path != null) {\r
+ }
+ if (path == null) {
+ if (other.path != null) {
return false;
- }\r
- } else if (!path.equals(other.path)) {\r
+ }
+ } else if (!path.equals(other.path)) {
return false;
- }\r
- return true;\r
- }\r
-\r
- // Static factories & helpers\r
-\r
- public static InstanceIdentifier of(QName name) {\r
- return new InstanceIdentifier(new NodeIdentifier(name));\r
- }\r
-\r
- static public InstanceIdentifierBuilder builder() {\r
- return new BuilderImpl();\r
- }\r
-\r
- static public InstanceIdentifierBuilder builder(InstanceIdentifier origin) {\r
- return new BuilderImpl(origin.getPath());\r
- }\r
-\r
- public interface PathArgument extends Immutable, Serializable {\r
- QName getNodeType();\r
-\r
- }\r
-\r
- public interface InstanceIdentifierBuilder extends Builder<InstanceIdentifier> {\r
- InstanceIdentifierBuilder node(QName nodeType);\r
-\r
- InstanceIdentifierBuilder nodeWithKey(QName nodeType, Map<QName, Object> keyValues);\r
-\r
- InstanceIdentifierBuilder nodeWithKey(QName nodeType, QName key, Object value);\r
-\r
- @Deprecated\r
- InstanceIdentifier getIdentifier();\r
- }\r
-\r
- public static final class NodeIdentifier implements PathArgument {\r
-\r
+ }
+ return true;
+ }
+
+ // Static factories & helpers
+
+ public static InstanceIdentifier of(QName name) {
+ return new InstanceIdentifier(new NodeIdentifier(name));
+ }
+
+ static public InstanceIdentifierBuilder builder() {
+ return new BuilderImpl();
+ }
+
+ static public InstanceIdentifierBuilder builder(InstanceIdentifier origin) {
+ return new BuilderImpl(origin.getPath());
+ }
+
+ public interface PathArgument extends Immutable, Serializable {
+
+ /**
+ * If applicable returns uniqee QName of data node as defined in YANG
+ * Schema.
+ *
+ * This method may return null, if the corresponding schema node, does
+ * not have QName associated, such as in cases of augmentations.
+ *
+ * @return
+ */
+ QName getNodeType();
+
+ }
+
+ public interface InstanceIdentifierBuilder extends Builder<InstanceIdentifier> {
+ InstanceIdentifierBuilder node(QName nodeType);
+
+ InstanceIdentifierBuilder nodeWithKey(QName nodeType, Map<QName, Object> keyValues);
+
+ InstanceIdentifierBuilder nodeWithKey(QName nodeType, QName key, Object value);
+
+ @Deprecated
+ InstanceIdentifier getIdentifier();
+
+ InstanceIdentifier build();
+ }
+
+ /**
+ * Simple path argument identifying a {@link ContainerNode} or {@link LeafNode} leaf
+ * overal data tree.
+ *
+ */
+ public static final class NodeIdentifier implements PathArgument {
+
/**\r
*\r
- */\r
- private static final long serialVersionUID = -2255888212390871347L;\r
-\r
- private final QName nodeType;\r
-\r
- public NodeIdentifier(QName node) {\r
- this.nodeType = node;\r
- }\r
-\r
+ */
+ private static final long serialVersionUID = -2255888212390871347L;
+
+ private final QName nodeType;
+
+ public NodeIdentifier(QName node) {
+ this.nodeType = node;
+ }
+
+ @Override
+ public QName getNodeType() {
+ return nodeType;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode());
+ return result;
+ }
+
@Override
- public QName getNodeType() {\r
- return nodeType;\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- final int prime = 31;\r
- int result = 1;\r
- result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode());\r
- return result;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj)\r
- return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- NodeIdentifier other = (NodeIdentifier) obj;\r
- if (nodeType == null) {\r
- if (other.nodeType != null)\r
- return false;\r
- } else if (!nodeType.equals(other.nodeType))\r
- return false;\r
- return true;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return nodeType.toString();\r
- }\r
- }\r
-\r
- public static final class NodeIdentifierWithPredicates implements PathArgument {\r
-\r
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ NodeIdentifier other = (NodeIdentifier) obj;
+ if (nodeType == null) {
+ if (other.nodeType != null)
+ return false;
+ } else if (!nodeType.equals(other.nodeType))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return nodeType.toString();
+ }
+ }
+
+ /**
+ *
+ * Composite path argument identifying a {@link MapEntryNode} leaf
+ * overal data tree.
+ *
+ */
+ public static final class NodeIdentifierWithPredicates implements PathArgument {
+
/**\r
*\r
- */\r
- private static final long serialVersionUID = -4787195606494761540L;\r
-\r
- private final QName nodeType;\r
- private final Map<QName, Object> keyValues;\r
-\r
- public NodeIdentifierWithPredicates(QName node, Map<QName, Object> keyValues) {\r
- this.nodeType = node;\r
- this.keyValues = ImmutableMap.copyOf(keyValues);\r
- }\r
-\r
- public NodeIdentifierWithPredicates(QName node, QName key, Object value) {\r
- this.nodeType = node;\r
- this.keyValues = ImmutableMap.of(key, value);\r
- }\r
-\r
- @Override\r
- public QName getNodeType() {\r
- return nodeType;\r
- }\r
-\r
- public Map<QName, Object> getKeyValues() {\r
- return keyValues;\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- final int prime = 31;\r
- int result = 1;\r
- result = prime * result + ((keyValues == null) ? 0 : keyValues.hashCode());\r
- result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode());\r
- return result;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj)\r
- return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- NodeIdentifierWithPredicates other = (NodeIdentifierWithPredicates) obj;\r
- if (keyValues == null) {\r
- if (other.keyValues != null)\r
- return false;\r
- } else if (!keyValues.equals(other.keyValues))\r
- return false;\r
- if (nodeType == null) {\r
- if (other.nodeType != null)\r
- return false;\r
- } else if (!nodeType.equals(other.nodeType))\r
- return false;\r
- return true;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return nodeType + "[" + keyValues + "]";\r
- }\r
+ */
+ private static final long serialVersionUID = -4787195606494761540L;
+
+ private final QName nodeType;
+ private final Map<QName, Object> keyValues;
+
+ public NodeIdentifierWithPredicates(QName node, Map<QName, Object> keyValues) {
+ this.nodeType = node;
+ this.keyValues = ImmutableMap.copyOf(keyValues);
+ }
+
+ public NodeIdentifierWithPredicates(QName node, QName key, Object value) {
+ this.nodeType = node;
+ this.keyValues = ImmutableMap.of(key, value);
+ }
+
+ @Override
+ public QName getNodeType() {
+ return nodeType;
+ }
+
+ public Map<QName, Object> getKeyValues() {
+ return keyValues;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((keyValues == null) ? 0 : keyValues.hashCode());
+ result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ NodeIdentifierWithPredicates other = (NodeIdentifierWithPredicates) obj;
+ if (keyValues == null) {
+ if (other.keyValues != null)
+ return false;
+ } else if (!keyValues.equals(other.keyValues))
+ return false;
+ if (nodeType == null) {
+ if (other.nodeType != null)
+ return false;
+ } else if (!nodeType.equals(other.nodeType))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return nodeType + "[" + keyValues + "]";
+ }
}
+ /**
+ * Simple path argument identifying a {@link LeafSetEntryNode} leaf
+ * overal data tree.
+ *
+ */
public static final class NodeWithValue implements PathArgument {
- /**
- *
- */
+ /**
+ *
+ * Composite path argument identifying a {@link AugmentationNode} leaf
+ * overal data tree.
+ *
+ */
private static final long serialVersionUID = -3637456085341738431L;
private final QName nodeType;
return nodeType + "[" + value + "]";
}
- }\r
-\r
- private static class BuilderImpl implements InstanceIdentifierBuilder {\r
-\r
- private final ImmutableList.Builder<PathArgument> path;\r
-\r
- public BuilderImpl() {\r
- path = ImmutableList.<PathArgument>builder();\r
- }\r
-\r
- public BuilderImpl(List<? extends PathArgument> prefix) {\r
- path = ImmutableList.<PathArgument>builder();\r
- path.addAll(prefix);\r
- }\r
-\r
- @Override\r
- public InstanceIdentifierBuilder node(QName nodeType) {\r
- path.add(new NodeIdentifier(nodeType));\r
- return this;\r
- }\r
-\r
- @Override\r
- public InstanceIdentifierBuilder nodeWithKey(QName nodeType, QName key, Object value) {\r
- path.add(new NodeIdentifierWithPredicates(nodeType, key, value));\r
- return this;\r
- }\r
-\r
- @Override\r
- public InstanceIdentifierBuilder nodeWithKey(QName nodeType, Map<QName, Object> keyValues) {\r
- path.add(new NodeIdentifierWithPredicates(nodeType, keyValues));\r
- return this;\r
- }\r
-\r
- @Override\r
- public InstanceIdentifier toInstance() {\r
- return new InstanceIdentifier(path.build());\r
- }\r
-\r
- @Override\r
- public InstanceIdentifier getIdentifier() {\r
- return toInstance();\r
- }\r
- }\r
-\r
- @Override\r
- public boolean contains(final InstanceIdentifier other) {\r
- if (other == null) {\r
- throw new IllegalArgumentException("other should not be null");\r
- }\r
- final int localSize = this.path.size();\r
- final List<PathArgument> otherPath = other.getPath();\r
- if (localSize > other.path.size()) {\r
- return false;\r
- }\r
- for (int i = 0; i < localSize; i++) {\r
- if (!path.get(i).equals(otherPath.get(i))) {\r
- return false;\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- @Override\r
+ }
+
+
+ public static final class AugmentationIdentifier implements PathArgument {
+
+
+ private static final long serialVersionUID = -8122335594681936939L;
+ private final QName nodeType;
+ private final ImmutableSet<QName> childNames;
+
+ @Override
+ public QName getNodeType() {
+ return nodeType;
+ }
+
+ public AugmentationIdentifier(QName nodeType, Set<QName> childNames) {
+ super();
+ this.nodeType = nodeType;
+ this.childNames = ImmutableSet.copyOf(childNames);
+ }
+
+ public Set<QName> getPossibleChildNames() {
+ return childNames;
+ }
+
+ }
+
+ private static class BuilderImpl implements InstanceIdentifierBuilder {
+
+ private final ImmutableList.Builder<PathArgument> path;
+
+ public BuilderImpl() {
+ path = ImmutableList.<PathArgument> builder();
+ }
+
+ public BuilderImpl(List<? extends PathArgument> prefix) {
+ path = ImmutableList.<PathArgument> builder();
+ path.addAll(prefix);
+ }
+
+ @Override
+ public InstanceIdentifierBuilder node(QName nodeType) {
+ path.add(new NodeIdentifier(nodeType));
+ return this;
+ }
+
+ @Override
+ public InstanceIdentifierBuilder nodeWithKey(QName nodeType, QName key, Object value) {
+ path.add(new NodeIdentifierWithPredicates(nodeType, key, value));
+ return this;
+ }
+
+ @Override
+ public InstanceIdentifierBuilder nodeWithKey(QName nodeType, Map<QName, Object> keyValues) {
+ path.add(new NodeIdentifierWithPredicates(nodeType, keyValues));
+ return this;
+ }
+
+ @Override
+ @Deprecated
+ public InstanceIdentifier toInstance() {
+ return build();
+ }
+
+ @Override
+ public InstanceIdentifier build() {
+ return new InstanceIdentifier(path.build());
+ }
+
+ @Override
+ @Deprecated
+ public InstanceIdentifier getIdentifier() {
+ return build();
+ }
+ }
+
+ @Override
+ public boolean contains(final InstanceIdentifier other) {
+ if (other == null) {
+ throw new IllegalArgumentException("other should not be null");
+ }
+ final int localSize = this.path.size();
+ final List<PathArgument> otherPath = other.getPath();
+ if (localSize > other.path.size()) {
+ return false;
+ }
+ for (int i = 0; i < localSize; i++) {
+ if (!path.get(i).equals(otherPath.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
public String toString() {
/*
- * The toStringCache is safe, since the object contract requires immutability
- * of the object and all objects referenced from this object.
+ * The toStringCache is safe, since the object contract requires
+ * immutability of the object and all objects referenced from this
+ * object.
*
- * Used lists, maps are immutable. Path Arguments (elements) are also immutable,
- * since the PathArgument contract requires immutability.
+ * Used lists, maps are immutable. Path Arguments (elements) are also
+ * immutable, since the PathArgument contract requires immutability.
*
- * The cache is thread-safe - if multiple computations occurs at the same time,
- * cache will be overwritten with same result.
- */\r
- if (toStringCache != null) {\r
- return toStringCache;\r
- }\r
- StringBuilder builder = new StringBuilder();\r
- for (PathArgument argument : path) {\r
- builder.append("/");\r
- builder.append(argument.toString());\r
- }\r
- toStringCache = builder.toString();\r
- return toStringCache;\r
- }\r
-\r
- public static InstanceIdentifierBuilder builder(QName node) {\r
- return builder().node(node);\r
- }\r
-}\r
+ * The cache is thread-safe - if multiple computations occurs at the
+ * same time, cache will be overwritten with same result.
+ */
+ if (toStringCache != null) {
+ return toStringCache;
+ }
+ StringBuilder builder = new StringBuilder();
+ for (PathArgument argument : path) {
+ builder.append("/");
+ builder.append(argument.toString());
+ }
+ toStringCache = builder.toString();
+ return toStringCache;
+ }
+
+ public static InstanceIdentifierBuilder builder(QName node) {
+ return builder().node(node);
+ }
+}
*/\r
package org.opendaylight.yangtools.yang.data.api;\r
\r
+import java.util.Arrays;\r
+\r
+// TODO rename to ModifyOperation\r
+\r
+/**\r
+ * http://tools.ietf.org/html/rfc6241#section-7.2\r
+ */\r
public enum ModifyAction {\r
- MERGE, REPLACE, CREATE, DELETE, REMOVE\r
+ MERGE, REPLACE, CREATE, DELETE, REMOVE, NONE;\r
+\r
+ public static ModifyAction fromXmlValue(String xmlNameOfAction) {\r
+ switch (xmlNameOfAction) {\r
+ case "merge":\r
+ return MERGE;\r
+ case "replace":\r
+ return REPLACE;\r
+ case "remove":\r
+ return REMOVE;\r
+ case "delete":\r
+ return DELETE;\r
+ case "create":\r
+ return CREATE;\r
+ case "none":\r
+ return NONE;\r
+ default:\r
+ throw new IllegalArgumentException("Unknown operation " + xmlNameOfAction + " available operations "\r
+ + Arrays.toString(ModifyAction.values()));\r
+ }\r
+ }\r
+\r
+ public boolean isAsDefaultPermitted() {\r
+ boolean isPermitted = this == MERGE;\r
+ isPermitted |= this == REPLACE;\r
+ isPermitted |= this == NONE;\r
+ return isPermitted;\r
+ }\r
+\r
+ public boolean isOnElementPermitted() {\r
+ return this != NONE;\r
+ }\r
+\r
}\r
*
*/
public interface MutableCompositeNode extends MutableNode<List<Node<?>>>, CompositeNode {
-
+
/**
* update internal map
*/
+ @Deprecated
void init();
-
+
/**
* @return original node, if available
*/
*/\r
package org.opendaylight.yangtools.yang.data.api;\r
\r
+import org.opendaylight.yangtools.concepts.Mutable;\r
+\r
\r
/**\r
* Base representation of node in the data tree, defines basic parameters of\r
* node such as a QName.\r
- * \r
- * \r
+ *\r
+ *\r
* @param <T>\r
*/\r
-public interface MutableNode<T> extends Node<T> {\r
+public interface MutableNode<T> extends Node<T>,Mutable {\r
\r
/**\r
* @param parent value to set\r
*/\r
void setParent(CompositeNode parent);\r
- \r
+\r
/**\r
* @param value value to set (children list or leaf value)\r
*/\r
+ @Override\r
T setValue(T value);\r
- \r
+\r
/**\r
* @param action value to set\r
*/\r
*\r
* @return parent node\r
*/\r
+ @Deprecated\r
CompositeNode getParent();\r
\r
/**\r
*\r
* @return Returns the value that holds current node.\r
*/\r
+ @Override\r
T getValue();\r
}\r
\r
/**\r
* @author michal.rehak\r
- * \r
+ *\r
*/\r
+@Deprecated\r
public interface NodeModification {\r
\r
/**\r
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+
+
+/**
+ *
+ * Node representing Augmentation.
+ *
+ * Augmentation node MUST NOT be direct child of other augmentation node.
+ *
+ */
+public interface AugmentationNode extends //
+ MixinNode, //
+ DataContainerNode<AugmentationIdentifier>,
+ DataContainerChild<InstanceIdentifier.AugmentationIdentifier, Iterable<DataContainerChild<? extends PathArgument, ?>>> {
+
+ @Override
+ public Iterable<DataContainerChild<? extends PathArgument, ?>> getValue();
+
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(PathArgument child);
+
+ @Override
+ public AugmentationIdentifier getIdentifier();
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+
+/**
+ *
+ * Node representing choice.
+ *
+ * @author Tony Tkacik
+ *
+ */
+public interface ChoiceNode extends //
+ MixinNode, //
+ DataContainerNode<NodeIdentifier>,
+ DataContainerChild<NodeIdentifier, Iterable<DataContainerChild<? extends PathArgument, ?>>> {
+
+ @Override
+ public NodeIdentifier getIdentifier();
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(PathArgument child);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+
+public interface ContainerNode extends //
+ DataContainerNode<NodeIdentifier>,
+ DataContainerChild<NodeIdentifier, Iterable<DataContainerChild<? extends PathArgument, ?>>> {
+
+ @Override
+ public NodeIdentifier getIdentifier();
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(PathArgument child);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+/**
+ *
+ * Marker interface for direct children of {@link DataContainerNode}.
+ *
+ * Implementation notes:
+ * This interface should not be implemented directly, but rather using one
+ * of its subinterfaces:
+ *
+ *
+ * {@link LeafNode}
+ * {@link ContainerNode}
+ * {@link ChoiceNode}
+ * {@link MapNode}
+ * {@link AugmentationNode}
+ *
+ * @param <K>
+ * @param <V>
+ */
+public interface DataContainerChild<K extends PathArgument,V> extends NormalizedNode<K, V> {
+
+ @Override
+ public K getIdentifier();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+
+public interface DataContainerNode<K extends PathArgument> extends //
+ NormalizedNodeContainer<K, PathArgument, DataContainerChild<? extends PathArgument, ?>> {
+
+ @Override
+ public K getIdentifier();
+
+ @Override
+ public Iterable<DataContainerChild<? extends PathArgument, ?>> getValue();
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(PathArgument child);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+
+public interface LeafNode<T> extends //
+ DataContainerChild<NodeIdentifier, T> {
+
+ @Override
+ public NodeIdentifier getIdentifier();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+
+public interface LeafSetEntryNode<T> extends NormalizedNode<NodeWithValue, T> {
+
+ @Override
+ public NodeWithValue getIdentifier();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+
+import com.google.common.base.Optional;
+
+public interface LeafSetNode<T> extends
+ MixinNode, //
+ DataContainerChild<NodeIdentifier, Iterable<LeafSetEntryNode<T>>>, //
+ NormalizedNodeContainer<NodeIdentifier, NodeWithValue,LeafSetEntryNode<T>> {
+
+ @Override
+ public NodeIdentifier getIdentifier();
+
+ @Override
+ public Iterable<LeafSetEntryNode<T>> getValue();
+
+
+ @Override
+ public Optional<LeafSetEntryNode<T>> getChild(NodeWithValue child);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+
+public interface MapEntryNode extends DataContainerNode<NodeIdentifierWithPredicates> {
+
+ @Override
+ public NodeIdentifierWithPredicates getIdentifier();
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+
+/**
+ * Containment node, which contains {@link MapEntryNode} of the same type.
+ *
+ * This node maps to the list node in YANG schema.
+ *
+ */
+public interface MapNode extends //
+ MixinNode,
+ DataContainerChild<NodeIdentifier, Iterable<MapEntryNode>>,
+ NormalizedNodeContainer<NodeIdentifier, NodeIdentifierWithPredicates, MapEntryNode> {
+
+ @Override
+ public NodeIdentifier getIdentifier();
+
+
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+/**
+ *
+ * Marker interface for nodes, which are mixins - their content
+ * belongs to parent node and in serialized form this node
+ * does not exists, but it's children are present.
+ *
+ */
+public interface MixinNode {
+
+}
--- /dev/null
+package org.opendaylight.yangtools.yang.data.api.schema;
+
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+
+/**
+ *
+ * Node which is normalized according to the YANG schema
+ * is identifiable by {@link InstanceIdentifier}.
+ *
+ *
+ * @author Tony Tkacik
+ *
+ * @param <K> Local identifier of node
+ * @param <V> Value of node
+ */
+public interface NormalizedNode<K extends InstanceIdentifier.PathArgument,V> extends
+ Identifiable<K>, //
+ Node<V> {
+
+ /**
+ *
+ * QName of the node as defined in YANG schema.
+ *
+ */
+ @Override
+ public QName getNodeType();
+
+ /**
+ *
+ * Locally unique identifier of nodes
+ *
+ */
+ @Override
+ public K getIdentifier();
+
+ /**
+ *
+ * Value of node
+ *
+ */
+ @Override
+ public V getValue();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.api.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+
+/**
+ *
+ * @param <I> Node Identifier type
+ * @param <K> Child Node Identifier type
+ * @param <V> Child Node type
+ */
+public interface NormalizedNodeContainer<I extends PathArgument, K extends PathArgument, V extends NormalizedNode<? extends K, ?>>
+ extends NormalizedNode<I, Iterable<V>> {
+
+ @Override
+ public I getIdentifier();
+
+ @Override
+ public Iterable<V> getValue();
+
+ /**
+ *
+ *
+ * @param child
+ * @return
+ */
+ Optional<V> getChild(K child);
+}
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
- <version>1.4</version>
+ <version>1.5</version>
<scope>test</scope>
</dependency>
<dependency>
*/
package org.opendaylight.yangtools.yang.data.impl;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.NodeModification;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+import java.net.URI;
+import java.util.Map;
/**
* @author michal.rehak
* @param <T>
* type of node value
- *
+ *
*/
public abstract class AbstractNodeTO<T> implements Node<T>, NodeModification {
* @param value
*/
public AbstractNodeTO(QName qname, CompositeNode parent, T value) {
- this.qName = qname;
- this.parent = parent;
- this.value = value;
+ this(qname, parent, value, null);
}
/**
.getLocalName(), getModificationAction() == null ? "n/a" : getModificationAction()));
return out.toString();
}
-
-
+
+
@Override
public final QName getKey() {
return getNodeType();
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((modifyAction == null) ? 0 : modifyAction.hashCode());
result = prime * result + ((qName == null) ? 0 : qName.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result % 2;
}
@SuppressWarnings("unchecked")
AbstractNodeTO<T> other = (AbstractNodeTO<T>) obj;
- if (modifyAction != other.modifyAction) {
- return false;
- }
if (parent == null) {
if (other.parent != null) {
return false;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.util.AbstractCompositeNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
import com.google.common.collect.ImmutableList;
public static ImmutableCompositeNode create(QName qName, List<Node<?>> childNodes) {
return new ImmutableCompositeNode(qName, ImmutableMap.<QName, String>of(),childNodes);
}
-
+
public static ImmutableCompositeNode create(QName qName, Map<QName, String> attributes, List<Node<?>> childNodes) {
return new ImmutableCompositeNode(qName, attributes,childNodes);
}
+
+ public static ImmutableCompositeNode create(QName qName, List<Node<?>> childNodes, ModifyAction modifyAction) {
+ return new ImmutableCompositeNode(qName, childNodes, modifyAction);
+ }
}
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
+import com.google.common.collect.Maps;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.ModifyAction;
/**
* @author michal.rehak
- *
+ *
*/
public abstract class NodeUtils {
/**
* build NodeMap, where key = qName; value = node
- *
+ *
* @param value
* @return map of children, where key = qName and value is list of children
* groupped by qName
*/
public static Map<QName, List<Node<?>>> buildNodeMap(List<Node<?>> value) {
- Map<QName, List<Node<?>>> nodeMapTmp = new HashMap<>();
+ Map<QName, List<Node<?>>> nodeMapTmp = Maps.newLinkedHashMap();
if (value == null) {
throw new IllegalStateException("nodeList should not be null or empty");
}
/**
* add given node to it's parent's list of children
- *
+ *
* @param newNode
*/
public static void fixParentRelation(Node<?> newNode) {
/**
* crawl all children of given node and assign it as their parent
- *
+ *
* @param parentNode
*/
public static void fixChildrenRelation(CompositeNode parentNode) {
import java.io.ObjectInputStream;\r
import java.io.ObjectOutputStream;\r
import java.io.Serializable;\r
+import java.util.Map;\r
\r
/**\r
* @author michal.rehak\r
super(qname, parent, value, modifyAction);\r
}\r
\r
-\r
@Override\r
public MutableSimpleNode<T> asMutable() {\r
throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
aStream.writeObject(getValue());\r
aStream.writeObject(getModificationAction());\r
}\r
+\r
}\r
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import com.google.common.collect.Maps;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
+import org.w3c.dom.*;
import com.google.common.base.Function;
import com.google.common.base.Objects;
private static final Logger logger = LoggerFactory.getLogger(XmlDocumentUtils.class);
/**
- * Converts Data DOM structure to XML Document for specified XML Codec Provider and corresponding
- * Data Node Container schema. The CompositeNode data parameter enters as root of Data DOM tree and will
- * be transformed to root in XML Document. Each element of Data DOM tree is compared against specified Data
+ * Converts Data DOM structure to XML Document for specified XML Codec Provider and corresponding
+ * Data Node Container schema. The CompositeNode data parameter enters as root of Data DOM tree and will
+ * be transformed to root in XML Document. Each element of Data DOM tree is compared against specified Data
* Node Container Schema and transformed accordingly.
- *
+ *
* @param data Data DOM root element
* @param schema Data Node Container Schema
* @param codecProvider XML Codec Provider
Preconditions.checkNotNull(data);
Preconditions.checkNotNull(schema);
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- Document doc = null;
- try {
- DocumentBuilder bob = dbf.newDocumentBuilder();
- doc = bob.newDocument();
- } catch (ParserConfigurationException e) {
- return null;
- }
+ Document doc = getDocument();
if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) {
doc.appendChild(createXmlRootElement(doc, data, (SchemaNode) schema, codecProvider));
}
}
+ public static Document getDocument() {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ Document doc = null;
+ try {
+ DocumentBuilder bob = dbf.newDocumentBuilder();
+ doc = bob.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ return doc;
+ }
+
/**
* Converts Data DOM structure to XML Document for specified XML Codec Provider. The CompositeNode
* data parameter enters as root of Data DOM tree and will be transformed to root in XML Document. The child
* nodes of Data Tree are transformed accordingly.
- *
+ *
* @param data Data DOM root element
* @param codecProvider XML Codec Provider
* @return new instance of XML Document
Preconditions.checkNotNull(data);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
Document doc = null;
try {
DocumentBuilder bob = dbf.newDocumentBuilder();
return itemEl;
}
- private static Element createElementFor(Document doc, Node<?> data) {
+ public static Element createElementFor(Document doc, Node<?> data) {
QName dataType = data.getNodeType();
Element ret;
if (dataType.getNamespace() != null) {
public static void writeValueByType(Element element, SimpleNode<?> node, TypeDefinition<?> type,
DataSchemaNode schema, XmlCodecProvider codecProvider) {
- TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ Object nodeValue = node.getValue();
+
+ writeValueByType(element, type, codecProvider, nodeValue);
+ }
+
+ public static void writeValueByType(Element element, TypeDefinition<?> type, XmlCodecProvider codecProvider, Object nodeValue) {
+ TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
if (baseType instanceof IdentityrefTypeDefinition) {
- if (node.getValue() instanceof QName) {
- QName value = (QName) node.getValue();
+ if (nodeValue instanceof QName) {
+ QName value = (QName) nodeValue;
String prefix = "x";
if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
prefix = value.getPrefix();
element.setAttribute("xmlns:" + prefix, value.getNamespace().toString());
element.setTextContent(prefix + ":" + value.getLocalName());
} else {
- Object value = node.getValue();
+ Object value = nodeValue;
logger.debug("Value of {}:{} is not instance of QName but is {}", baseType.getQName().getNamespace(),
baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
if (value != null) {
}
}
} else if (baseType instanceof InstanceIdentifierTypeDefinition) {
- if (node.getValue() instanceof InstanceIdentifier) {
+ if (nodeValue instanceof InstanceIdentifier) {
// Map< key = namespace, value = prefix>
Map<String, String> prefixes = new HashMap<>();
- InstanceIdentifier instanceIdentifier = (InstanceIdentifier) node.getValue();
+ InstanceIdentifier instanceIdentifier = (InstanceIdentifier) nodeValue;
StringBuilder textContent = new StringBuilder();
for (PathArgument pathArgument : instanceIdentifier.getPath()) {
textContent.append("/");
element.setTextContent(textContent.toString());
} else {
- Object value = node.getValue();
+ Object value = nodeValue;
logger.debug("Value of {}:{} is not instance of InstanceIdentifier but is {}", baseType.getQName()
.getNamespace(), //
baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
}
}
} else {
- if (node.getValue() != null) {
+ if (nodeValue != null) {
final TypeDefinitionAwareCodec<Object, ?> codec = codecProvider.codecFor(baseType);
if (codec != null) {
try {
- final String text = codec.serialize(node.getValue());
+ final String text = codec.serialize(nodeValue);
element.setTextContent(text);
} catch (ClassCastException e) {
- logger.error("Provided node {} did not have type {} required by mapping. Using stream instead.", node, baseType, e);
- element.setTextContent(String.valueOf(node.getValue()));
+ logger.error("Provided node value {} did not have type {} required by mapping. Using stream instead.", nodeValue, baseType, e);
+ element.setTextContent(String.valueOf(nodeValue));
}
} else {
logger.error("Failed to find codec for {}, falling back to using stream", baseType);
- element.setTextContent(String.valueOf(node.getValue()));
+ element.setTextContent(String.valueOf(nodeValue));
}
}
}
return node.toInstance();
}
- private static QName qNameFromElement(Element xmlElement) {
+ public static QName qNameFromElement(Element xmlElement) {
String namespace = xmlElement.getNamespaceURI();
String localName = xmlElement.getLocalName();
return QName.create(namespace != null ? URI.create(namespace) : null, null, localName);
} else {
value = xmlElement.getTextContent();
}
- return new SimpleNodeTOImpl<Object>(schema.getQName(), null, value);
+
+ Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+ return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
}
private static Node<?> toSimpleNodeWithType(Element xmlElement, LeafListSchemaNode schema,
} else {
value = xmlElement.getTextContent();
}
- return new SimpleNodeTOImpl<Object>(schema.getQName(), null, value);
+
+ Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+ return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
}
private static Node<?> toCompositeNodeWithSchema(Element xmlElement, QName qName, DataNodeContainer schema,
XmlCodecProvider codecProvider) {
List<Node<?>> values = toDomNodes(xmlElement, Optional.fromNullable(schema.getChildNodes()));
- return ImmutableCompositeNode.create(qName, values);
+ Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+ return ImmutableCompositeNode.create(qName, values, modifyAction.orNull());
+ }
+
+ public static final QName OPERATION_ATTRIBUTE_QNAME = QName.create(URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"), null, "operation");
+
+ public static Optional<ModifyAction> getModifyOperationFromAttributes(Element xmlElement) {
+ Attr attributeNodeNS = xmlElement.getAttributeNodeNS(OPERATION_ATTRIBUTE_QNAME.getNamespace().toString(), OPERATION_ATTRIBUTE_QNAME.getLocalName());
+ if(attributeNodeNS == null)
+ return Optional.absent();
+
+ ModifyAction action = ModifyAction.fromXmlValue(attributeNodeNS.getValue());
+ Preconditions.checkArgument(action.isOnElementPermitted(), "Unexpected operation %s on %s", action, xmlElement);
+
+ return Optional.of(action);
}
private static void checkQName(Element xmlElement, QName qName) {
checkState(qName.getLocalName().equals(xmlElement.getLocalName()));
}
- private static final Optional<DataSchemaNode> findFirstSchema(QName qname, Set<DataSchemaNode> dataSchemaNode) {
+ public static final Optional<DataSchemaNode> findFirstSchema(QName qname, Set<DataSchemaNode> dataSchemaNode) {
if (dataSchemaNode != null && !dataSchemaNode.isEmpty() && qname != null) {
for (DataSchemaNode dsn : dataSchemaNode) {
if (qname.isEqualWithoutRevision(dsn.getQName())) {
});
}
-
+
/**
* Converts XML Document containing notification data from Netconf device to
* Data DOM Nodes. <br>
* begins in element which is equal to notifications name defined in
* corresponding yang model. Rest of notification metadata are obfuscated,
* thus Data DOM contains only pure notification body.
- *
+ *
* @param document
* XML Document containing notification body
* @param notifications
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.*;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.*;
+import org.opendaylight.yangtools.yang.model.api.*;
+
+public class Builders {
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> leafBuilder() {
+ return ImmutableLeafNodeBuilder.create();
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> leafBuilder(
+ LeafSchemaNode schema) {
+ return ImmutableLeafNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> leafSetEntryBuilder() {
+ return ImmutableLeafSetEntryNodeBuilder.create();
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> leafSetEntryBuilder(
+ LeafListSchemaNode schema) {
+ return ImmutableLeafSetEntryNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> leafSetBuilder() {
+ return ImmutableLeafSetNodeBuilder.create();
+ }
+
+ public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> leafSetBuilder(LeafListSchemaNode schema) {
+ return ImmutableLeafSetNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> containerBuilder() {
+ return ImmutableContainerNodeBuilder.create();
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> containerBuilder(
+ ContainerSchemaNode schema) {
+ return ImmutableContainerNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder() {
+ return ImmutableMapEntryNodeBuilder.create();
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder(
+ ListSchemaNode schema) {
+ return ImmutableMapEntryNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder() {
+ return ImmutableMapNodeBuilder.create();
+ }
+
+ public static CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder(ListSchemaNode schema) {
+ return ImmutableMapNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> augmentationBuilder() {
+ return ImmutableAugmentationNodeBuilder.create();
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> augmentationBuilder(AugmentationSchema schema) {
+ return ImmutableAugmentationNodeSchemaAwareBuilder.create(schema);
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> choiceBuilder() {
+ return ImmutableChoiceNodeBuilder.create();
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> choiceBuilder(org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+ return ImmutableChoiceNodeSchemaAwareBuilder.create(schema);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.api;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface CollectionNodeBuilder<V, R extends NormalizedNode<InstanceIdentifier.NodeIdentifier, ?>>
+ extends NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, List<V>, R> {
+
+ //TODO might be list to keep ordering and map internal
+ @Override
+ CollectionNodeBuilder<V, R> withValue(List<V> value);
+
+ @Override
+ CollectionNodeBuilder<V, R> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier);
+
+ CollectionNodeBuilder<V, R> withChild(V child);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+
+public interface DataContainerNodeBuilder<I extends InstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
+ extends NormalizedNodeBuilder<I, List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>, R> {
+
+ @Override
+ DataContainerNodeBuilder<I, R> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value);
+
+ @Override
+ DataContainerNodeBuilder<I, R> withNodeIdentifier(I nodeIdentifier);
+
+ DataContainerNodeBuilder<I, R> withChild(DataContainerChild<?, ?> child);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.api;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+
+public interface ListNodeBuilder<T, V>
+ extends CollectionNodeBuilder<V, LeafSetNode<T>> {
+
+ @Override
+ ListNodeBuilder<T, V> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier);
+
+ @Override
+ ListNodeBuilder<T, V> withValue(List<V> value);
+
+ @Override
+ ListNodeBuilder<T, V> withChild(V child);
+
+ ListNodeBuilder<T, V> withChildValue(T child);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.api;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface NormalizedNodeBuilder<I extends InstanceIdentifier.PathArgument, V, R extends NormalizedNode<I, ?>> {
+
+ NormalizedNodeBuilder<I, V, R> withValue(V value);
+
+ NormalizedNodeBuilder<I, V, R> withNodeIdentifier(I nodeIdentifier);
+
+ R build();
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+
+import com.google.common.collect.Maps;
+
+abstract class AbstractImmutableDataContainerNodeBuilder<I extends InstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
+ implements DataContainerNodeBuilder<I, R> {
+
+ protected Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value;
+ protected I nodeIdentifier;
+
+ protected AbstractImmutableDataContainerNodeBuilder() {
+ this.value = Maps.newLinkedHashMap();
+ }
+
+ @Override
+ public DataContainerNodeBuilder<I, R> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
+ // TODO Replace or putAll ?
+ for (DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild : value) {
+ withChild(dataContainerChild);
+ }
+ return this;
+ }
+
+ @Override
+ public DataContainerNodeBuilder<I, R> withChild(DataContainerChild<?, ?> child) {
+ this.value.put(child.getIdentifier(), child);
+ return this;
+ }
+
+
+ @Override
+ public DataContainerNodeBuilder<I, R> withNodeIdentifier(I nodeIdentifier) {
+ this.nodeIdentifier = nodeIdentifier;
+ return this;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+
+abstract class AbstractImmutableNormalizedNodeBuilder<I extends InstanceIdentifier.PathArgument, V, R extends NormalizedNode<I, ?>>
+ implements NormalizedNodeBuilder<I,V,R> {
+
+ protected V value;
+ protected I nodeIdentifier;
+
+ @Override
+ public NormalizedNodeBuilder<I,V,R> withValue(V value) {
+ this.value = value;
+ return this;
+ }
+
+
+ @Override
+ public NormalizedNodeBuilder<I,V,R> withNodeIdentifier(I nodeIdentifier) {
+ this.nodeIdentifier = nodeIdentifier;
+ return this;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
+
+import com.google.common.base.Preconditions;
+
+public class ImmutableAugmentationNodeBuilder
+ extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> {
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> create() {
+ return new ImmutableAugmentationNodeBuilder();
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> withChild(
+ DataContainerChild<?, ?> child) {
+ // Check nested augments
+ Preconditions.checkArgument(child instanceof AugmentationNode == false,
+ "Unable to add: %s, as a child for: %s, Nested augmentations are not permitted", child.getNodeType(),
+ nodeIdentifier == null ? this : nodeIdentifier);
+
+ return super.withChild(child);
+ }
+
+ @Override
+ public AugmentationNode build() {
+ return new ImmutableAugmentationNode(nodeIdentifier, value);
+ }
+
+ static final class ImmutableAugmentationNode
+ extends AbstractImmutableDataContainerNode<InstanceIdentifier.AugmentationIdentifier>
+ implements AugmentationNode {
+
+ ImmutableAugmentationNode(InstanceIdentifier.AugmentationIdentifier nodeIdentifier, Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+ super(children, nodeIdentifier);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+public class ImmutableAugmentationNodeSchemaAwareBuilder extends ImmutableAugmentationNodeBuilder {
+
+ private final DataNodeContainerValidator validator;
+
+ protected ImmutableAugmentationNodeSchemaAwareBuilder(AugmentationSchema schema) {
+ super();
+ this.validator = new DataNodeContainerValidator(schema);
+ // TODO no QName for augmentation
+ super.withNodeIdentifier(new InstanceIdentifier.AugmentationIdentifier(null, getChildQNames(schema)));
+ }
+
+ // TODO move somewhere to UTIL
+ public static Set<QName> getChildQNames(AugmentationSchema schema) {
+ Set<QName> qnames = Sets.newHashSet();
+
+ for (DataSchemaNode dataSchemaNode : schema.getChildNodes()) {
+ qnames.add(dataSchemaNode.getQName());
+ }
+
+ return qnames;
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> withNodeIdentifier(InstanceIdentifier.AugmentationIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> withChild(DataContainerChild<?, ?> child) {
+ validator.validateChild(child.getIdentifier());
+ return super.withChild(child);
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> create(AugmentationSchema schema) {
+ return new ImmutableAugmentationNodeSchemaAwareBuilder(schema);
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
+
+public class ImmutableChoiceNodeBuilder extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> {
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> create() {
+ return new ImmutableChoiceNodeBuilder();
+ }
+
+ public ChoiceNode build() {
+ return new ImmutableChoiceNode(nodeIdentifier, value);
+ }
+
+ static final class ImmutableChoiceNode
+ extends AbstractImmutableDataContainerNode<InstanceIdentifier.NodeIdentifier>
+ implements ChoiceNode {
+
+ ImmutableChoiceNode(InstanceIdentifier.NodeIdentifier nodeIdentifier,
+ Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+ super(children, nodeIdentifier);
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import com.google.common.base.Preconditions;
+
+public class ImmutableChoiceNodeSchemaAwareBuilder extends ImmutableChoiceNodeBuilder {
+
+ private final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema;
+ private ChoiceCaseNode detectedCase;
+ private DataNodeContainerValidator validator;
+
+ protected ImmutableChoiceNodeSchemaAwareBuilder(org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+ super();
+ this.schema = schema;
+ super.withNodeIdentifier(new InstanceIdentifier.NodeIdentifier(schema.getQName()));
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> withChild(DataContainerChild<?, ?> child) {
+ if(detectedCase == null) {
+ detectedCase = detectCase(child);
+ validator = new DataNodeContainerValidator(detectedCase);
+ }
+
+ validator.validateChild(child.getIdentifier());
+
+ return super.withChild(child);
+ }
+
+ @Override
+ public ChoiceNode build() {
+ // TODO validate when statement
+ return super.build();
+ }
+
+ private ChoiceCaseNode detectCase(DataContainerChild<?, ?> child) {
+ for (ChoiceCaseNode choiceCaseNode : schema.getCases()) {
+ for (DataSchemaNode childFromCase : choiceCaseNode.getChildNodes()) {
+ if (childFromCase.getQName().equals(child.getNodeType())) {
+ return choiceCaseNode;
+ }
+ }
+ }
+
+ throw new IllegalArgumentException(String.format("Unknown child node: %s, for choice: %s", child.getNodeType(),
+ schema.getQName()));
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> create(org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+ return new ImmutableChoiceNodeSchemaAwareBuilder(schema);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
+
+public class ImmutableContainerNodeBuilder extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> {
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> create() {
+ return new ImmutableContainerNodeBuilder();
+ }
+
+ @Override
+ public ContainerNode build() {
+ return new ImmutableContainerNode(nodeIdentifier, value);
+ }
+
+ final class ImmutableContainerNode
+ extends AbstractImmutableDataContainerNode<InstanceIdentifier.NodeIdentifier>
+ implements ContainerNode {
+
+ ImmutableContainerNode(
+ InstanceIdentifier.NodeIdentifier nodeIdentifier,
+ Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+ super(children, nodeIdentifier);
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+
+public final class ImmutableContainerNodeSchemaAwareBuilder extends ImmutableContainerNodeBuilder {
+
+ private final DataNodeContainerValidator validator;
+
+ // TODO remove schema aware builders, replace by validator called at build()
+
+ private ImmutableContainerNodeSchemaAwareBuilder(ContainerSchemaNode schema) {
+ super();
+ this.validator = new DataNodeContainerValidator(schema);
+ super.withNodeIdentifier(new InstanceIdentifier.NodeIdentifier(schema.getQName()));
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> create(ContainerSchemaNode schema) {
+ return new ImmutableContainerNodeSchemaAwareBuilder(schema);
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> withChild(DataContainerChild<?, ?> child) {
+ validator.validateChild(child.getIdentifier());
+ return super.withChild(child);
+ }
+
+ @Override
+ public ContainerNode build() {
+ // TODO check when statements... somewhere
+ return super.build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
+
+public class ImmutableLeafNodeBuilder<T> extends AbstractImmutableNormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> {
+
+ protected ImmutableLeafNodeBuilder() {
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> create() {
+ return new ImmutableLeafNodeBuilder<>();
+ }
+
+ @Override
+ public LeafNode<T> build() {
+ return new ImmutableLeafNode<>(nodeIdentifier, value);
+ }
+
+ static final class ImmutableLeafNode<T> extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, T> implements LeafNode<T> {
+
+ ImmutableLeafNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, T value) {
+ super(nodeIdentifier, value);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ImmutableLeafNode{");
+ sb.append("nodeIdentifier=").append(nodeIdentifier);
+ sb.append(", value=").append(value);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+
+public final class ImmutableLeafNodeSchemaAwareBuilder<T> extends ImmutableLeafNodeBuilder<T> {
+
+ private final LeafSchemaNode schema;
+
+ private ImmutableLeafNodeSchemaAwareBuilder(LeafSchemaNode schema) {
+ super();
+ this.schema = schema;
+ super.withNodeIdentifier(new InstanceIdentifier.NodeIdentifier(schema.getQName()));
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> create(LeafSchemaNode schema) {
+ return new ImmutableLeafNodeSchemaAwareBuilder<>(schema);
+ }
+
+ @Override
+ public NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> withValue(T value) {
+// TODO check value type
+ return super.withValue(value);
+ }
+
+ @Override
+ public NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
+
+import com.google.common.base.Preconditions;
+
+public class ImmutableLeafSetEntryNodeBuilder<T> extends AbstractImmutableNormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> {
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> create() {
+ return new ImmutableLeafSetEntryNodeBuilder<>();
+ }
+
+ @Override
+ public LeafSetEntryNode<T> build() {
+ return new ImmutableLeafSetEntryNode<>(nodeIdentifier, value);
+ }
+
+ static final class ImmutableLeafSetEntryNode<T> extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeWithValue, T> implements LeafSetEntryNode<T> {
+
+ ImmutableLeafSetEntryNode(InstanceIdentifier.NodeWithValue nodeIdentifier, T value) {
+ super(nodeIdentifier, value);
+ Preconditions.checkArgument(nodeIdentifier.getValue().equals(value),
+ "Node identifier contains different value: %s than value itself: %s", nodeIdentifier, value);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ImmutableLeafSetEntryNode{");
+ sb.append("nodeIdentifier=").append(nodeIdentifier);
+ sb.append(", value=").append(value);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+public final class ImmutableLeafSetEntryNodeSchemaAwareBuilder<T> extends ImmutableLeafSetEntryNodeBuilder<T> {
+
+ private final LeafListSchemaNode schema;
+
+ private ImmutableLeafSetEntryNodeSchemaAwareBuilder(LeafListSchemaNode schema) {
+ super();
+ this.schema = schema;
+ }
+
+ public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> create(LeafListSchemaNode schema) {
+ return new ImmutableLeafSetEntryNodeSchemaAwareBuilder<>(schema);
+ }
+
+ @Override
+ public NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> withValue(T value) {
+ super.withNodeIdentifier(new InstanceIdentifier.NodeWithValue(schema.getQName(), value));
+ // TODO check value type
+ return super.withValue(value);
+ }
+
+ @Override
+ public NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> withNodeIdentifier(InstanceIdentifier.NodeWithValue nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+public class ImmutableLeafSetNodeBuilder<T>
+ implements ListNodeBuilder<T, LeafSetEntryNode<T>> {
+
+ protected Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> value;
+ protected InstanceIdentifier.NodeIdentifier nodeIdentifier;
+
+ public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create() {
+ return new ImmutableLeafSetNodeBuilder<>();
+ }
+
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withChild(LeafSetEntryNode<T> child) {
+ if(this.value == null) {
+ this.value = Maps.newLinkedHashMap();
+ }
+
+ this.value.put(child.getIdentifier(), child);
+ return this;
+ }
+
+ @Override
+ public LeafSetNode<T> build() {
+ return new ImmutableLeafSetNode<>(nodeIdentifier, value);
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ this.nodeIdentifier = nodeIdentifier;
+ return this;
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withValue(List<LeafSetEntryNode<T>> value) {
+ for (LeafSetEntryNode<T> leafSetEntry : value) {
+ withChild(leafSetEntry);
+ }
+
+ return this;
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withChildValue(T value) {
+ return withChild(new ImmutableLeafSetEntryNodeBuilder.ImmutableLeafSetEntryNode<>(new InstanceIdentifier.NodeWithValue(nodeIdentifier.getNodeType(), value), value));
+ }
+
+ final class ImmutableLeafSetNode<T> extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<LeafSetEntryNode<T>>> implements LeafSetNode<T> {
+
+ private final Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> mappedChildren;
+
+ ImmutableLeafSetNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> children) {
+ super(nodeIdentifier, children.values());
+ this.mappedChildren = children;
+ }
+
+ @Override
+ public Optional<LeafSetEntryNode<T>> getChild(InstanceIdentifier.NodeWithValue child) {
+ return Optional.fromNullable(mappedChildren.get(child));
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ImmutableLeafSetNode{");
+ sb.append("nodeIdentifier=").append(nodeIdentifier);
+ sb.append(", children=").append(value);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+import com.google.common.base.Preconditions;
+
+public final class ImmutableLeafSetNodeSchemaAwareBuilder<T> extends ImmutableLeafSetNodeBuilder<T> {
+
+ private final LeafListSchemaNode schema;
+
+ private ImmutableLeafSetNodeSchemaAwareBuilder(LeafListSchemaNode schema) {
+ super();
+ this.schema = schema;
+ super.withNodeIdentifier(new InstanceIdentifier.NodeIdentifier(schema.getQName()));
+ }
+
+ public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(LeafListSchemaNode schema) {
+ return new ImmutableLeafSetNodeSchemaAwareBuilder<>(schema);
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withChildValue(T value) {
+ // TODO check value type
+ return super.withChildValue(value);
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withChild(LeafSetEntryNode<T> child) {
+ Preconditions.checkArgument(schema.getQName().equals(child.getNodeType()),
+ "Incompatible node type, should be: %s, is: %s", schema.getQName(), child.getNodeType());
+ return super.withChild(child);
+ }
+
+ @Override
+ public ListNodeBuilder<T, LeafSetEntryNode<T>> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+
+public class ImmutableMapEntryNodeBuilder
+ extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> {
+
+ protected final Map<QName, InstanceIdentifier.PathArgument> childrenQNamesToPaths;
+
+ protected ImmutableMapEntryNodeBuilder() {
+ this.childrenQNamesToPaths = Maps.newLinkedHashMap();
+ }
+
+ public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> create() {
+ return new ImmutableMapEntryNodeBuilder();
+ }
+
+ // FIXME, find better solution than 2 maps (map from QName to Child ?)
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
+ for (DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> childId : value) {
+ this.childrenQNamesToPaths.put(childId.getNodeType(), childId.getIdentifier());
+ }
+ return super.withValue(value);
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withChild(DataContainerChild<?, ?> child) {
+ childrenQNamesToPaths.put(child.getNodeType(), child.getIdentifier());
+ return super.withChild(child);
+ }
+
+ public MapEntryNode build() {
+ checkKeys();
+ return new ImmutableMapEntryNode(nodeIdentifier, value);
+ }
+
+ private void checkKeys() {
+ for (QName keyQName : nodeIdentifier.getKeyValues().keySet()) {
+
+ InstanceIdentifier.PathArgument childNodePath = childrenQNamesToPaths.get(keyQName);
+ DataContainerChild<?, ?> childNode = value.get(childNodePath);
+
+ Preconditions.checkNotNull(childNode, "Key child node: %s, not present", keyQName);
+
+ Object actualValue = nodeIdentifier.getKeyValues().get(keyQName);
+ Object expectedValue = childNode.getValue();
+ Preconditions.checkArgument(expectedValue.equals(actualValue),
+ "Key child node with unexpected value, is: %s, should be: %s", actualValue, expectedValue);
+ }
+ }
+
+ static final class ImmutableMapEntryNode extends AbstractImmutableDataContainerNode<InstanceIdentifier.NodeIdentifierWithPredicates> implements MapEntryNode {
+
+ ImmutableMapEntryNode(InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier,
+ Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+ super(children, nodeIdentifier);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+
+public final class ImmutableMapEntryNodeSchemaAwareBuilder extends ImmutableMapEntryNodeBuilder{
+
+ private final ListSchemaNode schema;
+ private final DataNodeContainerValidator validator;
+
+ protected ImmutableMapEntryNodeSchemaAwareBuilder(ListSchemaNode schema) {
+ this.schema = schema;
+ this.validator = new DataNodeContainerValidator(schema);
+ }
+
+ @Override
+ public ImmutableMapEntryNodeBuilder withNodeIdentifier(InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+
+ @Override
+ public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withChild(DataContainerChild<?, ?> child) {
+ validator.validateChild(child.getIdentifier());
+ return super.withChild(child);
+ }
+
+ @Override
+ public MapEntryNode build() {
+ super.withNodeIdentifier(constructNodeIdentifier());
+ return super.build();
+ }
+
+ /**
+ * Build map entry node identifier from schema, and provided children
+ */
+ private InstanceIdentifier.NodeIdentifierWithPredicates constructNodeIdentifier() {
+ Collection<QName> keys = schema.getKeyDefinition();
+
+ // If no keys defined, add all child elements as key
+ // FIXME should be all PRESENT child nodes, not all from schema
+ if(keys.isEmpty()) {
+ keys = childrenQNamesToPaths.keySet();
+ }
+
+ Map<QName, Object> keysToValues = Maps.newHashMap();
+ for (QName key : keys) {
+ // TODO two maps ? find better solution
+ DataContainerChild<?, ?> valueForKey = value.get(childrenQNamesToPaths.get(key));
+ Preconditions.checkState(valueForKey != null, "Key value: %s cannot be empty for: %s", key, schema.getQName());
+ keysToValues.put(key, valueForKey.getValue());
+ }
+
+ return new InstanceIdentifier.NodeIdentifierWithPredicates(schema.getQName(), keysToValues);
+ }
+
+ public static ImmutableMapEntryNodeSchemaAwareBuilder create(ListSchemaNode schema) {
+ return new ImmutableMapEntryNodeSchemaAwareBuilder(schema);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
+
+public class ImmutableMapNodeBuilder
+ implements CollectionNodeBuilder<MapEntryNode, MapNode> {
+
+ protected Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
+ protected InstanceIdentifier.NodeIdentifier nodeIdentifier;
+
+ public static CollectionNodeBuilder<MapEntryNode, MapNode> create() {
+ return new ImmutableMapNodeBuilder();
+ }
+
+ public CollectionNodeBuilder<MapEntryNode, MapNode> withChild(MapEntryNode child) {
+ if(this.value == null) {
+ this.value = Maps.newLinkedHashMap();
+ }
+
+ this.value.put(child.getIdentifier(), child);
+ return this;
+ }
+
+ @Override
+ public CollectionNodeBuilder<MapEntryNode, MapNode> withValue(List<MapEntryNode> value) {
+ // TODO replace or putAll ?
+ for (MapEntryNode mapEntryNode : value) {
+ withChild(mapEntryNode);
+ }
+
+ return this;
+ }
+
+ public CollectionNodeBuilder<MapEntryNode, MapNode> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ this.nodeIdentifier = nodeIdentifier;
+ return this;
+ }
+
+ @Override
+ public MapNode build() {
+ return new ImmutableMapNode(nodeIdentifier, value);
+ }
+
+ static final class ImmutableMapNode extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<MapEntryNode>> implements MapNode {
+
+ private final Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mappedChildren;
+
+ ImmutableMapNode(InstanceIdentifier.NodeIdentifier nodeIdentifier,
+ Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> children) {
+ super(nodeIdentifier, children.values());
+ this.mappedChildren = children;
+ }
+
+ @Override
+ public Optional<MapEntryNode> getChild(InstanceIdentifier.NodeIdentifierWithPredicates child) {
+ return Optional.fromNullable(mappedChildren.get(child));
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ImmutableMapNode{");
+ sb.append("nodeIdentifier=").append(nodeIdentifier);
+ sb.append(", children=").append(mappedChildren);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import com.google.common.base.Preconditions;
+
+public class ImmutableMapNodeSchemaAwareBuilder extends ImmutableMapNodeBuilder {
+
+ private final ListSchemaNode schema;
+
+ protected ImmutableMapNodeSchemaAwareBuilder(ListSchemaNode schema) {
+ super();
+ this.schema = schema;
+ super.withNodeIdentifier(new InstanceIdentifier.NodeIdentifier(schema.getQName()));
+ }
+
+ public static CollectionNodeBuilder<MapEntryNode, MapNode> create(ListSchemaNode schema) {
+ return new ImmutableMapNodeSchemaAwareBuilder(schema);
+ }
+
+ @Override
+ public CollectionNodeBuilder<MapEntryNode, MapNode> withChild(MapEntryNode child) {
+ Preconditions.checkArgument(schema.getQName().equals(child.getNodeType()),
+ "Incompatible node type, should be: %s, is: %s", schema.getQName(), child.getNodeType());
+ return super.withChild(child);
+ }
+
+ @Override
+ public CollectionNodeBuilder<MapEntryNode, MapNode> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+ throw new UnsupportedOperationException("Node identifier created from schema");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.builder.impl.valid;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * General validator for container like statements, e.g. container, list-entry, choice, augment
+ */
+public class DataNodeContainerValidator {
+
+ private final DataNodeContainer schema;
+ private Collection<AugmentationSchema> augmentations;
+
+ public DataNodeContainerValidator(DataNodeContainer schema) {
+ this.schema = schema;
+ augmentations = schema instanceof AugmentationTarget ? ((AugmentationTarget) schema)
+ .getAvailableAugmentations() : Collections.<AugmentationSchema> emptyList();
+ }
+
+ private boolean isKnownChild(InstanceIdentifier.PathArgument child) {
+ // check augmentation by comparing all child nodes
+ if(child instanceof InstanceIdentifier.AugmentationIdentifier) {
+ for (AugmentationSchema augmentationSchema : augmentations) {
+ if(equalAugments(augmentationSchema, (InstanceIdentifier.AugmentationIdentifier) child)) {
+ return true;
+ }
+ }
+ // check regular child node
+ } else {
+ return schema.getDataChildByName(child.getNodeType()) != null;
+ }
+
+ return false;
+ }
+
+ private Optional<AugmentationSchema> isAugmentChild(InstanceIdentifier.PathArgument child) {
+ for (AugmentationSchema augmentationSchema : augmentations) {
+ if(ImmutableAugmentationNodeSchemaAwareBuilder.getChildQNames(augmentationSchema).contains(child.getNodeType())) {
+ return Optional.of(augmentationSchema);
+ }
+ }
+
+ return Optional.absent();
+ }
+
+ // FIXME, need to compare Set of QNames(AugmentationIdentifier) with Set of DataSchemaNodes(AugmentationSchema)
+ // throw away set is created just to compare
+ // Or if augmentationSchemaNode had a QName, we would just compare a QName
+ private boolean equalAugments(AugmentationSchema augmentationSchema, InstanceIdentifier.AugmentationIdentifier identifier) {
+ return identifier.getPossibleChildNames().equals(ImmutableAugmentationNodeSchemaAwareBuilder.getChildQNames(augmentationSchema));
+ }
+
+ public void validateChild(InstanceIdentifier.PathArgument child) {
+ Preconditions.checkArgument(isKnownChild(child), "Unknown child node: %s, does not belong to: %s", child.getNodeType(), schema);
+
+ // FIXME make a cache for augmentation child sets in constructor
+ Optional<AugmentationSchema> augmentChild = isAugmentChild(child);
+ Preconditions.checkArgument(
+ augmentChild.isPresent() == false,
+ "Illegal node type, child nodes from augmentation are not permitted as direct children, must be wrapped in augmentation node, "
+ + "node: %s, from augmentation: %s, in parent: %s", child.getNodeType(), augmentChild, schema);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.nodes;
+
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+
+import com.google.common.base.Optional;
+
+public abstract class AbstractImmutableDataContainerNode<K extends InstanceIdentifier.PathArgument>
+ extends AbstractImmutableNormalizedNode<K, Iterable<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>>
+ implements DataContainerNode<K> {
+
+ protected Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children;
+
+ public AbstractImmutableDataContainerNode(Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children, K nodeIdentifier) {
+ super(nodeIdentifier, children.values());
+ this.children = children;
+ }
+
+ @Override
+ public Optional<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> getChild(InstanceIdentifier.PathArgument child) {
+ return Optional.<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>fromNullable(children.get(child));
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("ImmutableContainerNode{");
+ sb.append("nodeIdentifier=").append(nodeIdentifier);
+ sb.append(", children=").append(children);
+ sb.append('}');
+ return sb.toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema.nodes;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractImmutableNormalizedNode<K extends InstanceIdentifier.PathArgument,V>
+ implements NormalizedNode<K, V>, Immutable {
+
+ protected final K nodeIdentifier;
+ protected V value;
+
+ protected AbstractImmutableNormalizedNode(K nodeIdentifier, V value) {
+ this.nodeIdentifier = Preconditions.checkNotNull(nodeIdentifier, "nodeIdentifier");
+ this.value = Preconditions.checkNotNull(value, "value");
+ }
+
+ @Override
+ public QName getNodeType() {
+ return getIdentifier().getNodeType();
+ }
+
+ @Override
+ public K getIdentifier() {
+ return nodeIdentifier;
+ }
+
+ @Override
+ public CompositeNode getParent() {
+ throw new UnsupportedOperationException("Deprecated");
+ }
+
+ @Override
+ public QName getKey() {
+ return getNodeType();
+ }
+
+ @Override
+ public V getValue() {
+ return value;
+ }
+
+ @Override
+ public V setValue(V value) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AbstractImmutableNormalizedNode)) return false;
+
+ AbstractImmutableNormalizedNode that = (AbstractImmutableNormalizedNode) o;
+
+ if (!nodeIdentifier.equals(that.nodeIdentifier)) return false;
+ if (!value.equals(that.value)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = nodeIdentifier.hashCode();
+ result = 31 * result + value.hashCode();
+ return result;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.data.impl.schema;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.*;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class NormalizedDataBuilderTest {
+
+ private ContainerSchemaNode containerNode;
+ private SchemaContext schema;
+
+ SchemaContext parseTestSchema() {
+ YangParserImpl yangParserImpl = new YangParserImpl();
+ Set<Module> modules = yangParserImpl.parseYangModelsFromStreams(getTestYangs());
+ return yangParserImpl.resolveSchemaContext(modules);
+ }
+
+ List<InputStream> getTestYangs() {
+
+ return Lists.newArrayList(Collections2.transform(Lists.newArrayList("test.yang"),
+ new Function<String, InputStream>() {
+ @Override
+ public InputStream apply(String input) {
+ InputStream resourceAsStream = getClass().getResourceAsStream(input);
+ Preconditions.checkNotNull(resourceAsStream, "File %s was null", resourceAsStream);
+ return resourceAsStream;
+ }
+ }));
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ schema = parseTestSchema();
+ containerNode = (ContainerSchemaNode) getSchemaNode(schema, "test", "container");
+ }
+
+ @Test
+ public void testSchemaUnaware() throws Exception {
+ // Container
+ DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders.containerBuilder().withNodeIdentifier(
+ getNodeIdentifier("container"));
+
+ // leaf
+ LeafNode<String> leafChild = Builders.<String>leafBuilder()
+ .withNodeIdentifier(getNodeIdentifier("leaf")).withValue("String").build();
+ builder.withChild(leafChild);
+
+ // leafList
+ LeafSetNode<Integer> leafList = Builders.<Integer>leafSetBuilder()
+ .withNodeIdentifier(getNodeIdentifier("leaf"))
+ .withChildValue(1)
+ .withChild(Builders.<Integer>leafSetEntryBuilder().withNodeIdentifier(getNodeWithValueIdentifier("leaf", 3)).withValue(3).build())
+ .build();
+ builder.withChild(leafList);
+
+ // list
+ MapEntryNode listChild1 = Builders.mapEntryBuilder()
+ .withChild(
+ Builders.<Integer>leafBuilder()
+ .withNodeIdentifier(getNodeIdentifier("uint32InList")).withValue(1).build())
+ .withChild(
+ Builders.containerBuilder().withNodeIdentifier(
+ getNodeIdentifier("containerInList"))
+ .build())
+ .withNodeIdentifier(
+ new InstanceIdentifier.NodeIdentifierWithPredicates(getNodeIdentifier("list").getNodeType(),
+ Collections.singletonMap(getNodeIdentifier("uint32InList").getNodeType(), (Object) 1)))
+ .build();
+
+ MapNode list = Builders.mapBuilder().withChild(listChild1).withNodeIdentifier(getNodeIdentifier("list")).build();
+ builder.withChild(list);
+
+ AugmentationNode augmentation = Builders.augmentationBuilder()
+ .withNodeIdentifier(new InstanceIdentifier.AugmentationIdentifier(null, Sets.newHashSet(getQName("augmentUint32"))))
+ .withChild(
+ Builders.<Integer>leafBuilder().withNodeIdentifier(getNodeIdentifier("augmentUint32")).withValue(11).build())
+ .build();
+
+ builder.withChild(augmentation);
+
+ // This works without schema (adding child from augment as a direct child)
+ builder.withChild(Builders.<Integer>leafBuilder().withNodeIdentifier(getNodeIdentifier("augmentUint32")).withValue(11).build());
+
+ System.out.println(builder.build());
+ }
+
+ @Test
+ public void testSchemaAware() throws Exception {
+ DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders.containerBuilder(containerNode);
+
+ LeafSchemaNode schemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "uint32");
+ LeafNode<String> leafChild = Builders.<String>leafBuilder(schemaNode)
+ .withValue("String").build();
+ builder.withChild(leafChild);
+
+ LeafListSchemaNode leafListSchemaNode = (LeafListSchemaNode) getSchemaNode(schema, "test", "leafList");
+ LeafSetNode<Integer> leafList = Builders.<Integer>leafSetBuilder(leafListSchemaNode)
+ .withChildValue(1)
+ .withChild(Builders.<Integer>leafSetEntryBuilder(leafListSchemaNode).withValue(3).build())
+ .build();
+ builder.withChild(leafList);
+
+ ListSchemaNode listSchema = (ListSchemaNode) getSchemaNode(schema, "test", "list");
+ LeafSchemaNode uint32InListSchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "uint32InList");
+ ContainerSchemaNode containerInListSchemaNode = (ContainerSchemaNode) getSchemaNode(schema, "test", "containerInList");
+
+ MapEntryNode listChild1 = Builders.mapEntryBuilder(listSchema)
+ .withChild(
+ Builders.<Integer>leafBuilder(uint32InListSchemaNode).withValue(1).build())
+ .withChild(
+ Builders.containerBuilder(containerInListSchemaNode).build())
+ .build();
+
+ MapNode list = ImmutableMapNodeSchemaAwareBuilder.create(listSchema).withChild(listChild1).build();
+ builder.withChild(list);
+
+ LeafSchemaNode augmentUint32SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentUint32");
+ AugmentationSchema augmentationSchema = getAugmentationSchemaForChild(containerNode, augmentUint32SchemaNode.getQName());
+
+ AugmentationNode augmentation = Builders.augmentationBuilder(augmentationSchema).withChild(
+ Builders.<Integer>leafBuilder(augmentUint32SchemaNode).withValue(11).build())
+ .build();
+
+ builder.withChild(augmentation);
+
+ // This should fail with schema, since the leaf comes from augmentation
+// builder.withChild(ImmutableLeafNodeSchemaAwareBuilder.<Integer>get(augmentUint32SchemaNode).withValue(11).build());
+
+ LeafSchemaNode augumentString1SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentString1");
+ LeafSchemaNode augumentString2SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentString2");
+
+ ChoiceNode choice1SchemaNode = (ChoiceNode) getSchemaNode(schema, "test", "choice");
+ org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode choice = ImmutableChoiceNodeSchemaAwareBuilder.create(choice1SchemaNode)
+ .withChild(Builders.<String>leafBuilder(augumentString1SchemaNode).withValue("case1")
+ .build())
+ // This should fail, since child node belongs to different case
+// .withChild(Builders.<String>leafBuilder(augumentString2SchemaNode).withValue("case2")
+// .build())
+ .build();
+
+; builder.withChild(choice);
+
+ // This should fail, child from case
+// builder.withChild(Builders.<String>leafBuilder(augumentString1SchemaNode).withValue("case1")
+// .build());
+
+ System.out.println(builder.build());
+ }
+
+ private AugmentationSchema getAugmentationSchemaForChild(ContainerSchemaNode containerNode, QName qName) {
+ for (AugmentationSchema augmentationSchema : containerNode.getAvailableAugmentations()) {
+ if(augmentationSchema.getDataChildByName(qName) != null) {
+ return augmentationSchema;
+ }
+ }
+ throw new IllegalStateException("Unable to find child augmentation in " + containerNode);
+ }
+
+ private InstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(String localName, Object value) {
+ return new InstanceIdentifier.NodeWithValue(getQName(localName), value);
+ }
+
+ private QName getQName(String localName) {
+ String namespace = "namespace";
+ return new QName(URI.create(namespace), localName);
+ }
+
+ private InstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(QName q, Object value) {
+ return new InstanceIdentifier.NodeWithValue(q, value);
+ }
+
+ private InstanceIdentifier.NodeIdentifier getNodeIdentifier(String localName) {
+ return new InstanceIdentifier.NodeIdentifier(getQName(localName));
+ }
+
+ private InstanceIdentifier.NodeIdentifier getNodeIdentifier(QName q) {
+ return new InstanceIdentifier.NodeIdentifier(q);
+ }
+
+ private Document loadDocument(String xmlPath) throws Exception {
+ InputStream resourceAsStream = getClass().getResourceAsStream(xmlPath);
+
+ Document currentConfigElement = readXmlToDocument(resourceAsStream);
+ Preconditions.checkNotNull(currentConfigElement);
+ return currentConfigElement;
+ }
+
+ private static final DocumentBuilderFactory BUILDERFACTORY;
+
+ static {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setCoalescing(true);
+ factory.setIgnoringElementContentWhitespace(true);
+ factory.setIgnoringComments(true);
+ BUILDERFACTORY = factory;
+ }
+
+ private Document readXmlToDocument(InputStream xmlContent) throws IOException, SAXException {
+ DocumentBuilder dBuilder;
+ try {
+ dBuilder = BUILDERFACTORY.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException("Failed to parse XML document", e);
+ }
+ Document doc = dBuilder.parse(xmlContent);
+
+ doc.getDocumentElement().normalize();
+ return doc;
+ }
+
+ public static String toString(Element xml) {
+ try {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ StreamResult result = new StreamResult(new StringWriter());
+ DOMSource source = new DOMSource(xml);
+ transformer.transform(source, result);
+
+ return result.getWriter().toString();
+ } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
+ throw new RuntimeException("Unable to serialize xml element " + xml, e);
+ }
+ }
+
+ DataSchemaNode getSchemaNode(SchemaContext context, String moduleName, String childNodeName) {
+ for (Module module : context.getModules()) {
+ if (module.getName().equals(moduleName)) {
+ DataSchemaNode found = findChildNode(module.getChildNodes(), childNodeName);
+ Preconditions.checkState(found!=null, "Unable to find %s", childNodeName);
+ return found;
+ }
+ }
+ throw new IllegalStateException("Unable to find child node " + childNodeName);
+ }
+
+ DataSchemaNode findChildNode(Set<DataSchemaNode> children, String name) {
+ List<DataNodeContainer> containers = Lists.newArrayList();
+
+ for (DataSchemaNode dataSchemaNode : children) {
+ if (dataSchemaNode.getQName().getLocalName().equals(name))
+ return dataSchemaNode;
+ if(dataSchemaNode instanceof DataNodeContainer) {
+ containers.add((DataNodeContainer) dataSchemaNode);
+ } else if(dataSchemaNode instanceof ChoiceNode) {
+ containers.addAll(((ChoiceNode) dataSchemaNode).getCases());
+ }
+ }
+
+ for (DataNodeContainer container : containers) {
+ DataSchemaNode retVal = findChildNode(container.getChildNodes(), name);
+ if(retVal != null) {
+ return retVal;
+ }
+ }
+
+ return null;
+ }
+}
--- /dev/null
+<container xmlns="urn:opendaylight:params:xml:ns:yang:controller:test">
+ <boolean>true</boolean>
+ <innerContainer>
+ <uint16>44</uint16>
+ </innerContainer>
+ <leafList>a</leafList>
+ <leafList>b</leafList>
+
+ <list>
+ <uint32InList>1</uint32InList>
+ <containerInList>
+ <uint32>32</uint32>
+ <uint16>16</uint16>
+ </containerInList>
+ </list>
+ <list>
+ <uint32InList>2</uint32InList>
+ <containerInList>
+ <uint32>32</uint32>
+ <uint16>16</uint16>
+ </containerInList>
+ </list>
+ <list>
+ <uint32InList>3</uint32InList>
+ </list>
+
+ <augmentUint32>999</augmentUint32>
+
+ <augmentString1>choice1Case1</augmentString1>
+ <augmentInt1>41</augmentInt1>
+
+ <augmentContainer>
+ <augmentStringInaugmentContainer>choice2Case1</augmentStringInaugmentContainer>
+ </augmentContainer>
+
+
+</container>
\ No newline at end of file
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module test {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:test";
+ prefix "test";
+
+ organization "Cisco Systems, Inc.";
+
+ revision "2013-2-21" {
+ description
+ "Initial revision";
+ }
+
+ grouping listGroup {
+ list list {
+ key "uint32InList";
+
+ leaf uint32InList {
+ type uint32;
+ }
+
+ container containerInList{
+ leaf uint32 {
+ type uint32;
+ }
+ leaf uint16 {
+ type uint16;
+ }
+ }
+ }
+ }
+
+ grouping innerContainerGrouping {
+ container innerContainer {
+ leaf uint16 {
+ type uint16;
+ }
+
+ container innerInnerContainer {
+
+ leaf uint16 {
+ type uint16;
+ }
+
+ leaf uint32 {
+ type uint32;
+ }
+ }
+ }
+ }
+
+ container container {
+ leaf uint32 {
+ type uint32;
+ }
+
+ leaf decimal64 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+
+ leaf boolean {
+ type boolean;
+ }
+
+ leaf binary {
+ type binary;
+ }
+
+ leaf string {
+ type string;
+ }
+
+ uses listGroup;
+ uses innerContainerGrouping;
+
+ choice choice{}
+ choice choice2{}
+
+ leaf-list leafList {
+ type string;
+ }
+
+ leaf identityRef {
+ type identityref {
+ base test-identity;
+ }
+ }
+
+ /* TODO test modification with empty type
+ leaf empty {
+ type empty;
+ }
+ */
+ }
+
+ augment "/container/" {
+ leaf augmentUint32 {
+ type uint32;
+ }
+ }
+
+ augment "/container/choice/" {
+ case test-identity-augment {
+ when "/container/identityRef = 'test-identity'";
+ leaf augmentString1 {
+ type string;
+ }
+
+ leaf augmentInt1 {
+ type uint32;
+ }
+ }
+ case test-identity-augment2 {
+ when "/container/identityRef = 'test-identity2'";
+ leaf augmentString2 {
+ type string;
+ }
+
+ leaf augmentInt2 {
+ type uint32;
+ }
+ }
+ }
+
+ augment "/container/choice2/" {
+ case test-identity-augment {
+ when "/container/identityRef = 'test-identity'";
+ container augmentContainer {
+ leaf augmentStringInaugmentContainer {
+ type string;
+ }
+ }
+ }
+ case test-identity-augment2 {
+ when "/container/identityRef = 'test-identity2'";
+ list augmentedList {
+ leaf augmentStringInaugmentList {
+ type string;
+ }
+ }
+ }
+ }
+
+
+ identity test-identity {}
+ identity test-identity2 {
+ base test-identity;
+ }
+
+}
\ No newline at end of file
<version>1.5</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>binding-java-api-generator</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<properties>
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
+import java.util.List;
import java.util.Properties;
import org.apache.maven.it.VerificationException;
fail("Verification exception should have been thrown");
}
+ @Test
+ public void testNamingConflict() throws Exception {
+ Verifier v = setUp("NamingConflict/", false);
+ v.verifyErrorFreeLog();
+ String baseDir = v.getBasedir();
+ String fileName = v.getLogFileName();
+ List<String> lines = v.loadFile(baseDir, fileName, false);
+ for (String s : lines) {
+ if (s.contains("conflict")) {
+ System.err.println(s);
+ }
+ }
+ v.verifyTextInLog("[WARNING] Naming conflict for type 'org.opendaylight.yang.gen.v1.urn.yang.test.rev140303.NetworkTopologyRef': file with same name already exists and will not be generated.");
+ }
+
static void verifyCorrectLog(Verifier v) throws VerificationException {
v.verifyErrorFreeLog();
v.verifyTextInLog("[INFO] yang-to-sources: YANG files parsed from");
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!-- Copyright (c) 2013 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.opendaylight.yangtools</groupId>
+ <version>0.5-SNAPSHOT</version>
+ <artifactId>test</artifactId>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${it-project.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <inspectDependencies>false</inspectDependencies>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ target/generated-sources
+ </outputBaseDir>
+ </generator>
+ </codeGenerators>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${it-project.version}</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+module test {\r
+ namespace "urn:yang:test";\r
+ prefix "t";\r
+\r
+ revision 2014-03-03 {\r
+ }\r
+\r
+ typedef network-topology-ref {\r
+ type instance-identifier;\r
+ }\r
+\r
+ grouping network-topology-ref {\r
+ leaf network-topology-ref {\r
+ type string;\r
+ }\r
+ }\r
+\r
+}\r
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <version>2.4</version>
</dependency>
<dependency>
*/
package org.opendaylight.yangtools.yang2sources.plugin;
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
class YangToSourcesProcessor {
static final String LOG_PREFIX = "yang-to-sources:";
projectYangModules = new HashSet<>();
for (InputStream inProject : yangsInProject) {
- projectYangModules.add(allYangModules.get(inProject));
+ Module module = checkNotNull(allYangModules.get(inProject), "Cannot find module by %s", inProject);
+ projectYangModules.add(module);
}
} finally {
<groupId>${project.groupId}</groupId>
<artifactId>yang-common</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
</dependencies>
</project>
*/
package org.opendaylight.yangtools.yang.model.api;
-import java.net.URI;
-import java.util.Date;
import java.util.List;
import java.util.Set;
</code>
*/
-public interface Module extends DataNodeContainer, SourceStreamAware {
+public interface Module extends DataNodeContainer, SourceStreamAware, ModuleIdentifier {
- /**
- * Returns the namespace of the module which is specified as argument of
- * YANG {@link Module <b><font color="#00FF00">namespace</font></b>}
- * keyword.
- *
- * @return URI format of the namespace of the module
- */
- URI getNamespace();
-
- /**
- * Returns the name of the module which is specified as argument of YANG
- * {@link Module <b><font color="#FF0000">module</font></b>} keyword
- *
- * @return string with the name of the module
- */
- String getName();
-
- /**
- * Returns the revision date for the module.
- *
- * @return date of the module revision which is specified as argument of
- * YANG {@link Module <b><font color="#339900">revison</font></b>}
- * keyword
- */
- Date getRevision();
/**
* Returns the prefix of the module
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.model.api;
+
+import java.net.URI;
+import java.util.Date;
+
+
+public interface ModuleIdentifier {
+
+ /**
+ * Returns the namespace of the module which is specified as argument of
+ * YANG {@link Module <b><font color="#00FF00">namespace</font></b>}
+ * keyword.
+ *
+ * @return URI format of the namespace of the module
+ */
+ URI getNamespace();
+
+ /**
+ * Returns the name of the module which is specified as argument of YANG
+ * {@link Module <b><font color="#FF0000">module</font></b>} keyword
+ *
+ * @return string with the name of the module
+ */
+ String getName();
+
+ /**
+ * Returns the revision date for the module.
+ *
+ * @return date of the module revision which is specified as argument of
+ * YANG {@link Module <b><font color="#339900">revison</font></b>}
+ * keyword
+ */
+ Date getRevision();
+}
*/
package org.opendaylight.yangtools.yang.model.api;
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.common.QName;
+
import java.net.URI;
import java.util.Date;
import java.util.Set;
-import org.opendaylight.yangtools.yang.common.QName;
-
/**
* The interface contains the methods for manipulating all the top level context
* data (data from all red modules) like YANG notifications, extensions,
*/
Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision);
+
+ /**
+ * Get yang source code represented as string for matching
+ * {@link org.opendaylight.yangtools.yang.model.api.ModuleIdentifier}.
+ * @param moduleIdentifier must provide a non-null
+ * {@link org.opendaylight.yangtools.yang.model.api.ModuleIdentifier#getName()},
+ * other methods might return null.
+ * @return value iif matching module is found in schema context.
+ */
+ Optional<String> getModuleSource(ModuleIdentifier moduleIdentifier);
+
+ /**
+ * Get all module and submodule identifiers.
+ */
+ Set<ModuleIdentifier> getAllModuleIdentifiers();
+
}
package org.opendaylight.yangtools.yang.model.api;
public interface SchemaContextListener extends SchemaServiceListener {
-
+ @Override
+ void onGlobalContextUpdated(SchemaContext context);
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.model.api;
+
+public interface SchemaContextProvider {
+
+ SchemaContext getSchemaContext();
+
+}
*/
@Deprecated
public interface SchemaServiceListener extends EventListener {
- // FIXME: move declaration to SchemaContextListener
void onGlobalContextUpdated(SchemaContext context);
}
*/
package org.opendaylight.yangtools.yang.model.api;
+// TODO: merge into Module, makes no sense as standalone interface
public interface SourceStreamAware {
+ /**
+ * Get descriptive source path (usually file path) from which this module was parsed.
+ */
String getModuleSourcePath();
}
*/
package org.opendaylight.yangtools.yang.model.parser.api;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition;
+
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition;
-
/**
* Yang Model Parser interface is designed for parsing yang models and convert
* the information to Data Schema Tree.
*
*/
+// refactor methods returning input streams, after introducing
public interface YangModelParser {
/**
* yang streams to parse
* @return Map of Yang Modules
*/
+ //TODO: when working with input streams do not swallow IOException, it should be propagated without having to wrap it in a runtime exception
+ //FIXME: it is not defined in which state are the returning streams.
Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams);
/**
<groupId>${project.groupId}</groupId>
<artifactId>concepts</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
</dependencies>
<build>
instance.setRevision(moduleBuilder.getRevision());
}
- instance.setTargetPath(targetNodeSchemaPath);
+ if (parent instanceof UsesNodeBuilder) {
+ ModuleBuilder mb = ParserUtils.getParentModule(this);
+ List<QName> newPath = new ArrayList<>();
+ List<QName> parsedPath = targetPath.getPath();
+ for (QName name : parsedPath) {
+ newPath.add(new QName(mb.getNamespace(), mb.getRevision(), name.getPrefix(), name.getLocalName()));
+ }
+ instance.setTargetPath(new SchemaPath(newPath, false));
+ } else {
+ instance.setTargetPath(targetNodeSchemaPath);
+ }
RevisionAwareXPath whenStmt;
if (whenCondition == null) {
*/
package org.opendaylight.yangtools.yang.parser.builder.impl;
-import java.net.URI;
-import java.util.*;
-
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.opendaylight.yangtools.yang.parser.builder.api.*;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
+import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.yangtools.yang.parser.util.Comparators;
import org.opendaylight.yangtools.yang.parser.util.ModuleImportImpl;
import org.opendaylight.yangtools.yang.parser.util.RefineHolder;
import org.opendaylight.yangtools.yang.parser.util.YangParseException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
/**
* Builder of Module object. If this module is dependent on external
* module/modules, these dependencies must be resolved before module is built,
private final List<ListSchemaNodeBuilder> allLists = new ArrayList<ListSchemaNodeBuilder>();
+ private String source;
+
public ModuleBuilder(final String name, final String sourcePath) {
this(name, false, sourcePath);
}
Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
instance.setUnknownSchemaNodes(unknownNodes);
+ instance.setSource(source);
+
return instance;
}
return "module " + name;
}
- private static final class ModuleImpl implements Module {
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public static final class ModuleImpl implements Module {
private URI namespace;
private final String name;
private final String sourcePath;
private final List<ExtensionDefinition> extensionNodes = new ArrayList<>();
private final Set<IdentitySchemaNode> identities = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
+ private String source;
private ModuleImpl(String name, String sourcePath) {
this.name = name;
return getChildNode(childNodes, name);
}
+ void setSource(String source){
+ this.source = source;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ // FIXME: prefix should not be taken into consideration, perhaps namespace too
@Override
public int hashCode() {
final int prime = 31;
return true;
}
+
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.parser.builder.impl;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+
+import java.net.URI;
+import java.util.Date;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * ModuleIdentifier that can be used for indexing/searching by name.
+ * Name is only non-null attribute.
+ * Equality check on namespace and revision is only triggered if they are non-null
+ */
+public class ModuleIdentifierImpl implements ModuleIdentifier {
+ private final String name;
+ private final Optional<URI> namespace;
+ private final Optional<Date> revision;
+
+ public ModuleIdentifierImpl(String name, Optional<URI> namespace, Optional<Date> revision) {
+ this.name = checkNotNull(name);
+ this.namespace = checkNotNull(namespace);
+ this.revision = checkNotNull(revision);
+ }
+
+ @Override
+ public Date getRevision() {
+ return revision.orNull();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public URI getNamespace() {
+ return namespace.orNull();
+ }
+
+ @Override
+ public String toString() {
+ return "ModuleIdentifierImpl{" +
+ "name='" + name + '\'' +
+ ", namespace=" + namespace +
+ ", revision=" + revision +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || (o instanceof ModuleIdentifier == false)) {
+ return false;
+ }
+
+ ModuleIdentifier that = (ModuleIdentifier) o;
+
+ if (!name.equals(that.getName())) {
+ return false;
+ }
+ // only fail if this namespace is non-null
+ if (namespace.isPresent() && namespace.get().equals(that.getNamespace()) == false) {
+ return false;
+ }
+ // only fail if this revision is non-null
+ if (revision.isPresent() && revision.get().equals(that.getRevision()) == false) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
*/
package org.opendaylight.yangtools.yang.parser.impl;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeMap;
-
+import com.google.common.base.Optional;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
final class SchemaContextImpl implements SchemaContext {
private final Set<Module> modules;
+ private final Map<ModuleIdentifier, String> identifiersToSources;
- SchemaContextImpl(final Set<Module> modules) {
+ SchemaContextImpl(final Set<Module> modules, Map<ModuleIdentifier, String> identifiersToSources) {
this.modules = modules;
+ this.identifiersToSources = identifiersToSources;
}
@Override
return Collections.emptySet();
}
+ //FIXME: should work for submodules too
+ @Override
+ public Set<ModuleIdentifier> getAllModuleIdentifiers() {
+ return identifiersToSources.keySet();
+ }
+
+ @Override
+ public Optional<String> getModuleSource(ModuleIdentifier moduleIdentifier) {
+ String maybeSource = identifiersToSources.get(moduleIdentifier);
+ return Optional.fromNullable(maybeSource);
+ }
}
*/
package org.opendaylight.yangtools.yang.parser.impl;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveType;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnion;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnionWithContext;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeWithContext;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.*;
-
+import com.google.common.base.Preconditions;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.apache.commons.io.IOUtils;
import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.*;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder.ModuleImpl;
+import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
import org.opendaylight.yangtools.yang.parser.util.Comparators;
import org.opendaylight.yangtools.yang.parser.util.GroupingSort;
import org.opendaylight.yangtools.yang.parser.util.GroupingUtils;
import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
-import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
+import org.opendaylight.yangtools.yang.parser.util.NamedByteArrayInputStream;
+import org.opendaylight.yangtools.yang.parser.util.NamedInputStream;
import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
import org.opendaylight.yangtools.yang.parser.util.YangParseException;
import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.fillAugmentTarget;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findBaseIdentity;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findBaseIdentityFromContext;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromBuilders;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromContext;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findSchemaNode;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findSchemaNodeInModule;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.processAugmentation;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.setNodeAddedByUses;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapChildNode;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapChildNodes;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapGroupings;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapTypedefs;
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapUnknownNodes;
+import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveType;
+import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnion;
+import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnionWithContext;
+import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeWithContext;
public final class YangParserImpl implements YangModelParser {
final String yangFileName = yangFile.getName();
final String[] fileList = directory.list();
- Preconditions.checkNotNull(fileList, directory + " not found");
+ checkNotNull(fileList, directory + " not found");
FileInputStream yangFileStream = null;
LinkedHashMap<InputStream, File> streamToFileMap = new LinkedHashMap<>();
return result;
}
+ // TODO: fix exception handling
@Override
public Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams) {
if (yangModelStreams == null) {
return Collections.emptyMap();
}
- Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>();
- Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams, builderToStreamMap,
+
+ // copy input streams so that they can be read more than once
+ Map<InputStream/*array backed copy */, InputStream/* original for returning*/> arrayBackedToOriginalInputStreams = new HashMap<>();
+ for (final InputStream originalIS : yangModelStreams) {
+ InputStream arrayBackedIs;
+ try {
+ arrayBackedIs = NamedByteArrayInputStream.create(originalIS);
+ } catch (IOException e) {
+ // FIXME: throw IOException here
+ throw new IllegalStateException("Can not get yang as String from " + originalIS, e);
+ }
+ arrayBackedToOriginalInputStreams.put(arrayBackedIs, originalIS);
+ }
+
+ // it would be better if all code from here used string representation of yang sources instead of input streams
+ Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>(); // FIXME: do not modify input parameter
+ Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(new ArrayList<>(arrayBackedToOriginalInputStreams.keySet()),
+ builderToStreamMap,
null);
- Map<InputStream, Module> result = new LinkedHashMap<>();
+
+
+ // TODO move deeper
+ for(TreeMap<Date, ModuleBuilder> value : modules.values()) {
+ Collection<ModuleBuilder> values = value.values();
+ for(ModuleBuilder builder: values) {
+ InputStream is = builderToStreamMap.get(builder);
+ try {
+ is.reset();
+ } catch (IOException e) {
+ // this cannot happen because it is ByteArrayInputStream
+ throw new IllegalStateException("Possible error in code", e);
+ }
+ String content;
+ try {
+ content = IOUtils.toString(is);
+ } catch (IOException e) {
+ // this cannot happen because it is ByteArrayInputStream
+ throw new IllegalStateException("Possible error in code", e);
+ }
+ builder.setSource(content);
+ }
+ }
+
+
Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
+
Set<ModuleBuilder> keyset = builderToModuleMap.keySet();
List<ModuleBuilder> sorted = ModuleDependencySort.sort(keyset.toArray(new ModuleBuilder[keyset.size()]));
+ Map<InputStream, Module> result = new LinkedHashMap<>();
for (ModuleBuilder key : sorted) {
- result.put(builderToStreamMap.get(key), builderToModuleMap.get(key));
+ Module value = checkNotNull(builderToModuleMap.get(key), "Cannot get module for %s", key);
+ InputStream arrayBackedIS = checkNotNull(builderToStreamMap.get(key), "Cannot get is for %s", key);
+ InputStream originalIS = arrayBackedToOriginalInputStreams.get(arrayBackedIS);
+ result.put(originalIS, value);
}
return result;
}
@Override
public SchemaContext resolveSchemaContext(final Set<Module> modules) {
- return new SchemaContextImpl(modules);
+ // after merging parse method with this one, add support for getting submodule sources.
+ Map<ModuleIdentifier, String> identifiersToSources = new HashMap<>();
+ for(Module module: modules) {
+ ModuleImpl moduleImpl = (ModuleImpl) module;
+ identifiersToSources.put(module, moduleImpl.getSource());
+ }
+ return new SchemaContextImpl(modules, identifiersToSources);
}
+ // FIXME: why a list is required?
+ // FIXME: streamToBuilderMap is output of this method, not input
private Map<InputStream, ModuleBuilder> parseModuleBuilders(List<InputStream> inputStreams,
Map<ModuleBuilder, InputStream> streamToBuilderMap) {
Map<InputStream, ModuleBuilder> modules = parseBuilders(inputStreams, streamToBuilderMap);
return result;
}
+ // FIXME: why a list is required?
+ // FIXME: streamToBuilderMap is output of this method, not input
private Map<InputStream, ModuleBuilder> parseBuilders(List<InputStream> inputStreams,
Map<ModuleBuilder, InputStream> streamToBuilderMap) {
final ParseTreeWalker walker = new ParseTreeWalker();
for (Map.Entry<InputStream, ParseTree> entry : trees.entrySet()) {
InputStream is = entry.getKey();
String path = null;
- if (is instanceof NamedFileInputStream) {
- NamedFileInputStream nis = (NamedFileInputStream)is;
- path = nis.getFileDestination();
+ if (is instanceof NamedInputStream) {
+ path = is.toString();
}
yangModelParser = new YangParserListenerImpl(path);
walker.walk(yangModelParser, entry.getValue());
ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder();
// We expect the order of trees and streams has to be the same
+ // FIXME: input parameters should be treated as immutable
streamToBuilderMap.put(moduleBuilder, entry.getKey());
builders.put(entry.getKey(), moduleBuilder);
module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes());
}
+ // FIXME: why a list is required?
+ // FIXME: streamToBuilderMap is output of this method, not input
private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(final List<InputStream> yangFileStreams,
final Map<ModuleBuilder, InputStream> streamToBuilderMap, final SchemaContext context) {
Map<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(yangFileStreams, streamToBuilderMap);
}
}
+ // FIXME: why a list is required?
private Map<InputStream, ParseTree> parseStreams(final List<InputStream> yangStreams) {
final Map<InputStream, ParseTree> trees = new HashMap<>();
for (InputStream yangStream : yangStreams) {
result = parser.yang();
errorListener.validate();
} catch (IOException e) {
+ // TODO: fix this ASAP
LOG.warn("Exception while reading yang file: " + yangStream, e);
}
return result;
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.parser.util;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class NamedByteArrayInputStream extends ByteArrayInputStream implements NamedInputStream {
+ private final String toString;
+ private NamedByteArrayInputStream(byte[] buf, String toString) {
+ super(buf);
+ this.toString = toString;
+ }
+
+ public static ByteArrayInputStream create(InputStream originalIS) throws IOException {
+ String content = IOUtils.toString(originalIS);
+ if (originalIS instanceof NamedInputStream) {
+ return new NamedByteArrayInputStream(content.getBytes(), originalIS.toString());
+ } else {
+ return new ByteArrayInputStream(content.getBytes());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return toString;
+ }
+}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-public class NamedFileInputStream extends FileInputStream {
+public class NamedFileInputStream extends FileInputStream implements NamedInputStream {
private final String fileDestination;
public NamedFileInputStream(File file, String fileDestination) throws FileNotFoundException {
return fileDestination;
}
+ @Override
+ public String toString() {
+ return fileDestination;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.yang.parser.util;
+
+public interface NamedInputStream {
+
+ /**
+ * @return name of resource from which this input stream is derived, typically file path.
+ */
+ String toString();
+}
*/
package org.opendaylight.yangtools.yang.parser.impl;
-import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
+import org.opendaylight.yangtools.yang.model.util.Decimal64;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.Int16;
+import org.opendaylight.yangtools.yang.model.util.Int32;
+import org.opendaylight.yangtools.yang.model.util.StringType;
+import org.opendaylight.yangtools.yang.model.util.Uint32;
+import org.opendaylight.yangtools.yang.model.util.UnionType;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
-import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.model.util.Decimal64;
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.util.Int16;
-import org.opendaylight.yangtools.yang.model.util.Int32;
-import org.opendaylight.yangtools.yang.model.util.StringType;
-import org.opendaylight.yangtools.yang.model.util.Uint32;
-import org.opendaylight.yangtools.yang.model.util.UnionType;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
public class YangParserTest {
public static final String FS = File.separator;
File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI());
YangModelParser parser = new YangParserImpl();
modules = parser.parseYangModels(yangFile, dependenciesDir);
- SchemaContext ctx = new SchemaContextImpl(modules);
+ SchemaContext ctx = new SchemaContextImpl(modules, Collections.<ModuleIdentifier, String>emptyMap());
checkOrder(modules);
assertSetEquals(modules, ctx.getModules());
}
Set<Module> newModules = parser.parseYangModels(testFiles);
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
// ##########
newModules = parser.parseYangModels(testFiles, null);
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
// ##########
List<InputStream> streams = new ArrayList<>();
}
newModules = parser.parseYangModelsFromStreams(streams);
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
// ##########
streams.clear();
}
newModules = parser.parseYangModelsFromStreams(streams, null);
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
// ##########
Map<File, Module> mapped = parser.parseYangModelsMapped(testFiles);
newModules = new LinkedHashSet<>(mapped.values());
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
// ##########
streams.clear();
Map<InputStream, Module> mappedStreams = parser.parseYangModelsFromStreamsMapped(streams);
newModules = new LinkedHashSet<>(mappedStreams.values());
assertSetEquals(newModules, modules);
- ctx = new SchemaContextImpl(newModules);
+ ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String>emptyMap());
assertSetEquals(newModules, ctx.getModules());
}